Dynamically create stencil buffer when needed.
Review URL: https://codereview.chromium.org/938383004
This commit is contained in:
parent
42380174ca
commit
6bc1b5fab8
@ -149,6 +149,7 @@
|
|||||||
'<(skia_src_path)/gpu/GrRectanizer_skyline.h',
|
'<(skia_src_path)/gpu/GrRectanizer_skyline.h',
|
||||||
'<(skia_src_path)/gpu/GrRedBlackTree.h',
|
'<(skia_src_path)/gpu/GrRedBlackTree.h',
|
||||||
'<(skia_src_path)/gpu/GrRenderTarget.cpp',
|
'<(skia_src_path)/gpu/GrRenderTarget.cpp',
|
||||||
|
'<(skia_src_path)/gpu/GrRenderTargetPriv.h',
|
||||||
'<(skia_src_path)/gpu/GrReducedClip.cpp',
|
'<(skia_src_path)/gpu/GrReducedClip.cpp',
|
||||||
'<(skia_src_path)/gpu/GrReducedClip.h',
|
'<(skia_src_path)/gpu/GrReducedClip.h',
|
||||||
'<(skia_src_path)/gpu/GrResourceCache.cpp',
|
'<(skia_src_path)/gpu/GrResourceCache.cpp',
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "SkRect.h"
|
#include "SkRect.h"
|
||||||
|
|
||||||
class GrStencilBuffer;
|
class GrStencilBuffer;
|
||||||
|
class GrRenderTargetPriv;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
|
* GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
|
||||||
@ -88,11 +89,9 @@ public:
|
|||||||
};
|
};
|
||||||
virtual ResolveType getResolveType() const = 0;
|
virtual ResolveType getResolveType() const = 0;
|
||||||
|
|
||||||
/**
|
// Provides access to functions that aren't part of the public API.
|
||||||
* GrStencilBuffer is not part of the public API.
|
GrRenderTargetPriv renderTargetPriv();
|
||||||
*/
|
const GrRenderTargetPriv renderTargetPriv() const;
|
||||||
GrStencilBuffer* getStencilBuffer() const { return fStencilBuffer; }
|
|
||||||
void setStencilBuffer(GrStencilBuffer* stencilBuffer);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GrRenderTarget(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc)
|
GrRenderTarget(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc)
|
||||||
@ -106,6 +105,11 @@ protected:
|
|||||||
void onRelease() SK_OVERRIDE;
|
void onRelease() SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Checked when this object is asked to attach a stencil buffer.
|
||||||
|
virtual bool canAttemptStencilAttachment() const = 0;
|
||||||
|
|
||||||
|
friend class GrRenderTargetPriv;
|
||||||
|
|
||||||
GrStencilBuffer* fStencilBuffer;
|
GrStencilBuffer* fStencilBuffer;
|
||||||
|
|
||||||
SkIRect fResolveRect;
|
SkIRect fResolveRect;
|
||||||
|
@ -390,10 +390,7 @@ enum GrSurfaceFlags {
|
|||||||
*/
|
*/
|
||||||
kRenderTarget_GrSurfaceFlag = 0x1,
|
kRenderTarget_GrSurfaceFlag = 0x1,
|
||||||
/**
|
/**
|
||||||
* By default all render targets have an associated stencil buffer that
|
* DEPRECATED. This has no effect.
|
||||||
* may be required for path filling. This flag overrides stencil buffer
|
|
||||||
* creation.
|
|
||||||
* MAKE THIS PRIVATE?
|
|
||||||
*/
|
*/
|
||||||
kNoStencil_GrSurfaceFlag = 0x2,
|
kNoStencil_GrSurfaceFlag = 0x2,
|
||||||
/**
|
/**
|
||||||
|
@ -273,7 +273,7 @@ bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp,
|
|||||||
} else {
|
} else {
|
||||||
maskDesc.fConfig = kRGBA_8888_GrPixelConfig;
|
maskDesc.fConfig = kRGBA_8888_GrPixelConfig;
|
||||||
}
|
}
|
||||||
maskDesc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
|
maskDesc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
// Add one pixel of border to ensure that clamp mode will be all zeros
|
// Add one pixel of border to ensure that clamp mode will be all zeros
|
||||||
// the outside.
|
// the outside.
|
||||||
maskDesc.fWidth = texture->width();
|
maskDesc.fWidth = texture->width();
|
||||||
|
@ -417,7 +417,7 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src,
|
|||||||
GrContext* context = color->getContext();
|
GrContext* context = color->getContext();
|
||||||
|
|
||||||
GrSurfaceDesc desc;
|
GrSurfaceDesc desc;
|
||||||
desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
|
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
desc.fWidth = bounds.width();
|
desc.fWidth = bounds.width();
|
||||||
desc.fHeight = bounds.height();
|
desc.fHeight = bounds.height();
|
||||||
desc.fConfig = kSkia8888_GrPixelConfig;
|
desc.fConfig = kSkia8888_GrPixelConfig;
|
||||||
|
@ -167,7 +167,7 @@ GrTexture* GaussianBlur(GrContext* context,
|
|||||||
kAlpha_8_GrPixelConfig == srcTexture->config());
|
kAlpha_8_GrPixelConfig == srcTexture->config());
|
||||||
|
|
||||||
GrSurfaceDesc desc;
|
GrSurfaceDesc desc;
|
||||||
desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
|
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
desc.fWidth = SkScalarFloorToInt(srcRect.width());
|
desc.fWidth = SkScalarFloorToInt(srcRect.width());
|
||||||
desc.fHeight = SkScalarFloorToInt(srcRect.height());
|
desc.fHeight = SkScalarFloorToInt(srcRect.height());
|
||||||
desc.fConfig = srcTexture->config();
|
desc.fConfig = srcTexture->config();
|
||||||
|
@ -657,7 +657,7 @@ bool apply_morphology(const SkBitmap& input,
|
|||||||
|
|
||||||
SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height());
|
SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height());
|
||||||
GrSurfaceDesc desc;
|
GrSurfaceDesc desc;
|
||||||
desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
|
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
desc.fWidth = rect.width();
|
desc.fWidth = rect.width();
|
||||||
desc.fHeight = rect.height();
|
desc.fHeight = rect.height();
|
||||||
desc.fConfig = kSkia8888_GrPixelConfig;
|
desc.fConfig = kSkia8888_GrPixelConfig;
|
||||||
|
@ -145,7 +145,7 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
|
|||||||
GrFragmentProcessor* xferProcessor = NULL;
|
GrFragmentProcessor* xferProcessor = NULL;
|
||||||
|
|
||||||
GrSurfaceDesc desc;
|
GrSurfaceDesc desc;
|
||||||
desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
|
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
desc.fWidth = src.width();
|
desc.fWidth = src.width();
|
||||||
desc.fHeight = src.height();
|
desc.fHeight = src.height();
|
||||||
desc.fConfig = kSkia8888_GrPixelConfig;
|
desc.fConfig = kSkia8888_GrPixelConfig;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "GrPaint.h"
|
#include "GrPaint.h"
|
||||||
#include "GrPathRenderer.h"
|
#include "GrPathRenderer.h"
|
||||||
#include "GrRenderTarget.h"
|
#include "GrRenderTarget.h"
|
||||||
|
#include "GrRenderTargetPriv.h"
|
||||||
#include "GrStencilBuffer.h"
|
#include "GrStencilBuffer.h"
|
||||||
#include "GrSWMaskHelper.h"
|
#include "GrSWMaskHelper.h"
|
||||||
#include "SkRasterClip.h"
|
#include "SkRasterClip.h"
|
||||||
@ -675,8 +676,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
|||||||
SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
|
SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
|
||||||
SkASSERT(rt);
|
SkASSERT(rt);
|
||||||
|
|
||||||
// TODO: dynamically attach a SB when needed.
|
GrStencilBuffer* stencilBuffer = rt->renderTargetPriv().attachStencilBuffer();
|
||||||
GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
|
|
||||||
if (NULL == stencilBuffer) {
|
if (NULL == stencilBuffer) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -905,9 +905,9 @@ void GrClipMaskManager::setPipelineBuilderStencil(GrPipelineBuilder* pipelineBui
|
|||||||
settings = pipelineBuilder->getStencil();
|
settings = pipelineBuilder->getStencil();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: dynamically attach a stencil buffer
|
|
||||||
int stencilBits = 0;
|
int stencilBits = 0;
|
||||||
GrStencilBuffer* stencilBuffer = pipelineBuilder->getRenderTarget()->getStencilBuffer();
|
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
|
||||||
|
GrStencilBuffer* stencilBuffer = rt->renderTargetPriv().attachStencilBuffer();
|
||||||
if (stencilBuffer) {
|
if (stencilBuffer) {
|
||||||
stencilBits = stencilBuffer->bits();
|
stencilBits = stencilBuffer->bits();
|
||||||
}
|
}
|
||||||
@ -1084,7 +1084,6 @@ void GrClipMaskManager::setClipTarget(GrClipTarget* clipTarget) {
|
|||||||
|
|
||||||
void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBuffer,
|
void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBuffer,
|
||||||
GrStencilSettings* settings) {
|
GrStencilSettings* settings) {
|
||||||
// TODO: dynamically attach a stencil buffer
|
|
||||||
if (stencilBuffer) {
|
if (stencilBuffer) {
|
||||||
int stencilBits = stencilBuffer->bits();
|
int stencilBits = stencilBuffer->bits();
|
||||||
this->adjustStencilParams(settings, fClipMode, stencilBits);
|
this->adjustStencilParams(settings, fClipMode, stencilBits);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "GrOvalRenderer.h"
|
#include "GrOvalRenderer.h"
|
||||||
#include "GrPathRenderer.h"
|
#include "GrPathRenderer.h"
|
||||||
#include "GrPathUtils.h"
|
#include "GrPathUtils.h"
|
||||||
|
#include "GrRenderTargetPriv.h"
|
||||||
#include "GrResourceCache.h"
|
#include "GrResourceCache.h"
|
||||||
#include "GrSoftwarePathRenderer.h"
|
#include "GrSoftwarePathRenderer.h"
|
||||||
#include "GrStencilAndCoverTextContext.h"
|
#include "GrStencilAndCoverTextContext.h"
|
||||||
@ -213,9 +214,11 @@ GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget,
|
|||||||
const SkDeviceProperties&
|
const SkDeviceProperties&
|
||||||
leakyProperties,
|
leakyProperties,
|
||||||
bool enableDistanceFieldFonts) {
|
bool enableDistanceFieldFonts) {
|
||||||
if (fGpu->caps()->pathRenderingSupport() && renderTarget->getStencilBuffer() &&
|
if (fGpu->caps()->pathRenderingSupport() && renderTarget->isMultisampled()) {
|
||||||
renderTarget->isMultisampled()) {
|
GrStencilBuffer* sb = renderTarget->renderTargetPriv().attachStencilBuffer();
|
||||||
return GrStencilAndCoverTextContext::Create(this, leakyProperties);
|
if (sb) {
|
||||||
|
return GrStencilAndCoverTextContext::Create(this, leakyProperties);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GrDistanceFieldTextContext::Create(this, leakyProperties, enableDistanceFieldFonts);
|
return GrDistanceFieldTextContext::Create(this, leakyProperties, enableDistanceFieldFonts);
|
||||||
@ -278,14 +281,10 @@ GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMat
|
|||||||
|
|
||||||
GrTexture* GrContext::internalRefScratchTexture(const GrSurfaceDesc& inDesc, uint32_t flags) {
|
GrTexture* GrContext::internalRefScratchTexture(const GrSurfaceDesc& inDesc, uint32_t flags) {
|
||||||
SkASSERT(!GrPixelConfigIsCompressed(inDesc.fConfig));
|
SkASSERT(!GrPixelConfigIsCompressed(inDesc.fConfig));
|
||||||
// kNoStencil has no meaning if kRT isn't set.
|
|
||||||
SkASSERT((inDesc.fFlags & kRenderTarget_GrSurfaceFlag) ||
|
|
||||||
!(inDesc.fFlags & kNoStencil_GrSurfaceFlag));
|
|
||||||
|
|
||||||
SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc);
|
SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc);
|
||||||
|
|
||||||
if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
|
if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
|
||||||
GrSurfaceFlags origFlags = desc->fFlags;
|
|
||||||
if (!(kExact_ScratchTextureFlag & flags)) {
|
if (!(kExact_ScratchTextureFlag & flags)) {
|
||||||
// bin by pow2 with a reasonable min
|
// bin by pow2 with a reasonable min
|
||||||
static const int MIN_SIZE = 16;
|
static const int MIN_SIZE = 16;
|
||||||
@ -294,44 +293,25 @@ GrTexture* GrContext::internalRefScratchTexture(const GrSurfaceDesc& inDesc, uin
|
|||||||
wdesc->fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc->fHeight));
|
wdesc->fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc->fHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
GrScratchKey key;
|
||||||
GrScratchKey key;
|
GrTexturePriv::ComputeScratchKey(*desc, &key);
|
||||||
GrTexturePriv::ComputeScratchKey(*desc, &key);
|
uint32_t scratchFlags = 0;
|
||||||
uint32_t scratchFlags = 0;
|
if (kNoPendingIO_ScratchTextureFlag & flags) {
|
||||||
if (kNoPendingIO_ScratchTextureFlag & flags) {
|
scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
|
||||||
scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
|
} else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
|
||||||
} else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
|
// If it is not a render target then it will most likely be populated by
|
||||||
// If it is not a render target then it will most likely be populated by
|
// writePixels() which will trigger a flush if the texture has pending IO.
|
||||||
// writePixels() which will trigger a flush if the texture has pending IO.
|
scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
|
||||||
scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
|
}
|
||||||
|
GrGpuResource* resource = fResourceCache->findAndRefScratchResource(key, scratchFlags);
|
||||||
|
if (resource) {
|
||||||
|
GrSurface* surface = static_cast<GrSurface*>(resource);
|
||||||
|
GrRenderTarget* rt = surface->asRenderTarget();
|
||||||
|
if (rt && fGpu->caps()->discardRenderTargetSupport()) {
|
||||||
|
rt->discard();
|
||||||
}
|
}
|
||||||
GrGpuResource* resource = fResourceCache->findAndRefScratchResource(key, scratchFlags);
|
return surface->asTexture();
|
||||||
if (resource) {
|
}
|
||||||
GrSurface* surface = static_cast<GrSurface*>(resource);
|
|
||||||
GrRenderTarget* rt = surface->asRenderTarget();
|
|
||||||
if (rt && fGpu->caps()->discardRenderTargetSupport()) {
|
|
||||||
rt->discard();
|
|
||||||
}
|
|
||||||
return surface->asTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kExact_ScratchTextureFlag & flags) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// We had a cache miss and we are in approx mode, relax the fit of the flags.
|
|
||||||
|
|
||||||
// We no longer try to reuse textures that were previously used as render targets in
|
|
||||||
// situations where no RT is needed; doing otherwise can confuse the video driver and
|
|
||||||
// cause significant performance problems in some cases.
|
|
||||||
if (desc->fFlags & kNoStencil_GrSurfaceFlag) {
|
|
||||||
desc.writable()->fFlags = desc->fFlags & ~kNoStencil_GrSurfaceFlag;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (true);
|
|
||||||
|
|
||||||
desc.writable()->fFlags = origFlags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(kNoCreate_ScratchTextureFlag & flags)) {
|
if (!(kNoCreate_ScratchTextureFlag & flags)) {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "GrPath.h"
|
#include "GrPath.h"
|
||||||
#include "GrPipeline.h"
|
#include "GrPipeline.h"
|
||||||
#include "GrRenderTarget.h"
|
#include "GrRenderTarget.h"
|
||||||
|
#include "GrRenderTargetPriv.h"
|
||||||
#include "GrSurfacePriv.h"
|
#include "GrSurfacePriv.h"
|
||||||
#include "GrTemplates.h"
|
#include "GrTemplates.h"
|
||||||
#include "GrTexture.h"
|
#include "GrTexture.h"
|
||||||
@ -607,9 +608,9 @@ void GrDrawTarget::stencilPath(GrPipelineBuilder* pipelineBuilder,
|
|||||||
|
|
||||||
// set stencil settings for path
|
// set stencil settings for path
|
||||||
GrStencilSettings stencilSettings;
|
GrStencilSettings stencilSettings;
|
||||||
this->getPathStencilSettingsForFilltype(fill,
|
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
|
||||||
pipelineBuilder->getRenderTarget()->getStencilBuffer(),
|
GrStencilBuffer* sb = rt->renderTargetPriv().attachStencilBuffer();
|
||||||
&stencilSettings);
|
this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
|
||||||
|
|
||||||
this->onStencilPath(*pipelineBuilder, pathProc, path, scissorState, stencilSettings);
|
this->onStencilPath(*pipelineBuilder, pathProc, path, scissorState, stencilSettings);
|
||||||
}
|
}
|
||||||
@ -636,9 +637,9 @@ void GrDrawTarget::drawPath(GrPipelineBuilder* pipelineBuilder,
|
|||||||
|
|
||||||
// set stencil settings for path
|
// set stencil settings for path
|
||||||
GrStencilSettings stencilSettings;
|
GrStencilSettings stencilSettings;
|
||||||
this->getPathStencilSettingsForFilltype(fill,
|
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
|
||||||
pipelineBuilder->getRenderTarget()->getStencilBuffer(),
|
GrStencilBuffer* sb = rt->renderTargetPriv().attachStencilBuffer();
|
||||||
&stencilSettings);
|
this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
|
||||||
|
|
||||||
GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, pathProc, &devBounds,
|
GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, pathProc, &devBounds,
|
||||||
this);
|
this);
|
||||||
@ -676,9 +677,9 @@ void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder,
|
|||||||
|
|
||||||
// set stencil settings for path
|
// set stencil settings for path
|
||||||
GrStencilSettings stencilSettings;
|
GrStencilSettings stencilSettings;
|
||||||
this->getPathStencilSettingsForFilltype(fill,
|
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
|
||||||
pipelineBuilder->getRenderTarget()->getStencilBuffer(),
|
GrStencilBuffer* sb = rt->renderTargetPriv().attachStencilBuffer();
|
||||||
&stencilSettings);
|
this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
|
||||||
|
|
||||||
// Don't compute a bounding box for dst copy texture, we'll opt
|
// Don't compute a bounding box for dst copy texture, we'll opt
|
||||||
// instead for it to just copy the entire dst. Realistically this is a moot
|
// instead for it to just copy the entire dst. Realistically this is a moot
|
||||||
|
@ -726,7 +726,7 @@ private:
|
|||||||
void initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* dstDesc) {
|
void initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* dstDesc) {
|
||||||
if (!this->onInitCopySurfaceDstDesc(src, dstDesc)) {
|
if (!this->onInitCopySurfaceDstDesc(src, dstDesc)) {
|
||||||
dstDesc->fOrigin = kDefault_GrSurfaceOrigin;
|
dstDesc->fOrigin = kDefault_GrSurfaceOrigin;
|
||||||
dstDesc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
|
dstDesc->fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
dstDesc->fConfig = src->config();
|
dstDesc->fConfig = src->config();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "GrGpuResourcePriv.h"
|
#include "GrGpuResourcePriv.h"
|
||||||
#include "GrIndexBuffer.h"
|
#include "GrIndexBuffer.h"
|
||||||
#include "GrResourceCache.h"
|
#include "GrResourceCache.h"
|
||||||
|
#include "GrRenderTargetPriv.h"
|
||||||
#include "GrStencilBuffer.h"
|
#include "GrStencilBuffer.h"
|
||||||
#include "GrVertexBuffer.h"
|
#include "GrVertexBuffer.h"
|
||||||
|
|
||||||
@ -61,16 +62,6 @@ GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc, bool budgeted,
|
|||||||
} else {
|
} else {
|
||||||
this->handleDirtyContext();
|
this->handleDirtyContext();
|
||||||
tex = this->onCreateTexture(desc, budgeted, srcData, rowBytes);
|
tex = this->onCreateTexture(desc, budgeted, srcData, rowBytes);
|
||||||
if (tex &&
|
|
||||||
(kRenderTarget_GrSurfaceFlag & desc.fFlags) &&
|
|
||||||
!(kNoStencil_GrSurfaceFlag & desc.fFlags)) {
|
|
||||||
SkASSERT(tex->asRenderTarget());
|
|
||||||
// TODO: defer this and attach dynamically
|
|
||||||
if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) {
|
|
||||||
tex->unref();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!this->caps()->reuseScratchTextures() && !isRT) {
|
if (!this->caps()->reuseScratchTextures() && !isRT) {
|
||||||
tex->resourcePriv().removeScratchKey();
|
tex->resourcePriv().removeScratchKey();
|
||||||
@ -85,7 +76,7 @@ GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc, bool budgeted,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
||||||
SkASSERT(NULL == rt->getStencilBuffer());
|
SkASSERT(NULL == rt->renderTargetPriv().getStencilBuffer());
|
||||||
GrUniqueKey sbKey;
|
GrUniqueKey sbKey;
|
||||||
|
|
||||||
int width = rt->width();
|
int width = rt->width();
|
||||||
@ -99,12 +90,11 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
|||||||
SkAutoTUnref<GrStencilBuffer> sb(static_cast<GrStencilBuffer*>(
|
SkAutoTUnref<GrStencilBuffer> sb(static_cast<GrStencilBuffer*>(
|
||||||
this->getContext()->getResourceCache()->findAndRefUniqueResource(sbKey)));
|
this->getContext()->getResourceCache()->findAndRefUniqueResource(sbKey)));
|
||||||
if (sb) {
|
if (sb) {
|
||||||
rt->setStencilBuffer(sb);
|
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
|
||||||
bool attached = this->attachStencilBufferToRenderTarget(sb, rt);
|
rt->renderTargetPriv().didAttachStencilBuffer(sb);
|
||||||
if (!attached) {
|
return true;
|
||||||
rt->setStencilBuffer(NULL);
|
|
||||||
}
|
}
|
||||||
return attached;
|
return false;
|
||||||
}
|
}
|
||||||
if (this->createStencilBufferForRenderTarget(rt, width, height)) {
|
if (this->createStencilBufferForRenderTarget(rt, width, height)) {
|
||||||
// Right now we're clearing the stencil buffer here after it is
|
// Right now we're clearing the stencil buffer here after it is
|
||||||
@ -116,7 +106,8 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
|||||||
// FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
|
// FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
|
||||||
// FBO status.
|
// FBO status.
|
||||||
this->clearStencil(rt);
|
this->clearStencil(rt);
|
||||||
rt->getStencilBuffer()->resourcePriv().setUniqueKey(sbKey);
|
GrStencilBuffer* sb = rt->renderTargetPriv().getStencilBuffer();
|
||||||
|
sb->resourcePriv().setUniqueKey(sbKey);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -405,6 +405,9 @@ public:
|
|||||||
void saveActiveTraceMarkers();
|
void saveActiveTraceMarkers();
|
||||||
void restoreActiveTraceMarkers();
|
void restoreActiveTraceMarkers();
|
||||||
|
|
||||||
|
// Given a rt, find or create a stencil buffer and attach it
|
||||||
|
bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Functions used to map clip-respecting stencil tests into normal
|
// Functions used to map clip-respecting stencil tests into normal
|
||||||
// stencil funcs supported by GPUs.
|
// stencil funcs supported by GPUs.
|
||||||
@ -489,9 +492,6 @@ private:
|
|||||||
// clears target's entire stencil buffer to 0
|
// clears target's entire stencil buffer to 0
|
||||||
virtual void clearStencil(GrRenderTarget* target) = 0;
|
virtual void clearStencil(GrRenderTarget* target) = 0;
|
||||||
|
|
||||||
// Given a rt, find or create a stencil buffer and attach it
|
|
||||||
bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
|
|
||||||
|
|
||||||
virtual void didAddGpuTraceMarker() = 0;
|
virtual void didAddGpuTraceMarker() = 0;
|
||||||
virtual void didRemoveGpuTraceMarker() = 0;
|
virtual void didRemoveGpuTraceMarker() = 0;
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "GrContext.h"
|
#include "GrContext.h"
|
||||||
#include "GrGpu.h"
|
#include "GrGpu.h"
|
||||||
|
#include "GrRenderTargetPriv.h"
|
||||||
#include "GrStencilBuffer.h"
|
#include "GrStencilBuffer.h"
|
||||||
|
|
||||||
void GrRenderTarget::discard() {
|
void GrRenderTarget::discard() {
|
||||||
@ -46,18 +47,30 @@ void GrRenderTarget::overrideResolveRect(const SkIRect rect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrRenderTarget::setStencilBuffer(GrStencilBuffer* stencilBuffer) {
|
|
||||||
SkRefCnt_SafeAssign(fStencilBuffer, stencilBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrRenderTarget::onRelease() {
|
void GrRenderTarget::onRelease() {
|
||||||
this->setStencilBuffer(NULL);
|
this->renderTargetPriv().didAttachStencilBuffer(NULL);
|
||||||
|
|
||||||
INHERITED::onRelease();
|
INHERITED::onRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrRenderTarget::onAbandon() {
|
void GrRenderTarget::onAbandon() {
|
||||||
this->setStencilBuffer(NULL);
|
this->renderTargetPriv().didAttachStencilBuffer(NULL);
|
||||||
|
|
||||||
INHERITED::onAbandon();
|
INHERITED::onAbandon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void GrRenderTargetPriv::didAttachStencilBuffer(GrStencilBuffer* stencilBuffer) {
|
||||||
|
SkRefCnt_SafeAssign(fRenderTarget->fStencilBuffer, stencilBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
GrStencilBuffer* GrRenderTargetPriv::attachStencilBuffer() const {
|
||||||
|
if (fRenderTarget->fStencilBuffer) {
|
||||||
|
return fRenderTarget->fStencilBuffer;
|
||||||
|
}
|
||||||
|
if (!fRenderTarget->wasDestroyed() && fRenderTarget->canAttemptStencilAttachment()) {
|
||||||
|
fRenderTarget->getGpu()->attachStencilBufferToRenderTarget(fRenderTarget);
|
||||||
|
}
|
||||||
|
return fRenderTarget->fStencilBuffer;
|
||||||
|
}
|
||||||
|
51
src/gpu/GrRenderTargetPriv.h
Normal file
51
src/gpu/GrRenderTargetPriv.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GrRenderTargetPriv_DEFINED
|
||||||
|
#define GrRenderTargetPriv_DEFINED
|
||||||
|
|
||||||
|
#include "GrRenderTarget.h"
|
||||||
|
|
||||||
|
/** Class that adds methods to GrRenderTarget that are only intended for use internal to Skia.
|
||||||
|
This class is purely a privileged window into GrRenderTarget. It should never have additional
|
||||||
|
data members or virtual methods. */
|
||||||
|
class GrRenderTargetPriv {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* GrStencilBuffer is not part of the public API.
|
||||||
|
*/
|
||||||
|
GrStencilBuffer* getStencilBuffer() const { return fRenderTarget->fStencilBuffer; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this render target already has a stencil buffer, return it. Otherwise attempt to attach
|
||||||
|
* one.
|
||||||
|
*/
|
||||||
|
GrStencilBuffer* attachStencilBuffer() const;
|
||||||
|
|
||||||
|
void didAttachStencilBuffer(GrStencilBuffer*);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit GrRenderTargetPriv(GrRenderTarget* renderTarget) : fRenderTarget(renderTarget) {}
|
||||||
|
GrRenderTargetPriv(const GrRenderTargetPriv&) {} // unimpl
|
||||||
|
GrRenderTargetPriv& operator=(const GrRenderTargetPriv&); // unimpl
|
||||||
|
|
||||||
|
// No taking addresses of this type.
|
||||||
|
const GrRenderTargetPriv* operator&() const;
|
||||||
|
GrRenderTargetPriv* operator&();
|
||||||
|
|
||||||
|
GrRenderTarget* fRenderTarget;
|
||||||
|
|
||||||
|
friend class GrRenderTarget; // to construct/copy this type.
|
||||||
|
};
|
||||||
|
|
||||||
|
inline GrRenderTargetPriv GrRenderTarget::renderTargetPriv() { return GrRenderTargetPriv(this); }
|
||||||
|
|
||||||
|
inline const GrRenderTargetPriv GrRenderTarget::renderTargetPriv () const {
|
||||||
|
return GrRenderTargetPriv(const_cast<GrRenderTarget*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -12,6 +12,8 @@
|
|||||||
#include "GrDrawTargetCaps.h"
|
#include "GrDrawTargetCaps.h"
|
||||||
#include "GrGpu.h"
|
#include "GrGpu.h"
|
||||||
#include "GrPath.h"
|
#include "GrPath.h"
|
||||||
|
#include "GrRenderTarget.h"
|
||||||
|
#include "GrRenderTargetPriv.h"
|
||||||
#include "SkStrokeRec.h"
|
#include "SkStrokeRec.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -58,7 +60,6 @@ bool GrStencilAndCoverPathRenderer::canDrawPath(const GrDrawTarget* target,
|
|||||||
bool antiAlias) const {
|
bool antiAlias) const {
|
||||||
return !stroke.isHairlineStyle() &&
|
return !stroke.isHairlineStyle() &&
|
||||||
!antiAlias && // doesn't do per-path AA, relies on the target having MSAA
|
!antiAlias && // doesn't do per-path AA, relies on the target having MSAA
|
||||||
pipelineBuilder->getRenderTarget()->getStencilBuffer() &&
|
|
||||||
pipelineBuilder->getStencil().isDisabled();
|
pipelineBuilder->getStencil().isDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,9 +34,9 @@ public:
|
|||||||
bool hasPendingIO() const { return fSurface->hasPendingIO(); }
|
bool hasPendingIO() const { return fSurface->hasPendingIO(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrSurfacePriv(GrSurface* surface) : fSurface(surface) { }
|
explicit GrSurfacePriv(GrSurface* surface) : fSurface(surface) {}
|
||||||
GrSurfacePriv(const GrSurfacePriv& that) : fSurface(that.fSurface) { }
|
GrSurfacePriv(const GrSurfacePriv&); // unimpl
|
||||||
GrSurfacePriv& operator=(const GrSurface&); // unimpl
|
GrSurfacePriv& operator=(const GrSurfacePriv&); // unimpl
|
||||||
|
|
||||||
// No taking addresses of this type.
|
// No taking addresses of this type.
|
||||||
const GrSurfacePriv* operator&() const;
|
const GrSurfacePriv* operator&() const;
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include "GrDrawTargetCaps.h"
|
#include "GrDrawTargetCaps.h"
|
||||||
#include "GrGpu.h"
|
#include "GrGpu.h"
|
||||||
#include "GrResourceKey.h"
|
#include "GrResourceKey.h"
|
||||||
|
#include "GrRenderTarget.h"
|
||||||
|
#include "GrRenderTargetPriv.h"
|
||||||
#include "GrTexture.h"
|
#include "GrTexture.h"
|
||||||
#include "GrTexturePriv.h"
|
#include "GrTexturePriv.h"
|
||||||
|
|
||||||
@ -49,17 +51,9 @@ void GrTexture::validateDesc() const {
|
|||||||
if (this->asRenderTarget()) {
|
if (this->asRenderTarget()) {
|
||||||
// This texture has a render target
|
// This texture has a render target
|
||||||
SkASSERT(0 != (fDesc.fFlags & kRenderTarget_GrSurfaceFlag));
|
SkASSERT(0 != (fDesc.fFlags & kRenderTarget_GrSurfaceFlag));
|
||||||
|
|
||||||
if (this->asRenderTarget()->getStencilBuffer()) {
|
|
||||||
SkASSERT(0 != (fDesc.fFlags & kNoStencil_GrSurfaceFlag));
|
|
||||||
} else {
|
|
||||||
SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrSurfaceFlag));
|
|
||||||
}
|
|
||||||
|
|
||||||
SkASSERT(fDesc.fSampleCnt == this->asRenderTarget()->numSamples());
|
SkASSERT(fDesc.fSampleCnt == this->asRenderTarget()->numSamples());
|
||||||
} else {
|
} else {
|
||||||
SkASSERT(0 == (fDesc.fFlags & kRenderTarget_GrSurfaceFlag));
|
SkASSERT(0 == (fDesc.fFlags & kRenderTarget_GrSurfaceFlag));
|
||||||
SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrSurfaceFlag));
|
|
||||||
SkASSERT(0 == fDesc.fSampleCnt);
|
SkASSERT(0 == fDesc.fSampleCnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,9 +198,7 @@ GrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch,
|
|||||||
|
|
||||||
// Either it's a cache miss or the original wasn't cached to begin with.
|
// Either it's a cache miss or the original wasn't cached to begin with.
|
||||||
GrSurfaceDesc rtDesc = inputTexture->desc();
|
GrSurfaceDesc rtDesc = inputTexture->desc();
|
||||||
rtDesc.fFlags = rtDesc.fFlags |
|
rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
|
||||||
kRenderTarget_GrSurfaceFlag |
|
|
||||||
kNoStencil_GrSurfaceFlag;
|
|
||||||
rtDesc.fWidth = GrNextPow2(rtDesc.fWidth);
|
rtDesc.fWidth = GrNextPow2(rtDesc.fWidth);
|
||||||
rtDesc.fHeight = GrNextPow2(rtDesc.fHeight);
|
rtDesc.fHeight = GrNextPow2(rtDesc.fHeight);
|
||||||
rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
|
rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
|
||||||
@ -377,9 +375,7 @@ static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKe
|
|||||||
}
|
}
|
||||||
|
|
||||||
GrSurfaceDesc rtDesc = desc;
|
GrSurfaceDesc rtDesc = desc;
|
||||||
rtDesc.fFlags = rtDesc.fFlags |
|
rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
|
||||||
kRenderTarget_GrSurfaceFlag |
|
|
||||||
kNoStencil_GrSurfaceFlag;
|
|
||||||
|
|
||||||
GrTexture* result = create_texture_for_bmp(ctx, optionalKey, rtDesc, pixelRef, NULL, 0);
|
GrTexture* result = create_texture_for_bmp(ctx, optionalKey, rtDesc, pixelRef, NULL, 0);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -77,7 +77,7 @@ static SkGrPixelRef* copy_to_new_texture_pixelref(GrTexture* texture, SkColorTyp
|
|||||||
desc.fHeight = subset->height();
|
desc.fHeight = subset->height();
|
||||||
srcRect = *subset;
|
srcRect = *subset;
|
||||||
}
|
}
|
||||||
desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
|
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, kPremul_SkAlphaType, dstPT);
|
desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, kPremul_SkAlphaType, dstPT);
|
||||||
|
|
||||||
GrTexture* dst = context->createTexture(desc, false, NULL, 0);
|
GrTexture* dst = context->createTexture(desc, false, NULL, 0);
|
||||||
|
@ -181,8 +181,7 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
|
|||||||
}
|
}
|
||||||
|
|
||||||
GrSurfaceDesc desc;
|
GrSurfaceDesc desc;
|
||||||
desc.fFlags = kRenderTarget_GrSurfaceFlag |
|
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
kNoStencil_GrSurfaceFlag;
|
|
||||||
desc.fWidth = 256;
|
desc.fWidth = 256;
|
||||||
desc.fHeight = 256;
|
desc.fHeight = 256;
|
||||||
desc.fConfig = kRGBA_8888_GrPixelConfig;
|
desc.fConfig = kRGBA_8888_GrPixelConfig;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "GrGLTextureRenderTarget.h"
|
#include "GrGLTextureRenderTarget.h"
|
||||||
#include "GrGpuResourcePriv.h"
|
#include "GrGpuResourcePriv.h"
|
||||||
#include "GrPipeline.h"
|
#include "GrPipeline.h"
|
||||||
|
#include "GrRenderTargetPriv.h"
|
||||||
#include "GrSurfacePriv.h"
|
#include "GrSurfacePriv.h"
|
||||||
#include "GrTemplates.h"
|
#include "GrTemplates.h"
|
||||||
#include "GrTexturePriv.h"
|
#include "GrTexturePriv.h"
|
||||||
@ -454,7 +455,7 @@ GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
|
|||||||
desc.fHeight,
|
desc.fHeight,
|
||||||
desc.fSampleCnt,
|
desc.fSampleCnt,
|
||||||
format));
|
format));
|
||||||
tgt->setStencilBuffer(sb);
|
tgt->renderTargetPriv().didAttachStencilBuffer(sb);
|
||||||
sb->unref();
|
sb->unref();
|
||||||
}
|
}
|
||||||
return tgt;
|
return tgt;
|
||||||
@ -1175,7 +1176,7 @@ bool GrGLGpu::createStencilBufferForRenderTarget(GrRenderTarget* rt, int width,
|
|||||||
(this, sbDesc, width, height, samples, format)));
|
(this, sbDesc, width, height, samples, format)));
|
||||||
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
|
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
|
||||||
fLastSuccessfulStencilFmtIdx = sIdx;
|
fLastSuccessfulStencilFmtIdx = sIdx;
|
||||||
rt->setStencilBuffer(sb);
|
rt->renderTargetPriv().didAttachStencilBuffer(sb);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Remove the scratch key from this resource so we don't grab it from the cache ever
|
// Remove the scratch key from this resource so we don't grab it from the cache ever
|
||||||
@ -1195,7 +1196,7 @@ bool GrGLGpu::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
|
|||||||
GrGLuint fbo = glrt->renderFBOID();
|
GrGLuint fbo = glrt->renderFBOID();
|
||||||
|
|
||||||
if (NULL == sb) {
|
if (NULL == sb) {
|
||||||
if (rt->getStencilBuffer()) {
|
if (rt->renderTargetPriv().getStencilBuffer()) {
|
||||||
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
|
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
|
||||||
GR_GL_STENCIL_ATTACHMENT,
|
GR_GL_STENCIL_ATTACHMENT,
|
||||||
GR_GL_RENDERBUFFER, 0));
|
GR_GL_RENDERBUFFER, 0));
|
||||||
@ -1570,10 +1571,11 @@ void GrGLGpu::clearStencil(GrRenderTarget* target) {
|
|||||||
void GrGLGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool insideClip) {
|
void GrGLGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool insideClip) {
|
||||||
SkASSERT(target);
|
SkASSERT(target);
|
||||||
|
|
||||||
|
GrStencilBuffer* sb = target->renderTargetPriv().getStencilBuffer();
|
||||||
// this should only be called internally when we know we have a
|
// this should only be called internally when we know we have a
|
||||||
// stencil buffer.
|
// stencil buffer.
|
||||||
SkASSERT(target->getStencilBuffer());
|
SkASSERT(sb);
|
||||||
GrGLint stencilBitCount = target->getStencilBuffer()->bits();
|
GrGLint stencilBitCount = sb->bits();
|
||||||
#if 0
|
#if 0
|
||||||
SkASSERT(stencilBitCount > 0);
|
SkASSERT(stencilBitCount > 0);
|
||||||
GrGLint clipStencilMask = (1 << (stencilBitCount - 1));
|
GrGLint clipStencilMask = (1 << (stencilBitCount - 1));
|
||||||
@ -2560,7 +2562,7 @@ bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
|
|||||||
// then we set up for that, otherwise fail.
|
// then we set up for that, otherwise fail.
|
||||||
if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) {
|
if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) {
|
||||||
desc->fOrigin = kDefault_GrSurfaceOrigin;
|
desc->fOrigin = kDefault_GrSurfaceOrigin;
|
||||||
desc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
|
desc->fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
desc->fConfig = kBGRA_8888_GrPixelConfig;
|
desc->fConfig = kBGRA_8888_GrPixelConfig;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2576,7 +2578,7 @@ bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
|
|||||||
// fail.
|
// fail.
|
||||||
if (this->caps()->isConfigRenderable(src->config(), false)) {
|
if (this->caps()->isConfigRenderable(src->config(), false)) {
|
||||||
desc->fOrigin = kDefault_GrSurfaceOrigin;
|
desc->fOrigin = kDefault_GrSurfaceOrigin;
|
||||||
desc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
|
desc->fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
desc->fConfig = src->config();
|
desc->fConfig = src->config();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,9 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** When we don't own the FBO ID we don't attempt to modify its attachments. */
|
||||||
|
bool canAttemptStencilAttachment() const SK_OVERRIDE { return !fIsWrapped; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// The public constructor registers this object with the cache. However, only the most derived
|
// The public constructor registers this object with the cache. However, only the most derived
|
||||||
// class should register with the cache. This constructor does not do the registration and
|
// class should register with the cache. This constructor does not do the registration and
|
||||||
|
@ -313,7 +313,7 @@ DEF_GPUTEST(ReadPixels, reporter, factory) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
GrSurfaceDesc desc;
|
GrSurfaceDesc desc;
|
||||||
desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
|
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||||
desc.fWidth = DEV_W;
|
desc.fWidth = DEV_W;
|
||||||
desc.fHeight = DEV_H;
|
desc.fHeight = DEV_H;
|
||||||
desc.fConfig = kSkia8888_GrPixelConfig;
|
desc.fConfig = kSkia8888_GrPixelConfig;
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#include "GrGpu.h"
|
#include "GrGpu.h"
|
||||||
#include "GrGpuResourceCacheAccess.h"
|
#include "GrGpuResourceCacheAccess.h"
|
||||||
#include "GrGpuResourcePriv.h"
|
#include "GrGpuResourcePriv.h"
|
||||||
|
#include "GrRenderTarget.h"
|
||||||
|
#include "GrRenderTargetPriv.h"
|
||||||
#include "GrResourceCache.h"
|
#include "GrResourceCache.h"
|
||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
#include "SkGr.h"
|
#include "SkGr.h"
|
||||||
@ -73,18 +75,29 @@ static void test_stencil_buffers(skiatest::Reporter* reporter, GrContext* contex
|
|||||||
|
|
||||||
// Test that two budgeted RTs with the same desc share a stencil buffer.
|
// Test that two budgeted RTs with the same desc share a stencil buffer.
|
||||||
SkAutoTUnref<GrTexture> smallRT0(context->createTexture(smallDesc, true));
|
SkAutoTUnref<GrTexture> smallRT0(context->createTexture(smallDesc, true));
|
||||||
|
if (smallRT0 && smallRT0->asRenderTarget()) {
|
||||||
|
smallRT0->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
SkAutoTUnref<GrTexture> smallRT1(context->createTexture(smallDesc, true));
|
SkAutoTUnref<GrTexture> smallRT1(context->createTexture(smallDesc, true));
|
||||||
|
if (smallRT1 && smallRT1->asRenderTarget()) {
|
||||||
|
smallRT1->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
REPORTER_ASSERT(reporter, smallRT0 && smallRT1 &&
|
REPORTER_ASSERT(reporter, smallRT0 && smallRT1 &&
|
||||||
smallRT0->asRenderTarget() && smallRT1->asRenderTarget() &&
|
smallRT0->asRenderTarget() && smallRT1->asRenderTarget() &&
|
||||||
smallRT0->asRenderTarget()->getStencilBuffer() ==
|
smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() ==
|
||||||
smallRT1->asRenderTarget()->getStencilBuffer());
|
smallRT1->asRenderTarget()->renderTargetPriv().getStencilBuffer());
|
||||||
|
|
||||||
// An unbudgeted RT with the same desc should also share.
|
// An unbudgeted RT with the same desc should also share.
|
||||||
SkAutoTUnref<GrTexture> smallRT2(context->createTexture(smallDesc, false));
|
SkAutoTUnref<GrTexture> smallRT2(context->createTexture(smallDesc, false));
|
||||||
|
if (smallRT2 && smallRT2->asRenderTarget()) {
|
||||||
|
smallRT2->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
|
||||||
|
}
|
||||||
REPORTER_ASSERT(reporter, smallRT0 && smallRT2 &&
|
REPORTER_ASSERT(reporter, smallRT0 && smallRT2 &&
|
||||||
smallRT0->asRenderTarget() && smallRT2->asRenderTarget() &&
|
smallRT0->asRenderTarget() && smallRT2->asRenderTarget() &&
|
||||||
smallRT0->asRenderTarget()->getStencilBuffer() ==
|
smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() ==
|
||||||
smallRT2->asRenderTarget()->getStencilBuffer());
|
smallRT2->asRenderTarget()->renderTargetPriv().getStencilBuffer());
|
||||||
|
|
||||||
// An RT with a much larger size should not share.
|
// An RT with a much larger size should not share.
|
||||||
GrSurfaceDesc bigDesc;
|
GrSurfaceDesc bigDesc;
|
||||||
@ -94,44 +107,60 @@ static void test_stencil_buffers(skiatest::Reporter* reporter, GrContext* contex
|
|||||||
bigDesc.fHeight = 200;
|
bigDesc.fHeight = 200;
|
||||||
bigDesc.fSampleCnt = 0;
|
bigDesc.fSampleCnt = 0;
|
||||||
SkAutoTUnref<GrTexture> bigRT(context->createTexture(bigDesc, false));
|
SkAutoTUnref<GrTexture> bigRT(context->createTexture(bigDesc, false));
|
||||||
|
if (bigRT && bigRT->asRenderTarget()) {
|
||||||
|
bigRT->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
|
||||||
|
}
|
||||||
REPORTER_ASSERT(reporter, smallRT0 && bigRT &&
|
REPORTER_ASSERT(reporter, smallRT0 && bigRT &&
|
||||||
smallRT0->asRenderTarget() && bigRT->asRenderTarget() &&
|
smallRT0->asRenderTarget() && bigRT->asRenderTarget() &&
|
||||||
smallRT0->asRenderTarget()->getStencilBuffer() !=
|
smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() !=
|
||||||
bigRT->asRenderTarget()->getStencilBuffer());
|
bigRT->asRenderTarget()->renderTargetPriv().getStencilBuffer());
|
||||||
|
|
||||||
if (context->getMaxSampleCount() >= 4) {
|
if (context->getMaxSampleCount() >= 4) {
|
||||||
// An RT with a different sample count should not share.
|
// An RT with a different sample count should not share.
|
||||||
GrSurfaceDesc smallMSAADesc = smallDesc;
|
GrSurfaceDesc smallMSAADesc = smallDesc;
|
||||||
smallMSAADesc.fSampleCnt = 4;
|
smallMSAADesc.fSampleCnt = 4;
|
||||||
SkAutoTUnref<GrTexture> smallMSAART0(context->createTexture(smallMSAADesc, false));
|
SkAutoTUnref<GrTexture> smallMSAART0(context->createTexture(smallMSAADesc, false));
|
||||||
|
if (smallMSAART0 && smallMSAART0->asRenderTarget()) {
|
||||||
|
smallMSAART0->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
|
||||||
|
}
|
||||||
#ifdef SK_BUILD_FOR_ANDROID
|
#ifdef SK_BUILD_FOR_ANDROID
|
||||||
if (!smallMSAART0) {
|
if (!smallMSAART0) {
|
||||||
// The nexus player seems to fail to create MSAA textures.
|
// The nexus player seems to fail to create MSAA textures.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
REPORTER_ASSERT(reporter, smallRT0 && smallMSAART0 &&
|
REPORTER_ASSERT(reporter,
|
||||||
smallRT0->asRenderTarget() && smallMSAART0->asRenderTarget() &&
|
smallRT0 && smallMSAART0 &&
|
||||||
smallRT0->asRenderTarget()->getStencilBuffer() !=
|
smallRT0->asRenderTarget() && smallMSAART0->asRenderTarget() &&
|
||||||
smallMSAART0->asRenderTarget()->getStencilBuffer());
|
smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() !=
|
||||||
|
smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilBuffer());
|
||||||
// A second MSAA RT should share with the first MSAA RT.
|
// A second MSAA RT should share with the first MSAA RT.
|
||||||
SkAutoTUnref<GrTexture> smallMSAART1(context->createTexture(smallMSAADesc, false));
|
SkAutoTUnref<GrTexture> smallMSAART1(context->createTexture(smallMSAADesc, false));
|
||||||
REPORTER_ASSERT(reporter, smallMSAART0 && smallMSAART1 &&
|
if (smallMSAART1 && smallMSAART1->asRenderTarget()) {
|
||||||
smallMSAART0->asRenderTarget() &&
|
smallMSAART1->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
|
||||||
smallMSAART1->asRenderTarget() &&
|
}
|
||||||
smallMSAART0->asRenderTarget()->getStencilBuffer() ==
|
REPORTER_ASSERT(reporter,
|
||||||
smallMSAART1->asRenderTarget()->getStencilBuffer());
|
smallMSAART0 && smallMSAART1 &&
|
||||||
|
smallMSAART0->asRenderTarget() &&
|
||||||
|
smallMSAART1->asRenderTarget() &&
|
||||||
|
smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilBuffer() ==
|
||||||
|
smallMSAART1->asRenderTarget()->renderTargetPriv().getStencilBuffer());
|
||||||
// But not one with a larger sample count should not. (Also check that the request for 4
|
// But not one with a larger sample count should not. (Also check that the request for 4
|
||||||
// samples didn't get rounded up to >= 8 or else they could share.).
|
// samples didn't get rounded up to >= 8 or else they could share.).
|
||||||
if (context->getMaxSampleCount() >= 8 && smallMSAART0 && smallMSAART0->asRenderTarget() &&
|
if (context->getMaxSampleCount() >= 8 && smallMSAART0 && smallMSAART0->asRenderTarget() &&
|
||||||
smallMSAART0->asRenderTarget()->numSamples() < 8) {
|
smallMSAART0->asRenderTarget()->numSamples() < 8) {
|
||||||
smallMSAADesc.fSampleCnt = 8;
|
smallMSAADesc.fSampleCnt = 8;
|
||||||
smallMSAART1.reset(context->createTexture(smallMSAADesc, false));
|
smallMSAART1.reset(context->createTexture(smallMSAADesc, false));
|
||||||
REPORTER_ASSERT(reporter, smallMSAART0 && smallMSAART1 &&
|
SkAutoTUnref<GrTexture> smallMSAART1(context->createTexture(smallMSAADesc, false));
|
||||||
smallMSAART0->asRenderTarget() &&
|
if (smallMSAART1 && smallMSAART1->asRenderTarget()) {
|
||||||
smallMSAART1->asRenderTarget() &&
|
smallMSAART1->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
|
||||||
smallMSAART0->asRenderTarget()->getStencilBuffer() !=
|
}
|
||||||
smallMSAART1->asRenderTarget()->getStencilBuffer());
|
REPORTER_ASSERT(reporter,
|
||||||
|
smallMSAART0 && smallMSAART1 &&
|
||||||
|
smallMSAART0->asRenderTarget() &&
|
||||||
|
smallMSAART1->asRenderTarget() &&
|
||||||
|
smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilBuffer() !=
|
||||||
|
smallMSAART1->asRenderTarget()->renderTargetPriv().getStencilBuffer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user