| 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);
 | 
|  
 | 
| 
 |