| Index: src/gpu/GrClipMaskManager.cpp
|
| diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
|
| index 0df74a6c286c9cc189b9f9959fe3f9686ed7e943..1ddcef1b36c3cc4c48c4f00d8a6f401172736995 100644
|
| --- a/src/gpu/GrClipMaskManager.cpp
|
| +++ b/src/gpu/GrClipMaskManager.cpp
|
| @@ -9,10 +9,12 @@
|
| #include "GrCaps.h"
|
| #include "GrDrawContext.h"
|
| #include "GrDrawTarget.h"
|
| +#include "GrGpuResourcePriv.h"
|
| #include "GrPaint.h"
|
| #include "GrPathRenderer.h"
|
| #include "GrRenderTarget.h"
|
| #include "GrRenderTargetPriv.h"
|
| +#include "GrResourceProvider.h"
|
| #include "GrStencilAttachment.h"
|
| #include "GrSWMaskHelper.h"
|
| #include "SkRasterClip.h"
|
| @@ -78,7 +80,6 @@ bool path_needs_SW_renderer(GrContext* context,
|
|
|
| GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
|
| : fCurrClipMaskType(kNone_ClipMaskType)
|
| - , fAACache(drawTarget->cmmAccess().resourceProvider())
|
| , fDrawTarget(drawTarget)
|
| , fClipMode(kIgnoreClip_StencilClipMode) {
|
| }
|
| @@ -344,13 +345,6 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
|
| // if alpha clip mask creation fails fall through to the non-AA code paths
|
| }
|
|
|
| - // Either a hard (stencil buffer) clip was explicitly requested or an anti-aliased clip couldn't
|
| - // be created. In either case, free up the texture in the anti-aliased mask cache.
|
| - // TODO: this may require more investigation. Ganesh performs a lot of utility draws (e.g.,
|
| - // clears, GrBufferedDrawTarget playbacks) that hit the stencil buffer path. These may be
|
| - // "incorrectly" clearing the AA cache.
|
| - fAACache.reset();
|
| -
|
| // use the stencil clip if we can't represent the clip as a rectangle.
|
| SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin();
|
| this->createStencilClipMask(rt,
|
| @@ -516,62 +510,55 @@ GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| -// Return the texture currently in the cache if it exists. Otherwise, return nullptr
|
| -GrTexture* GrClipMaskManager::getCachedMaskTexture(int32_t elementsGenID,
|
| - const SkIRect& clipSpaceIBounds) {
|
| - bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds);
|
| - if (!cached) {
|
| - return nullptr;
|
| - }
|
| +// Create a 8-bit clip mask in alpha
|
|
|
| - return fAACache.getLastMask();
|
| +static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey* key) {
|
| + static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
| + GrUniqueKey::Builder builder(key, kDomain, 3);
|
| + builder[0] = clipGenID;
|
| + builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16);
|
| + builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16);
|
| }
|
|
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// Allocate a texture in the texture cache. This function returns the texture
|
| -// allocated (or nullptr on error).
|
| -GrTexture* GrClipMaskManager::allocMaskTexture(int32_t elementsGenID,
|
| - const SkIRect& clipSpaceIBounds,
|
| - bool willUpload) {
|
| - // Since we are setting up the cache we should free up the
|
| - // currently cached mask so it can be reused.
|
| - fAACache.reset();
|
| -
|
| +GrTexture* GrClipMaskManager::createCachedMask(int width, int height, const GrUniqueKey& key,
|
| + bool renderTarget) {
|
| GrSurfaceDesc desc;
|
| - desc.fFlags = willUpload ? kNone_GrSurfaceFlags : kRenderTarget_GrSurfaceFlag;
|
| - desc.fWidth = clipSpaceIBounds.width();
|
| - desc.fHeight = clipSpaceIBounds.height();
|
| - desc.fConfig = kRGBA_8888_GrPixelConfig;
|
| - if (willUpload ||
|
| - this->getContext()->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
|
| - // We would always like A8 but it isn't supported on all platforms
|
| + desc.fWidth = width;
|
| + desc.fHeight = height;
|
| + desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
|
| + if (!renderTarget || fDrawTarget->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
|
| desc.fConfig = kAlpha_8_GrPixelConfig;
|
| + } else {
|
| + desc.fConfig = kRGBA_8888_GrPixelConfig;
|
| }
|
|
|
| - fAACache.acquireMask(elementsGenID, desc, clipSpaceIBounds);
|
| - return fAACache.getLastMask();
|
| + GrTexture* texture = fDrawTarget->cmmAccess().resourceProvider()->createApproxTexture(desc, 0);
|
| + if (!texture) {
|
| + return nullptr;
|
| + }
|
| + texture->resourcePriv().setUniqueKey(key);
|
| + return texture;
|
| }
|
|
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// Create a 8-bit clip mask in alpha
|
| GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| GrReducedClip::InitialState initialState,
|
| const GrReducedClip::ElementList& elements,
|
| const SkVector& clipToMaskOffset,
|
| const SkIRect& clipSpaceIBounds) {
|
| SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
|
| -
|
| - // First, check for cached texture
|
| - GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBounds);
|
| - if (result) {
|
| + GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProvider();
|
| + GrUniqueKey key;
|
| + GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key);
|
| + if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) {
|
| fCurrClipMaskType = kAlpha_ClipMaskType;
|
| - return result;
|
| + return texture;
|
| }
|
|
|
| + SkAutoTUnref<GrTexture> texture(this->createCachedMask(
|
| + clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true));
|
| +
|
| // There's no texture in the cache. Let's try to allocate it then.
|
| - result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, false);
|
| - if (nullptr == result) {
|
| - fAACache.reset();
|
| + if (!texture) {
|
| return nullptr;
|
| }
|
|
|
| @@ -589,7 +576,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| fDrawTarget->clear(&maskSpaceIBounds,
|
| GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000,
|
| true,
|
| - result->asRenderTarget());
|
| + texture->asRenderTarget());
|
|
|
| // When we use the stencil in the below loop it is important to have this clip installed.
|
| // The second pass that zeros the stencil buffer renders the rect maskSpaceIBounds so the first
|
| @@ -608,7 +595,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
|
|
| pipelineBuilder.setClip(clip);
|
| GrPathRenderer* pr = nullptr;
|
| - bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, result, &pr, element);
|
| + bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, texture, &pr, element);
|
| GrTexture* dst;
|
| // This is the bounds of the clip element in the space of the alpha-mask. The temporary
|
| // mask buffer can be substantially larger than the actually clip stack element. We
|
| @@ -629,7 +616,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| temp.reset(this->createTempMask(maskSpaceIBounds.fRight,
|
| maskSpaceIBounds.fBottom));
|
| if (!temp) {
|
| - fAACache.reset();
|
| + texture->resourcePriv().removeUniqueKey();
|
| return nullptr;
|
| }
|
| }
|
| @@ -643,7 +630,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| } else {
|
| // draw directly into the result with the stencil set to make the pixels affected
|
| // by the clip shape be non-zero.
|
| - dst = result;
|
| + dst = texture;
|
| GR_STATIC_CONST_SAME_STENCIL(kStencilInElement,
|
| kReplace_StencilOp,
|
| kReplace_StencilOp,
|
| @@ -656,25 +643,25 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| }
|
|
|
| if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr)) {
|
| - fAACache.reset();
|
| + texture->resourcePriv().removeUniqueKey();
|
| return nullptr;
|
| }
|
|
|
| if (useTemp) {
|
| GrPipelineBuilder backgroundPipelineBuilder;
|
| - backgroundPipelineBuilder.setRenderTarget(result->asRenderTarget());
|
| + backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarget());
|
|
|
| // Now draw into the accumulator using the real operation and the temp buffer as a
|
| // texture
|
| this->mergeMask(&backgroundPipelineBuilder,
|
| - result,
|
| + texture,
|
| temp,
|
| op,
|
| maskSpaceIBounds,
|
| maskSpaceElementIBounds);
|
| } else {
|
| GrPipelineBuilder backgroundPipelineBuilder;
|
| - backgroundPipelineBuilder.setRenderTarget(result->asRenderTarget());
|
| + backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarget());
|
|
|
| set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder);
|
| // Draw to the exterior pixels (those with a zero stencil value).
|
| @@ -697,12 +684,12 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| // all the remaining ops can just be directly draw into the accumulation buffer
|
| set_coverage_drawing_xpf(op, false, &pipelineBuilder);
|
| // The color passed in here does not matter since the coverageSetOpXP won't read it.
|
| - this->drawElement(&pipelineBuilder, translate, result, element);
|
| + this->drawElement(&pipelineBuilder, translate, texture, element);
|
| }
|
| }
|
|
|
| fCurrClipMaskType = kAlpha_ClipMaskType;
|
| - return result;
|
| + return texture.detach();
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -1079,10 +1066,11 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
|
| const SkVector& clipToMaskOffset,
|
| const SkIRect& clipSpaceIBounds) {
|
| SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
|
| -
|
| - GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBounds);
|
| - if (result) {
|
| - return result;
|
| + GrUniqueKey key;
|
| + GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key);
|
| + GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProvider();
|
| + if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) {
|
| + return texture;
|
| }
|
|
|
| // The mask texture may be larger than necessary. We round out the clip space bounds and pin
|
| @@ -1133,9 +1121,9 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
|
| }
|
|
|
| // Allocate clip mask texture
|
| - result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, true);
|
| + GrTexture* result = this->createCachedMask(clipSpaceIBounds.width(), clipSpaceIBounds.height(),
|
| + key, false);
|
| if (nullptr == result) {
|
| - fAACache.reset();
|
| return nullptr;
|
| }
|
| helper.toTexture(result);
|
| @@ -1145,9 +1133,6 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| -void GrClipMaskManager::purgeResources() {
|
| - fAACache.purgeResources();
|
| -}
|
|
|
| void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stencilAttachment,
|
| GrStencilSettings* settings) {
|
|
|