aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-02-24 08:37:13 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-24 14:21:50 +0000
commit875218ebd816eb8931c64c5018ce2dc9bc8fd695 (patch)
treee2936879d44b66aea231b3098342866b9ddf714c
parente3d4421e67d328fc0994bbfd25deab0ce3964dc2 (diff)
Wrap cached GrTextures in GrTextureProxies (e.g., blur profiles, nine-patch blurs, etc.)
This is pulled out of: https://skia-review.googlesource.com/c/8823/ (Remove GrFragmentProcessor-derived class' GrTexture-based ctors) Change-Id: I5feac04dc1bf54bd74c65febdf6bba9e7ce28f55 Reviewed-on: https://skia-review.googlesource.com/8942 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r--src/effects/GrCircleBlurFragmentProcessor.cpp40
-rw-r--r--src/effects/GrCircleBlurFragmentProcessor.h8
-rw-r--r--src/effects/SkBlurMaskFilter.cpp66
-rw-r--r--src/gpu/GrClipStackClip.cpp48
-rw-r--r--src/gpu/GrClipStackClip.h10
-rw-r--r--src/gpu/SkGr.cpp4
-rw-r--r--tests/ClipStackTest.cpp7
7 files changed, 109 insertions, 74 deletions
diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp
index 6332895b84..de4bb58231 100644
--- a/src/effects/GrCircleBlurFragmentProcessor.cpp
+++ b/src/effects/GrCircleBlurFragmentProcessor.cpp
@@ -82,15 +82,17 @@ void GrCircleBlurFragmentProcessor::GLSLProcessor::onSetData(const GrGLSLProgram
///////////////////////////////////////////////////////////////////////////////
-GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(const SkRect& circle,
+GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(GrTextureProvider* textureProvider,
+ const SkRect& circle,
float textureRadius,
float solidRadius,
- GrTexture* blurProfile)
+ sk_sp<GrTextureProxy> blurProfile)
: INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
, fCircle(circle)
, fSolidRadius(solidRadius)
, fTextureRadius(textureRadius)
- , fBlurProfileSampler(blurProfile, GrSamplerParams::kBilerp_FilterMode) {
+ , fBlurProfileSampler(textureProvider, std::move(blurProfile),
+ GrSamplerParams::kBilerp_FilterMode) {
this->initClassID<GrCircleBlurFragmentProcessor>();
this->addTextureSampler(&fBlurProfileSampler);
}
@@ -258,8 +260,10 @@ static uint8_t* create_half_plane_profile(int profileWidth) {
return profile;
}
-static GrTexture* create_profile_texture(GrTextureProvider* textureProvider, const SkRect& circle,
- float sigma, float* solidRadius, float* textureRadius) {
+static sk_sp<GrTextureProxy> create_profile_texture(GrTextureProvider* textureProvider,
+ const SkRect& circle,
+ float sigma,
+ float* solidRadius, float* textureRadius) {
float circleR = circle.width() / 2.0f;
// Profile textures are cached by the ratio of sigma to circle radius and by the size of the
// profile texture (binned by powers of 2).
@@ -295,7 +299,8 @@ static GrTexture* create_profile_texture(GrTextureProvider* textureProvider, con
builder[0] = sigmaToCircleRRatioFixed;
builder.finish();
- GrTexture *blurProfile = textureProvider->findAndRefTextureByUniqueKey(key);
+ // MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs
+ sk_sp<GrTexture> blurProfile(textureProvider->findAndRefTextureByUniqueKey(key));
if (!blurProfile) {
static constexpr int kProfileTextureWidth = 512;
GrSurfaceDesc texDesc;
@@ -313,28 +318,33 @@ static GrTexture* create_profile_texture(GrTextureProvider* textureProvider, con
kProfileTextureWidth));
}
- blurProfile = textureProvider->createTexture(texDesc, SkBudgeted::kYes, profile.get(), 0);
- if (blurProfile) {
- textureProvider->assignUniqueKeyToTexture(key, blurProfile);
+ blurProfile.reset(textureProvider->createTexture(texDesc, SkBudgeted::kYes,
+ profile.get(), 0));
+ if (!blurProfile) {
+ return nullptr;
}
+
+ textureProvider->assignUniqueKeyToTexture(key, blurProfile.get());
}
- return blurProfile;
+ return GrSurfaceProxy::MakeWrapped(std::move(blurProfile));
}
//////////////////////////////////////////////////////////////////////////////
-sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(GrTextureProvider*textureProvider,
+sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(GrTextureProvider* textureProvider,
const SkRect& circle, float sigma) {
float solidRadius;
float textureRadius;
- sk_sp<GrTexture> profile(create_profile_texture(textureProvider, circle, sigma,
- &solidRadius, &textureRadius));
+ sk_sp<GrTextureProxy> profile(create_profile_texture(textureProvider, circle, sigma,
+ &solidRadius, &textureRadius));
if (!profile) {
return nullptr;
}
- return sk_sp<GrFragmentProcessor>(
- new GrCircleBlurFragmentProcessor(circle, textureRadius, solidRadius, profile.get()));
+ return sk_sp<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(textureProvider,
+ circle,
+ textureRadius, solidRadius,
+ std::move(profile)));
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/src/effects/GrCircleBlurFragmentProcessor.h b/src/effects/GrCircleBlurFragmentProcessor.h
index f577cc7e42..9b1fdbf08a 100644
--- a/src/effects/GrCircleBlurFragmentProcessor.h
+++ b/src/effects/GrCircleBlurFragmentProcessor.h
@@ -34,8 +34,7 @@ public:
return str;
}
- static sk_sp<GrFragmentProcessor> Make(GrTextureProvider*textureProvider,
- const SkRect& circle, float sigma);
+ static sk_sp<GrFragmentProcessor> Make(GrTextureProvider*, const SkRect& circle, float sigma);
private:
// This nested GLSL processor implementation is defined in the cpp file.
@@ -46,8 +45,9 @@ private:
* The x texture coord should map from 0 to 1 across the radius range of solidRadius to
* solidRadius + textureRadius.
*/
- GrCircleBlurFragmentProcessor(const SkRect& circle, float textureRadius, float innerRadius,
- GrTexture* blurProfile);
+ GrCircleBlurFragmentProcessor(GrTextureProvider*, const SkRect& circle,
+ float textureRadius, float innerRadius,
+ sk_sp<GrTextureProxy> blurProfile);
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 69b518235e..507b6975f8 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -780,7 +780,7 @@ public:
return nullptr;
}
- sk_sp<GrTexture> blurProfile(CreateBlurProfileTexture(textureProvider, sigma));
+ sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(textureProvider, sigma));
if (!blurProfile) {
return nullptr;
}
@@ -804,8 +804,8 @@ public:
precision = kDefault_GrSLPrecision;
}
- return sk_sp<GrFragmentProcessor>(
- new GrRectBlurEffect(rect, sigma, blurProfile.get(), precision));
+ return sk_sp<GrFragmentProcessor>(new GrRectBlurEffect(textureProvider, rect, sigma,
+ std::move(blurProfile), precision));
}
const SkRect& getRect() const { return fRect; }
@@ -813,8 +813,8 @@ public:
GrSLPrecision precision() const { return fPrecision; }
private:
- GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blurProfile,
- GrSLPrecision fPrecision);
+ GrRectBlurEffect(GrTextureProvider*, const SkRect& rect, float sigma,
+ sk_sp<GrTextureProxy> blurProfile, GrSLPrecision fPrecision);
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
@@ -822,7 +822,7 @@ private:
bool onIsEqual(const GrFragmentProcessor&) const override;
- static GrTexture* CreateBlurProfileTexture(GrTextureProvider*, float sigma);
+ static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrTextureProvider*, float sigma);
SkRect fRect;
float fSigma;
@@ -940,8 +940,9 @@ void GrGLRectBlurEffect::onSetData(const GrGLSLProgramDataManager& pdman,
pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma()));
}
-GrTexture* GrRectBlurEffect::CreateBlurProfileTexture(GrTextureProvider* textureProvider,
- float sigma) {
+// MDB TODO (caching): This side-steps the issue of texture proxies with unique IDs
+sk_sp<GrTextureProxy> GrRectBlurEffect::CreateBlurProfileTexture(GrTextureProvider* textureProvider,
+ float sigma) {
GrSurfaceDesc texDesc;
unsigned int profileSize = SkScalarCeilToInt(6*sigma);
@@ -957,26 +958,31 @@ GrTexture* GrRectBlurEffect::CreateBlurProfileTexture(GrTextureProvider* texture
builder[0] = profileSize;
builder.finish();
- GrTexture *blurProfile = textureProvider->findAndRefTextureByUniqueKey(key);
+ sk_sp<GrTexture> blurProfile(textureProvider->findAndRefTextureByUniqueKey(key));
if (!blurProfile) {
std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
- blurProfile = textureProvider->createTexture(texDesc, SkBudgeted::kYes, profile.get(), 0);
- if (blurProfile) {
- textureProvider->assignUniqueKeyToTexture(key, blurProfile);
+ blurProfile.reset(textureProvider->createTexture(texDesc, SkBudgeted::kYes,
+ profile.get(), 0));
+ if (!blurProfile) {
+ return nullptr;
}
+
+ textureProvider->assignUniqueKeyToTexture(key, blurProfile.get());
}
- return blurProfile;
+ return GrSurfaceProxy::MakeWrapped(std::move(blurProfile));
}
-GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture* blurProfile,
+GrRectBlurEffect::GrRectBlurEffect(GrTextureProvider* textureProvider,
+ const SkRect& rect, float sigma,
+ sk_sp<GrTextureProxy> blurProfile,
GrSLPrecision precision)
: INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
, fRect(rect)
, fSigma(sigma)
- , fBlurProfileSampler(blurProfile)
+ , fBlurProfileSampler(textureProvider, std::move(blurProfile))
, fPrecision(precision) {
this->initClassID<GrRectBlurEffect>();
this->addTextureSampler(&fBlurProfileSampler);
@@ -1070,7 +1076,7 @@ public:
float sigma, float xformedSigma,
const SkRRect& srcRRect, const SkRRect& devRRect);
- virtual ~GrRRectBlurEffect() {}
+ ~GrRRectBlurEffect() override {}
const char* name() const override { return "GrRRectBlur"; }
const SkRRect& getRRect() const { return fRRect; }
@@ -1079,7 +1085,8 @@ public:
private:
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
- GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture);
+ GrRRectBlurEffect(GrTextureProvider*, float sigma, const SkRRect&,
+ sk_sp<GrTextureProxy> profileProxy);
virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps,
GrProcessorKeyBuilder* b) const override;
@@ -1095,10 +1102,11 @@ private:
typedef GrFragmentProcessor INHERITED;
};
-static sk_sp<GrTexture> find_or_create_rrect_blur_mask(GrContext* context,
- const SkRRect& rrectToDraw,
- const SkISize& size,
- float xformedSigma) {
+// MDB TODO (caching): This side-steps the issue of texture proxies with unique IDs
+static sk_sp<GrTextureProxy> find_or_create_rrect_blur_mask(GrContext* context,
+ const SkRRect& rrectToDraw,
+ const SkISize& size,
+ float xformedSigma) {
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
GrUniqueKey key;
GrUniqueKey::Builder builder(&key, kDomain, 9);
@@ -1152,7 +1160,7 @@ static sk_sp<GrTexture> find_or_create_rrect_blur_mask(GrContext* context,
context->textureProvider()->assignUniqueKeyToTexture(key, mask.get());
}
- return mask;
+ return GrSurfaceProxy::MakeWrapped(std::move(mask));
}
sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context,
@@ -1186,21 +1194,25 @@ sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context,
return nullptr;
}
- sk_sp<GrTexture> mask(find_or_create_rrect_blur_mask(context, rrectToDraw, size, xformedSigma));
+ sk_sp<GrTextureProxy> mask(find_or_create_rrect_blur_mask(context, rrectToDraw,
+ size, xformedSigma));
if (!mask) {
return nullptr;
}
- return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma,
+ return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(context->textureProvider(),
+ xformedSigma,
devRRect,
- mask.get()));
+ std::move(mask)));
}
-GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture* ninePatchTexture)
+GrRRectBlurEffect::GrRRectBlurEffect(GrTextureProvider* textureProvider,
+ float sigma, const SkRRect& rrect,
+ sk_sp<GrTextureProxy> ninePatchProxy)
: INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
, fRRect(rrect)
, fSigma(sigma)
- , fNinePatchSampler(ninePatchTexture) {
+ , fNinePatchSampler(textureProvider, std::move(ninePatchProxy)) {
this->initClassID<GrRRectBlurEffect>();
this->addTextureSampler(&fNinePatchSampler);
}
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 7b50d52332..375ee8ba13 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -85,10 +85,11 @@ void GrClipStackClip::getConservativeBounds(int width, int height, SkIRect* devR
////////////////////////////////////////////////////////////////////////////////
// set up the draw state to enable the aa clipping mask.
-static sk_sp<GrFragmentProcessor> create_fp_for_mask(GrTexture* result,
+static sk_sp<GrFragmentProcessor> create_fp_for_mask(GrContext* context,
+ sk_sp<GrTextureProxy> mask,
const SkIRect &devBound) {
SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
- return GrDeviceSpaceTextureDecalFragmentProcessor::Make(result, domainTexels,
+ return GrDeviceSpaceTextureDecalFragmentProcessor::Make(context, std::move(mask), domainTexels,
{devBound.fLeft, devBound.fTop});
}
@@ -338,7 +339,7 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar
// If the stencil buffer is multisampled we can use it to do everything.
if (!renderTargetContext->isStencilBufferMultisampled() && reducedClip.requiresAA()) {
- sk_sp<GrTexture> result;
+ sk_sp<GrTextureProxy> result;
if (UseSWOnlyPath(context, hasUserStencilSettings, renderTargetContext, reducedClip)) {
// The clip geometry is complex enough that it will be more efficient to create it
// entirely in software
@@ -352,7 +353,7 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar
// clipSpace bounds. We determine the mask's position WRT to the render target here.
SkIRect rtSpaceMaskBounds = reducedClip.ibounds();
rtSpaceMaskBounds.offset(-fOrigin);
- out->addCoverageFP(create_fp_for_mask(result.get(), rtSpaceMaskBounds));
+ out->addCoverageFP(create_fp_for_mask(context, std::move(result), rtSpaceMaskBounds));
return true;
}
// if alpha clip mask creation fails fall through to the non-AA code paths
@@ -409,13 +410,16 @@ static void add_invalidate_on_pop_message(const SkClipStack& stack, int32_t clip
SkDEBUGFAIL("Gen ID was not found in stack.");
}
-sk_sp<GrTexture> GrClipStackClip::createAlphaClipMask(GrContext* context,
- const GrReducedClip& reducedClip) const {
+// MDB TODO (caching): this side-steps the issue of texture proxies cached by unique ID
+sk_sp<GrTextureProxy> GrClipStackClip::createAlphaClipMask(GrContext* context,
+ const GrReducedClip& reducedClip) const {
GrResourceProvider* resourceProvider = context->resourceProvider();
GrUniqueKey key;
create_clip_mask_key(reducedClip.elementsGenID(), reducedClip.ibounds(), &key);
- if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) {
- return sk_sp<GrTexture>(texture);
+
+ sk_sp<GrTexture> texture(resourceProvider->findAndRefTextureByUniqueKey(key));
+ if (texture) {
+ return GrSurfaceProxy::MakeWrapped(std::move(texture));
}
sk_sp<GrRenderTargetContext> rtc(context->makeRenderTargetContextWithFallback(
@@ -432,22 +436,32 @@ sk_sp<GrTexture> GrClipStackClip::createAlphaClipMask(GrContext* context,
return nullptr;
}
- sk_sp<GrTexture> texture(rtc->asTexture());
- if (!texture) {
+ sk_sp<GrTextureProxy> result(rtc->asTextureProxyRef());
+ if (!result) {
return nullptr;
}
- texture->resourcePriv().setUniqueKey(key);
+ GrTexture* tex = result->instantiate(context->textureProvider());
+ if (!tex) {
+ return nullptr;
+ }
+
+ tex->resourcePriv().setUniqueKey(key);
add_invalidate_on_pop_message(*fStack, reducedClip.elementsGenID(), key);
- return texture;
+
+ return result;
}
-sk_sp<GrTexture> GrClipStackClip::createSoftwareClipMask(GrContext* context,
- const GrReducedClip& reducedClip) const {
+// MDB TODO (caching): This side-steps the caching of texture proxies by unique ID
+sk_sp<GrTextureProxy> GrClipStackClip::createSoftwareClipMask(
+ GrContext* context,
+ const GrReducedClip& reducedClip) const {
GrUniqueKey key;
create_clip_mask_key(reducedClip.elementsGenID(), reducedClip.ibounds(), &key);
- if (GrTexture* texture = context->textureProvider()->findAndRefTextureByUniqueKey(key)) {
- return sk_sp<GrTexture>(texture);
+
+ sk_sp<GrTexture> texture(context->textureProvider()->findAndRefTextureByUniqueKey(key));
+ if (texture) {
+ return GrSurfaceProxy::MakeWrapped(std::move(texture));
}
// The mask texture may be larger than necessary. We round out the clip space bounds and pin
@@ -510,5 +524,5 @@ sk_sp<GrTexture> GrClipStackClip::createSoftwareClipMask(GrContext* context,
tex->resourcePriv().setUniqueKey(key);
add_invalidate_on_pop_message(*fStack, reducedClip.elementsGenID(), key);
- return sk_ref_sp(tex);
+ return result;
}
diff --git a/src/gpu/GrClipStackClip.h b/src/gpu/GrClipStackClip.h
index 1c4d40b173..b8c5d17286 100644
--- a/src/gpu/GrClipStackClip.h
+++ b/src/gpu/GrClipStackClip.h
@@ -12,9 +12,7 @@
#include "SkClipStack.h"
class GrPathRenderer;
-class GrTexture;
-class GrTextureProvider;
-class GrUniqueKey;
+class GrTextureProxy;
/**
* GrClipStackClip can apply a generic SkClipStack to the draw state. It may need to generate an
@@ -40,7 +38,7 @@ public:
bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA* aa) const override;
- sk_sp<GrTexture> testingOnly_createClipMask(GrContext*) const;
+ sk_sp<GrTextureProxy> testingOnly_createClipMask(GrContext*) const;
static const char kMaskTestTag[];
private:
@@ -54,10 +52,10 @@ private:
// Creates an alpha mask of the clip. The mask is a rasterization of elements through the
// rect specified by clipSpaceIBounds.
- sk_sp<GrTexture> createAlphaClipMask(GrContext*, const GrReducedClip&) const;
+ sk_sp<GrTextureProxy> createAlphaClipMask(GrContext*, const GrReducedClip&) const;
// Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture.
- sk_sp<GrTexture> createSoftwareClipMask(GrContext*, const GrReducedClip&) const;
+ sk_sp<GrTextureProxy> createSoftwareClipMask(GrContext*, const GrReducedClip&) const;
static bool UseSWOnlyPath(GrContext*,
bool hasUserStencilSettings,
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 45f6e6eb92..fe7e98c8d9 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -269,8 +269,8 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
nullptr, scaleAdjust);
}
-// For better or for worse, this method currently sidesteps the issue of caching an uninstantiated
-// proxy via a key.
+// MDB TODO (caching): For better or for worse, this method currently side-steps the issue of
+// caching an uninstantiated proxy via a key.
sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrContext* context, const SkBitmap& bitmap) {
GrUniqueKey originalKey;
diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp
index 744ef18d17..e3980504f2 100644
--- a/tests/ClipStackTest.cpp
+++ b/tests/ClipStackTest.cpp
@@ -1413,7 +1413,7 @@ DEF_TEST(ClipStack, reporter) {
//////////////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
-sk_sp<GrTexture> GrClipStackClip::testingOnly_createClipMask(GrContext* context) const {
+sk_sp<GrTextureProxy> GrClipStackClip::testingOnly_createClipMask(GrContext* context) const {
const GrReducedClip reducedClip(*fStack, SkRect::MakeWH(512, 512), 0);
return this->createSoftwareClipMask(context, reducedClip);
}
@@ -1440,8 +1440,9 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ClipMaskCache, reporter, ctxInfo) {
m.setTranslate(0.5, 0.5);
stack.save();
stack.clipPath(path, m, SkClipOp::kIntersect, true);
- auto mask = GrClipStackClip(&stack).testingOnly_createClipMask(context);
- REPORTER_ASSERT(reporter, 0 == strcmp(mask->getUniqueKey().tag(), kTag));
+ sk_sp<GrTextureProxy> mask = GrClipStackClip(&stack).testingOnly_createClipMask(context);
+ GrTexture* tex = mask->instantiate(context->textureProvider());
+ REPORTER_ASSERT(reporter, 0 == strcmp(tex->getUniqueKey().tag(), kTag));
// Make sure mask isn't pinned in cache.
mask.reset(nullptr);
context->flush();