| Index: src/gpu/GrClipMaskManager.cpp
|
| diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
|
| index 4b57868520d479f9cfb726cbcef98070f6dcdfbb..c2dc4fb2238f01400ec82e03d9cac14e375652b3 100644
|
| --- a/src/gpu/GrClipMaskManager.cpp
|
| +++ b/src/gpu/GrClipMaskManager.cpp
|
| @@ -56,6 +56,7 @@ void setup_drawstate_aaclip(const SkIRect &devBound,
|
| bool path_needs_SW_renderer(GrContext* context,
|
| const GrDrawTarget* gpu,
|
| const GrDrawState* drawState,
|
| + const SkMatrix& viewMatrix,
|
| const SkPath& origPath,
|
| const SkStrokeRec& stroke,
|
| bool doAA) {
|
| @@ -69,7 +70,7 @@ bool path_needs_SW_renderer(GrContext* context,
|
| GrPathRendererChain::kColorAntiAlias_DrawType :
|
| GrPathRendererChain::kColor_DrawType;
|
|
|
| - return NULL == context->getPathRenderer(gpu, drawState, *path, stroke, false, type);
|
| + return NULL == context->getPathRenderer(gpu, drawState, viewMatrix, *path, stroke, false, type);
|
| }
|
| }
|
|
|
| @@ -79,12 +80,18 @@ bool path_needs_SW_renderer(GrContext* context,
|
| * entire clip should be rendered in SW and then uploaded en masse to the gpu.
|
| */
|
| bool GrClipMaskManager::useSWOnlyPath(const GrDrawState* drawState,
|
| + const SkVector& clipToMaskOffset,
|
| const GrReducedClip::ElementList& elements) {
|
| // 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.
|
| SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
|
|
|
| + // Set the matrix so that rendered clip elements are transformed to mask space from clip
|
| + // space.
|
| + SkMatrix translate;
|
| + translate.setTranslate(clipToMaskOffset);
|
| +
|
| for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
|
| const Element* element = iter.get();
|
| // rects can always be drawn directly w/o using the software path
|
| @@ -92,8 +99,8 @@ bool GrClipMaskManager::useSWOnlyPath(const GrDrawState* drawState,
|
| if (Element::kRect_Type != element->getType()) {
|
| SkPath path;
|
| element->asPath(&path);
|
| - if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawState, path, stroke,
|
| - element->isAA())) {
|
| + if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawState, translate,
|
| + path, stroke, element->isAA())) {
|
| return true;
|
| }
|
| }
|
| @@ -273,17 +280,25 @@ bool GrClipMaskManager::setupClipping(GrDrawState* drawState,
|
| if (0 == rt->numSamples() && requiresAA) {
|
| GrTexture* result = NULL;
|
|
|
| - if (this->useSWOnlyPath(drawState, elements)) {
|
| + // The top-left of the mask corresponds to the top-left corner of the bounds.
|
| + SkVector clipToMaskOffset = {
|
| + SkIntToScalar(-clipSpaceIBounds.fLeft),
|
| + SkIntToScalar(-clipSpaceIBounds.fTop)
|
| + };
|
| +
|
| + if (this->useSWOnlyPath(drawState, clipToMaskOffset, elements)) {
|
| // The clip geometry is complex enough that it will be more efficient to create it
|
| // entirely in software
|
| result = this->createSoftwareClipMask(genID,
|
| initialState,
|
| elements,
|
| + clipToMaskOffset,
|
| clipSpaceIBounds);
|
| } else {
|
| result = this->createAlphaClipMask(genID,
|
| initialState,
|
| elements,
|
| + clipToMaskOffset,
|
| clipSpaceIBounds);
|
| }
|
|
|
| @@ -337,6 +352,7 @@ void set_coverage_drawing_xpf(SkRegion::Op op, bool invertCoverage, GrDrawState*
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| bool GrClipMaskManager::drawElement(GrDrawState* drawState,
|
| + const SkMatrix& viewMatrix,
|
| GrTexture* target,
|
| const SkClipStack::Element* element,
|
| GrPathRenderer* pr) {
|
| @@ -357,15 +373,16 @@ bool GrClipMaskManager::drawElement(GrDrawState* drawState,
|
| // TODO: Do rects directly to the accumulator using a aa-rect GrProcessor that covers
|
| // the entire mask bounds and writes 0 outside the rect.
|
| if (element->isAA()) {
|
| + SkRect devRect = element->getRect();
|
| + viewMatrix.mapRect(&devRect);
|
| this->getContext()->getAARectRenderer()->fillAARect(fClipTarget,
|
| drawState,
|
| color,
|
| - SkMatrix::I(),
|
| + viewMatrix,
|
| element->getRect(),
|
| - SkMatrix::I(),
|
| - element->getRect());
|
| + devRect);
|
| } else {
|
| - fClipTarget->drawSimpleRect(drawState, color, element->getRect());
|
| + fClipTarget->drawSimpleRect(drawState, color, viewMatrix, element->getRect());
|
| }
|
| return true;
|
| default: {
|
| @@ -380,14 +397,14 @@ bool GrClipMaskManager::drawElement(GrDrawState* drawState,
|
| GrPathRendererChain::DrawType type;
|
| type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType :
|
| GrPathRendererChain::kColor_DrawType;
|
| - pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke,
|
| - false, type);
|
| + pr = this->getContext()->getPathRenderer(fClipTarget, drawState, viewMatrix, path,
|
| + stroke, false, type);
|
| }
|
| if (NULL == pr) {
|
| return false;
|
| }
|
|
|
| - pr->drawPath(fClipTarget, drawState, color, path, stroke, element->isAA());
|
| + pr->drawPath(fClipTarget, drawState, color, viewMatrix, path, stroke, element->isAA());
|
| break;
|
| }
|
| }
|
| @@ -414,8 +431,8 @@ bool GrClipMaskManager::canStencilAndDrawElement(GrDrawState* drawState,
|
| GrPathRendererChain::DrawType type = element->isAA() ?
|
| GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
|
| GrPathRendererChain::kStencilAndColor_DrawType;
|
| - *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke, false,
|
| - type);
|
| + *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, SkMatrix::I(), path,
|
| + stroke, false, type);
|
| return SkToBool(*pr);
|
| }
|
| }
|
| @@ -441,7 +458,7 @@ void GrClipMaskManager::mergeMask(GrDrawState* drawState,
|
| GrTextureDomain::kDecal_Mode,
|
| GrTextureParams::kNone_FilterMode))->unref();
|
| // The color passed in here does not matter since the coverageSetOpXP won't read it.
|
| - fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound));
|
| + fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkMatrix::I(), SkRect::Make(dstBound));
|
| }
|
|
|
| GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
|
| @@ -499,6 +516,7 @@ GrTexture* GrClipMaskManager::allocMaskTexture(int32_t elementsGenID,
|
| GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| GrReducedClip::InitialState initialState,
|
| const GrReducedClip::ElementList& elements,
|
| + const SkVector& clipToMaskOffset,
|
| const SkIRect& clipSpaceIBounds) {
|
| SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
|
|
|
| @@ -516,19 +534,15 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| return NULL;
|
| }
|
|
|
| - // The top-left of the mask corresponds to the top-left corner of the bounds.
|
| - SkVector clipToMaskOffset = {
|
| - SkIntToScalar(-clipSpaceIBounds.fLeft),
|
| - SkIntToScalar(-clipSpaceIBounds.fTop)
|
| - };
|
| + // Set the matrix so that rendered clip elements are transformed to mask space from clip
|
| + // space.
|
| + 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.
|
| SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpaceIBounds.height());
|
|
|
| - // Set the matrix so that rendered clip elements are transformed to mask space from clip space.
|
| - SkMatrix translate;
|
| - translate.setTranslate(clipToMaskOffset);
|
| -
|
| // The scratch texture that we are drawing into can be substantially larger than the mask. Only
|
| // clear the part that we care about.
|
| fClipTarget->clear(&maskSpaceIBounds,
|
| @@ -549,7 +563,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| SkRegion::Op op = element->getOp();
|
| bool invert = element->isInverseFilled();
|
| if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) {
|
| - GrDrawState drawState(translate);
|
| + GrDrawState drawState;
|
| drawState.enableState(GrDrawState::kClip_StateBit);
|
|
|
| GrPathRenderer* pr = NULL;
|
| @@ -600,7 +614,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| set_coverage_drawing_xpf(op, invert, &drawState);
|
| }
|
|
|
| - if (!this->drawElement(&drawState, dst, element, pr)) {
|
| + if (!this->drawElement(&drawState, translate, dst, element, pr)) {
|
| fAACache.reset();
|
| return NULL;
|
| }
|
| @@ -619,7 +633,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| maskSpaceIBounds,
|
| maskSpaceElementIBounds);
|
| } else {
|
| - GrDrawState backgroundDrawState(translate);
|
| + GrDrawState backgroundDrawState;
|
| backgroundDrawState.enableState(GrDrawState::kClip_StateBit);
|
| backgroundDrawState.setRenderTarget(result->asRenderTarget());
|
|
|
| @@ -634,16 +648,17 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| 0xffff);
|
| backgroundDrawState.setStencil(kDrawOutsideElement);
|
| // The color passed in here does not matter since the coverageSetOpXP won't read it.
|
| - fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, clipSpaceIBounds);
|
| + fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, translate,
|
| + clipSpaceIBounds);
|
| }
|
| } else {
|
| - GrDrawState drawState(translate);
|
| + GrDrawState drawState;
|
| drawState.enableState(GrDrawState::kClip_StateBit);
|
|
|
| // all the remaining ops can just be directly draw into the accumulation buffer
|
| set_coverage_drawing_xpf(op, false, &drawState);
|
| // The color passed in here does not matter since the coverageSetOpXP won't read it.
|
| - this->drawElement(&drawState, result, element);
|
| + this->drawElement(&drawState, translate, result, element);
|
| }
|
| }
|
|
|
| @@ -676,8 +691,8 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
| SkIntToScalar(clipSpaceToStencilOffset.fX),
|
| SkIntToScalar(clipSpaceToStencilOffset.fY)
|
| };
|
| - SkMatrix matrix;
|
| - matrix.setTranslate(translate);
|
| + SkMatrix viewMatrix;
|
| + viewMatrix.setTranslate(translate);
|
|
|
| // We set the current clip to the bounds so that our recursive draws are scissored to them.
|
| SkIRect stencilSpaceIBounds(clipSpaceIBounds);
|
| @@ -697,7 +712,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
| for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
|
| const Element* element = iter.get();
|
|
|
| - GrDrawState drawState(matrix);
|
| + GrDrawState drawState;
|
| drawState.setRenderTarget(rt);
|
| drawState.enableState(GrDrawState::kClip_StateBit);
|
|
|
| @@ -732,6 +747,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
| }
|
| pr = this->getContext()->getPathRenderer(fClipTarget,
|
| &drawState,
|
| + viewMatrix,
|
| clipPath,
|
| stroke,
|
| false,
|
| @@ -769,16 +785,17 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
| 0xffff);
|
| if (Element::kRect_Type == element->getType()) {
|
| *drawState.stencil() = gDrawToStencil;
|
| - fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, element->getRect());
|
| + fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, viewMatrix,
|
| + element->getRect());
|
| } else {
|
| if (!clipPath.isEmpty()) {
|
| GrDrawTarget::AutoGeometryPush agp(fClipTarget);
|
| if (canRenderDirectToStencil) {
|
| *drawState.stencil() = gDrawToStencil;
|
| - pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, clipPath, stroke,
|
| - false);
|
| + pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, viewMatrix,
|
| + clipPath, stroke, false);
|
| } else {
|
| - pr->stencilPath(fClipTarget, &drawState, clipPath, stroke);
|
| + pr->stencilPath(fClipTarget, &drawState, viewMatrix, clipPath, stroke);
|
| }
|
| }
|
| }
|
| @@ -793,16 +810,17 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
|
|
| if (canDrawDirectToClip) {
|
| if (Element::kRect_Type == element->getType()) {
|
| - fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE,
|
| + fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, viewMatrix,
|
| element->getRect());
|
| } else {
|
| GrDrawTarget::AutoGeometryPush agp(fClipTarget);
|
| - pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, clipPath, stroke, false);
|
| + pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, viewMatrix,
|
| + clipPath, stroke, false);
|
| }
|
| } else {
|
| // The view matrix is setup to do clip space -> stencil space translation, so
|
| // draw rect in clip space.
|
| - fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE,
|
| + fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, viewMatrix,
|
| SkRect::Make(clipSpaceIBounds));
|
| }
|
| }
|
| @@ -989,6 +1007,7 @@ void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,
|
| GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
|
| GrReducedClip::InitialState initialState,
|
| const GrReducedClip::ElementList& elements,
|
| + const SkVector& clipToMaskOffset,
|
| const SkIRect& clipSpaceIBounds) {
|
| SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
|
|
|
| @@ -1003,11 +1022,12 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
|
|
|
| GrSWMaskHelper helper(this->getContext());
|
|
|
| - SkMatrix matrix;
|
| - matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft),
|
| - SkIntToScalar(-clipSpaceIBounds.fTop));
|
| + // Set the matrix so that rendered clip elements are transformed to mask space from clip
|
| + // space.
|
| + SkMatrix translate;
|
| + translate.setTranslate(clipToMaskOffset);
|
|
|
| - helper.init(maskSpaceIBounds, &matrix, false);
|
| + helper.init(maskSpaceIBounds, &translate, false);
|
| helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x00);
|
| SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
|
|
|
|
|