Revert of Fix ClipMaskManager's SW-fallback logic (patchset #4 id:60001 of https://codereview.chromium.org/1421533007/ )
Reason for revert: Logic may be incorrect Original issue's description: > Fix ClipMaskManager's SW-fallback logic > > > 'useSWOnlyPath' was not correctly toggling between stencil and color draws so there was a mismatch with the behavior in createAlphaClipMask (i.e., we were inadvertently rendering some of the elements in a clip using SW but using stenciling for others - precisely what 'useSWOnlyPath' was intended to prevent). > > Committed: https://skia.googlesource.com/skia/+/5c3ea4cd3921e8904d4f201bcdedfd5b8a726542 TBR=bsalomon@google.com NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Review URL: https://codereview.chromium.org/1426443008
This commit is contained in:
parent
ee7d516d4b
commit
24cdec1744
@ -334,7 +334,7 @@ public:
|
||||
void getTestTarget(GrTestTarget*);
|
||||
|
||||
GrPathRenderer* getPathRenderer(
|
||||
const GrPipelineBuilder&,
|
||||
const GrPipelineBuilder*,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkPath& path,
|
||||
const GrStrokeInfo& stroke,
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
whether the path can be rendered with arbitrary stencil rules or not. See comments on
|
||||
StencilSupport in GrPathRenderer.h. */
|
||||
GrPathRenderer* getPathRenderer(const GrShaderCaps* shaderCaps,
|
||||
const GrPipelineBuilder&,
|
||||
const GrPipelineBuilder*,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkPath& path,
|
||||
const GrStrokeInfo& stroke,
|
||||
|
@ -46,71 +46,24 @@ static const GrFragmentProcessor* create_fp_for_mask(GrTexture* result, const Sk
|
||||
kDevice_GrCoordSet);
|
||||
}
|
||||
|
||||
// Does the path in 'element' require SW rendering? If so, return true (and,
|
||||
// optionally, set 'prOut' to NULL. If not, return false (and, optionally, set
|
||||
// 'prOut' to the non-SW path renderer that will do the job).
|
||||
static bool path_needs_SW_renderer(GrContext* context,
|
||||
const GrPipelineBuilder& pipelineBuilder,
|
||||
const SkMatrix& viewMatrix,
|
||||
const Element* element,
|
||||
GrPathRenderer** prOut,
|
||||
bool needsStencil) {
|
||||
if (Element::kRect_Type == element->getType()) {
|
||||
// rects can always be drawn directly w/o using the software path
|
||||
// TODO: skip rrects once we're drawing them directly.
|
||||
return false;
|
||||
} else {
|
||||
// We shouldn't get here with an empty clip element.
|
||||
SkASSERT(Element::kEmpty_Type != element->getType());
|
||||
|
||||
// the gpu alpha mask will draw the inverse paths as non-inverse to a temp buffer
|
||||
SkPath path;
|
||||
element->asPath(&path);
|
||||
if (path.isInverseFillType()) {
|
||||
path.toggleInverseFillType();
|
||||
}
|
||||
GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
|
||||
|
||||
GrPathRendererChain::DrawType type;
|
||||
|
||||
if (needsStencil) {
|
||||
type = element->isAA()
|
||||
? GrPathRendererChain::kStencilAndColorAntiAlias_DrawType
|
||||
: GrPathRendererChain::kStencilAndColor_DrawType;
|
||||
} else {
|
||||
type = element->isAA()
|
||||
? GrPathRendererChain::kColorAntiAlias_DrawType
|
||||
: GrPathRendererChain::kColor_DrawType;
|
||||
}
|
||||
|
||||
// the 'false' parameter disallows use of the SW path renderer
|
||||
GrPathRenderer* pr = context->getPathRenderer(pipelineBuilder, viewMatrix, path,
|
||||
stroke, false, type);
|
||||
if (prOut) {
|
||||
*prOut = pr;
|
||||
}
|
||||
return SkToBool(!pr);
|
||||
const SkPath& origPath,
|
||||
const GrStrokeInfo& stroke,
|
||||
bool doAA) {
|
||||
// the gpu alpha mask will draw the inverse paths as non-inverse to a temp buffer
|
||||
SkTCopyOnFirstWrite<SkPath> path(origPath);
|
||||
if (path->isInverseFillType()) {
|
||||
path.writable()->toggleInverseFillType();
|
||||
}
|
||||
}
|
||||
// last (false) parameter disallows use of the SW path renderer
|
||||
GrPathRendererChain::DrawType type = doAA ?
|
||||
GrPathRendererChain::kColorAntiAlias_DrawType :
|
||||
GrPathRendererChain::kColor_DrawType;
|
||||
|
||||
// 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,
|
||||
GrPipelineBuilder* pipelineBuilder,
|
||||
GrTexture* texture,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkClipStack::Element* element,
|
||||
GrPathRenderer** pr) {
|
||||
pipelineBuilder->setRenderTarget(texture->asRenderTarget());
|
||||
|
||||
static const bool kNeedsStencil = true;
|
||||
return !path_needs_SW_renderer(context,
|
||||
*pipelineBuilder,
|
||||
viewMatrix,
|
||||
element,
|
||||
pr,
|
||||
kNeedsStencil);
|
||||
return nullptr == context->getPathRenderer(&pipelineBuilder, viewMatrix, *path, stroke,
|
||||
false, type);
|
||||
}
|
||||
|
||||
GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
|
||||
@ -131,22 +84,24 @@ bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder,
|
||||
// TODO: generalize this function so that when
|
||||
// a clip gets complex enough it can just be done in SW regardless
|
||||
// of whether it would invoke the GrSoftwarePathRenderer.
|
||||
GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
|
||||
|
||||
// Set the matrix so that rendered clip elements are transformed to mask space from clip
|
||||
// space.
|
||||
const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMaskOffset.fY);
|
||||
SkMatrix translate;
|
||||
translate.setTranslate(clipToMaskOffset);
|
||||
|
||||
for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
|
||||
const Element* element = iter.get();
|
||||
|
||||
SkRegion::Op op = element->getOp();
|
||||
bool invert = element->isInverseFilled();
|
||||
bool needsStencil = invert ||
|
||||
SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op;
|
||||
|
||||
if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translate,
|
||||
element, nullptr, needsStencil)) {
|
||||
return true;
|
||||
// rects can always be drawn directly w/o using the software path
|
||||
// Skip rrects once we're drawing them directly.
|
||||
if (Element::kRect_Type != element->getType()) {
|
||||
SkPath path;
|
||||
element->asPath(&path);
|
||||
if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translate,
|
||||
path, stroke, element->isAA())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -457,7 +412,7 @@ bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder,
|
||||
GrPathRendererChain::DrawType type;
|
||||
type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType :
|
||||
GrPathRendererChain::kColor_DrawType;
|
||||
pr = this->getContext()->getPathRenderer(*pipelineBuilder, viewMatrix,
|
||||
pr = this->getContext()->getPathRenderer(pipelineBuilder, viewMatrix,
|
||||
path, stroke, false, type);
|
||||
}
|
||||
if (nullptr == pr) {
|
||||
@ -479,6 +434,32 @@ bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrClipMaskManager::canStencilAndDrawElement(GrPipelineBuilder* pipelineBuilder,
|
||||
GrTexture* target,
|
||||
GrPathRenderer** pr,
|
||||
const SkClipStack::Element* element) {
|
||||
pipelineBuilder->setRenderTarget(target->asRenderTarget());
|
||||
|
||||
if (Element::kRect_Type == element->getType()) {
|
||||
return true;
|
||||
} else {
|
||||
// We shouldn't get here with an empty clip element.
|
||||
SkASSERT(Element::kEmpty_Type != element->getType());
|
||||
SkPath path;
|
||||
element->asPath(&path);
|
||||
if (path.isInverseFillType()) {
|
||||
path.toggleInverseFillType();
|
||||
}
|
||||
GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
|
||||
GrPathRendererChain::DrawType type = element->isAA() ?
|
||||
GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
|
||||
GrPathRendererChain::kStencilAndColor_DrawType;
|
||||
*pr = this->getContext()->getPathRenderer(pipelineBuilder, SkMatrix::I(), path,
|
||||
stroke, false, type);
|
||||
return SkToBool(*pr);
|
||||
}
|
||||
}
|
||||
|
||||
void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder,
|
||||
GrTexture* dstMask,
|
||||
GrTexture* srcMask,
|
||||
@ -574,7 +555,8 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
||||
|
||||
// Set the matrix so that rendered clip elements are transformed to mask space from clip
|
||||
// space.
|
||||
const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMaskOffset.fY);
|
||||
SkMatrix translate;
|
||||
translate.setTranslate(clipToMaskOffset);
|
||||
|
||||
// The texture may be larger than necessary, this rect represents the part of the texture
|
||||
// we populate with a rasterization of the clip.
|
||||
@ -604,8 +586,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
||||
|
||||
pipelineBuilder.setClip(clip);
|
||||
GrPathRenderer* pr = nullptr;
|
||||
bool useTemp = !can_stencil_and_draw_element(this->getContext(), &pipelineBuilder,
|
||||
texture, translate, element, &pr);
|
||||
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
|
||||
@ -613,8 +594,6 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
||||
// the accumulator.
|
||||
SkIRect maskSpaceElementIBounds;
|
||||
|
||||
SkASSERT(!useTemp);
|
||||
|
||||
if (useTemp) {
|
||||
if (invert) {
|
||||
maskSpaceElementIBounds = maskSpaceIBounds;
|
||||
@ -780,7 +759,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
||||
if (fillInverted) {
|
||||
clipPath.toggleInverseFillType();
|
||||
}
|
||||
pr = this->getContext()->getPathRenderer(pipelineBuilder,
|
||||
pr = this->getContext()->getPathRenderer(&pipelineBuilder,
|
||||
viewMatrix,
|
||||
clipPath,
|
||||
stroke,
|
||||
|
@ -133,6 +133,14 @@ private:
|
||||
const SkClipStack::Element*,
|
||||
GrPathRenderer* pr = nullptr);
|
||||
|
||||
// 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.
|
||||
bool canStencilAndDrawElement(GrPipelineBuilder*,
|
||||
GrTexture* target,
|
||||
GrPathRenderer**,
|
||||
const SkClipStack::Element*);
|
||||
|
||||
void mergeMask(GrPipelineBuilder*,
|
||||
GrTexture* dstMask,
|
||||
GrTexture* srcMask,
|
||||
|
@ -541,7 +541,7 @@ void GrContext::flushSurfaceWrites(GrSurface* surface) {
|
||||
* Due to its expense, the software path renderer has split out so it can
|
||||
* can be individually allowed/disallowed via the "allowSW" boolean.
|
||||
*/
|
||||
GrPathRenderer* GrContext::getPathRenderer(const GrPipelineBuilder& pipelineBuilder,
|
||||
GrPathRenderer* GrContext::getPathRenderer(const GrPipelineBuilder* pipelineBuilder,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkPath& path,
|
||||
const GrStrokeInfo& stroke,
|
||||
|
@ -691,7 +691,7 @@ void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder,
|
||||
const GrStrokeInfo* strokeInfoPtr = &strokeInfo;
|
||||
|
||||
// Try a 1st time without stroking the path and without allowing the SW renderer
|
||||
GrPathRenderer* pr = fDrawingManager->getContext()->getPathRenderer(*pipelineBuilder,
|
||||
GrPathRenderer* pr = fDrawingManager->getContext()->getPathRenderer(pipelineBuilder,
|
||||
viewMatrix, *pathPtr,
|
||||
*strokeInfoPtr, false,
|
||||
type);
|
||||
@ -707,7 +707,7 @@ void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder,
|
||||
return;
|
||||
}
|
||||
strokeInfoPtr = &dashlessStrokeInfo;
|
||||
pr = fDrawingManager->getContext()->getPathRenderer(*pipelineBuilder, viewMatrix,
|
||||
pr = fDrawingManager->getContext()->getPathRenderer(pipelineBuilder, viewMatrix,
|
||||
*pathPtr, *strokeInfoPtr,
|
||||
false, type);
|
||||
}
|
||||
@ -732,7 +732,7 @@ void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder,
|
||||
}
|
||||
|
||||
// This time, allow SW renderer
|
||||
pr = fDrawingManager->getContext()->getPathRenderer(*pipelineBuilder, viewMatrix,
|
||||
pr = fDrawingManager->getContext()->getPathRenderer(pipelineBuilder, viewMatrix,
|
||||
*pathPtr, *strokeInfoPtr,
|
||||
true, type);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) {
|
||||
}
|
||||
|
||||
GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrShaderCaps* shaderCaps,
|
||||
const GrPipelineBuilder& pipelineBuilder,
|
||||
const GrPipelineBuilder* pipelineBuilder,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkPath& path,
|
||||
const GrStrokeInfo& stroke,
|
||||
@ -66,15 +66,15 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrShaderCaps* shaderC
|
||||
minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport;
|
||||
}
|
||||
|
||||
GrPathRenderer::CanDrawPathArgs args;
|
||||
args.fShaderCaps = shaderCaps;
|
||||
args.fPipelineBuilder = &pipelineBuilder;
|
||||
args.fViewMatrix = &viewMatrix;
|
||||
args.fPath = &path;
|
||||
args.fStroke = &stroke;
|
||||
args.fAntiAlias = antiAlias;
|
||||
|
||||
for (int i = 0; i < fChain.count(); ++i) {
|
||||
GrPathRenderer::CanDrawPathArgs args;
|
||||
args.fShaderCaps = shaderCaps;
|
||||
args.fPipelineBuilder = pipelineBuilder;
|
||||
args.fViewMatrix = &viewMatrix;
|
||||
args.fPath = &path;
|
||||
args.fStroke = &stroke;
|
||||
args.fAntiAlias = antiAlias;
|
||||
if (fChain[i]->canDrawPath(args)) {
|
||||
if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
|
||||
GrPathRenderer::StencilSupport support =
|
||||
|
Loading…
Reference in New Issue
Block a user