aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2015-10-28 11:01:41 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-10-28 11:01:41 -0700
commit544b9aa9e77389034f207601508cc2e46d08d6e6 (patch)
tree5d084e1809fe5c52a2885f335db11d44d360c91e /src
parentd5fa77ff6a0da93c613e8fc556d96197005ff768 (diff)
Remove gpu-side clip mask merging from clip mask manager
In the clip mask merging path, the CMM creates new renderTargets and draws to them. In the non-MDB world this is okay b.c. all the draws land in the same drawTarget anyway. In the MDB world the draws for the new renderTargets have to land in different drawTargets. This can be resolved by a lot of plumbing and refactoring to create drawContexts for the created renderTargets or by removing the mask-merging drawing path. Since, https://codereview.chromium.org/1424853002/ (Disable gpu-side clip mask merging in the clip mask manager), appears to have stuck, this CL removes the clip mask merging code. BUG=skia:4094 BUG=skia:4519 Review URL: https://codereview.chromium.org/1418073005
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrClipMaskManager.cpp186
-rw-r--r--src/gpu/GrClipMaskManager.h12
2 files changed, 53 insertions, 145 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index ff00a94f5a..445c6dbc78 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -99,21 +99,14 @@ static bool path_needs_SW_renderer(GrContext* context,
// Determines whether it is possible to draw the element to both the stencil buffer and the
// alpha mask simultaneously. If so and the element is a path a compatible path renderer is
// also returned.
-static bool can_stencil_and_draw_element(GrContext* context,
+static GrPathRenderer* get_path_renderer(GrContext* context,
GrPipelineBuilder* pipelineBuilder,
- GrTexture* texture,
const SkMatrix& viewMatrix,
- const SkClipStack::Element* element,
- GrPathRenderer** pr) {
- pipelineBuilder->setRenderTarget(texture->asRenderTarget());
-
+ const SkClipStack::Element* element) {
+ GrPathRenderer* pr;
static const bool kNeedsStencil = true;
- return !path_needs_SW_renderer(context,
- *pipelineBuilder,
- viewMatrix,
- element,
- pr,
- kNeedsStencil);
+ path_needs_SW_renderer(context, *pipelineBuilder, viewMatrix, element, &pr, kNeedsStencil);
+ return pr;
}
GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
@@ -121,8 +114,17 @@ GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
, fClipMode(kIgnoreClip_StencilClipMode) {
}
-GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().context(); }
+GrContext* GrClipMaskManager::getContext() {
+ return fDrawTarget->cmmAccess().context();
+}
+const GrCaps* GrClipMaskManager::caps() const {
+ return fDrawTarget->caps();
+}
+
+GrResourceProvider* GrClipMaskManager::resourceProvider() {
+ return fDrawTarget->cmmAccess().resourceProvider();
+}
/*
* This method traverses the clip stack to see if the GrSoftwarePathRenderer
* will be used on any element. If so, it returns true to indicate that the
@@ -482,48 +484,6 @@ bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder,
return true;
}
-void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder,
- GrTexture* dstMask,
- GrTexture* srcMask,
- SkRegion::Op op,
- const SkIRect& dstBound,
- const SkIRect& srcBound) {
- pipelineBuilder->setRenderTarget(dstMask->asRenderTarget());
-
- // We want to invert the coverage here
- set_coverage_drawing_xpf(op, false, pipelineBuilder);
-
- SkMatrix sampleM;
- sampleM.setIDiv(srcMask->width(), srcMask->height());
-
- pipelineBuilder->addCoverageFragmentProcessor(
- GrTextureDomainEffect::Create(srcMask,
- sampleM,
- GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
- GrTextureDomain::kDecal_Mode,
- GrTextureParams::kNone_FilterMode))->unref();
-
- // The color passed in here does not matter since the coverageSetOpXP won't read it.
- fDrawTarget->drawNonAARect(*pipelineBuilder,
- GrColor_WHITE,
- SkMatrix::I(),
- SkRect::Make(dstBound));
-}
-
-GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
- GrSurfaceDesc desc;
- desc.fFlags = kRenderTarget_GrSurfaceFlag;
- desc.fWidth = width;
- desc.fHeight = height;
- if (this->getContext()->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
- desc.fConfig = kAlpha_8_GrPixelConfig;
- } else {
- desc.fConfig = kRGBA_8888_GrPixelConfig;
- }
-
- return this->getContext()->textureProvider()->createApproxTexture(desc);
-}
-
////////////////////////////////////////////////////////////////////////////////
// Create a 8-bit clip mask in alpha
@@ -541,13 +501,13 @@ GrTexture* GrClipMaskManager::createCachedMask(int width, int height, const GrUn
desc.fWidth = width;
desc.fHeight = height;
desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
- if (!renderTarget || fDrawTarget->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
+ if (!renderTarget || this->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
desc.fConfig = kAlpha_8_GrPixelConfig;
} else {
desc.fConfig = kRGBA_8888_GrPixelConfig;
}
- GrTexture* texture = fDrawTarget->cmmAccess().resourceProvider()->createApproxTexture(desc, 0);
+ GrTexture* texture = this->resourceProvider()->createApproxTexture(desc, 0);
if (!texture) {
return nullptr;
}
@@ -560,17 +520,16 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
const GrReducedClip::ElementList& elements,
const SkVector& clipToMaskOffset,
const SkIRect& clipSpaceIBounds) {
- GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProvider();
+ GrResourceProvider* resourceProvider = this->resourceProvider();
GrUniqueKey key;
GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key);
if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) {
return texture;
}
+ // There's no texture in the cache. Let's try to allocate it then.
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.
if (!texture) {
return nullptr;
}
@@ -594,8 +553,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
// The second pass that zeros the stencil buffer renders the rect maskSpaceIBounds so the first
// pass must not set values outside of this bounds or stencil values outside the rect won't be
// cleared.
- GrClip clip(maskSpaceIBounds);
- SkAutoTUnref<GrTexture> temp;
+ const GrClip clip(maskSpaceIBounds);
// walk through each clip element and perform its set op
for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get(); iter.next()) {
@@ -606,78 +564,36 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setClip(clip);
- GrPathRenderer* pr = nullptr;
- bool useTemp = !can_stencil_and_draw_element(this->getContext(), &pipelineBuilder,
- texture, translate, element, &pr);
-
- // useSWOnlyPath should now filter out all cases where gpu-side mask merging is
- // performed. See skbug.com/4519 for rationale and details.
- SkASSERT(!useTemp);
-
- 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
- // touch the minimum number of pixels necessary and use decal mode to combine it with
- // the accumulator.
- SkIRect maskSpaceElementIBounds;
-
- if (useTemp) {
- if (invert) {
- maskSpaceElementIBounds = maskSpaceIBounds;
- } else {
- SkRect elementBounds = element->getBounds();
- elementBounds.offset(clipToMaskOffset);
- elementBounds.roundOut(&maskSpaceElementIBounds);
- }
-
- if (!temp) {
- temp.reset(this->createTempMask(maskSpaceIBounds.fRight,
- maskSpaceIBounds.fBottom));
- if (!temp) {
- texture->resourcePriv().removeUniqueKey();
- return nullptr;
- }
- }
- dst = temp;
- // clear the temp target and set blend to replace
- fDrawTarget->clear(&maskSpaceElementIBounds,
- invert ? 0xffffffff : 0x00000000,
- true,
- dst->asRenderTarget());
- set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelineBuilder);
- } else {
- // draw directly into the result with the stencil set to make the pixels affected
- // by the clip shape be non-zero.
- dst = texture;
- GR_STATIC_CONST_SAME_STENCIL(kStencilInElement,
- kReplace_StencilOp,
- kReplace_StencilOp,
- kAlways_StencilFunc,
- 0xffff,
- 0xffff,
- 0xffff);
- pipelineBuilder.setStencil(kStencilInElement);
- set_coverage_drawing_xpf(op, invert, &pipelineBuilder);
+ pipelineBuilder.setRenderTarget(texture->asRenderTarget());
+
+ GrPathRenderer* pr = get_path_renderer(this->getContext(), &pipelineBuilder,
+ translate, element);
+ if (Element::kRect_Type != element->getType() && !pr) {
+ // useSWOnlyPath should now filter out all cases where gpu-side mask merging would
+ // be performed (i.e., pr would be NULL for a non-rect path). See skbug.com/4519
+ // for rationale and details.
+ SkASSERT(0);
+ continue;
}
- if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr)) {
+ // draw directly into the result with the stencil set to make the pixels affected
+ // by the clip shape be non-zero.
+ GR_STATIC_CONST_SAME_STENCIL(kStencilInElement,
+ kReplace_StencilOp,
+ kReplace_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0xffff,
+ 0xffff);
+ pipelineBuilder.setStencil(kStencilInElement);
+ set_coverage_drawing_xpf(op, invert, &pipelineBuilder);
+
+ if (!this->drawElement(&pipelineBuilder, translate, texture, element, pr)) {
texture->resourcePriv().removeUniqueKey();
return nullptr;
}
- if (useTemp) {
- GrPipelineBuilder backgroundPipelineBuilder;
- backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarget());
-
- // Now draw into the accumulator using the real operation and the temp buffer as a
- // texture
- this->mergeMask(&backgroundPipelineBuilder,
- texture,
- temp,
- op,
- maskSpaceIBounds,
- maskSpaceElementIBounds);
- } else {
+ {
GrPipelineBuilder backgroundPipelineBuilder;
backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarget());
@@ -720,8 +636,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
const SkIPoint& clipSpaceToStencilOffset) {
SkASSERT(rt);
- GrStencilAttachment* stencilAttachment =
- fDrawTarget->cmmAccess().resourceProvider()->attachStencilAttachment(rt);
+ GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachStencilAttachment(rt);
if (nullptr == stencilAttachment) {
return false;
}
@@ -977,14 +892,13 @@ void GrClipMaskManager::setPipelineBuilderStencil(const GrPipelineBuilder& pipel
int stencilBits = 0;
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
- GrStencilAttachment* stencilAttachment =
- fDrawTarget->cmmAccess().resourceProvider()->attachStencilAttachment(rt);
+ GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachStencilAttachment(rt);
if (stencilAttachment) {
stencilBits = stencilAttachment->bits();
}
- SkASSERT(fDrawTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
- SkASSERT(fDrawTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
+ SkASSERT(this->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
+ SkASSERT(this->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
this->adjustStencilParams(&settings, fClipMode, stencilBits);
ars->set(&pipelineBuilder);
ars->setStencil(settings);
@@ -1005,7 +919,7 @@ void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,
unsigned int userBits = clipBit - 1;
GrStencilSettings::Face face = GrStencilSettings::kFront_Face;
- bool twoSided = fDrawTarget->caps()->twoSidedStencilSupport();
+ bool twoSided = this->caps()->twoSidedStencilSupport();
bool finished = false;
while (!finished) {
@@ -1077,7 +991,7 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
const SkIRect& clipSpaceIBounds) {
GrUniqueKey key;
GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key);
- GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProvider();
+ GrResourceProvider* resourceProvider = this->resourceProvider();
if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) {
return texture;
}
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index b0e9b4f943..2d9816c84c 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -21,6 +21,7 @@
class GrDrawTarget;
class GrPathRenderer;
class GrPathRendererChain;
+class GrResourceProvider;
class GrTexture;
class SkPath;
@@ -72,6 +73,8 @@ public:
private:
inline GrContext* getContext();
+ inline const GrCaps* caps() const;
+ inline GrResourceProvider* resourceProvider();
/**
* Informs the helper function adjustStencilParams() about how the stencil
@@ -134,15 +137,6 @@ private:
const SkClipStack::Element*,
GrPathRenderer* pr = nullptr);
- void mergeMask(GrPipelineBuilder*,
- GrTexture* dstMask,
- GrTexture* srcMask,
- SkRegion::Op op,
- const SkIRect& dstBound,
- const SkIRect& srcBound);
-
- GrTexture* createTempMask(int width, int height);
-
/**
* Called prior to return control back the GrGpu in setupClipping. It updates the
* GrPipelineBuilder with stencil settings that account for stencil-based clipping.