From 9ef1bb1375e66d9aac1124e005b500cb6d9caf01 Mon Sep 17 00:00:00 2001 From: egdaniel Date: Mon, 20 Apr 2015 12:28:57 -0700 Subject: [PATCH] Return correctly mapped bounds from GrOvalRenderer. Before we were returning non transformed bounds for the ovals instead of device bounds from the various draw calls. This was causing us to do dst copies from the wrong portion of the screen when there was some transform on the matrix. This fixes the gpu issues from the new imagefilters-xfermodes gm as well an old bug from the srcmode GM. BUG=skia: Review URL: https://codereview.chromium.org/1090453003 --- src/gpu/GrOvalRenderer.cpp | 40 ++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index f33944fa7b..90e5ab0be1 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -692,7 +692,7 @@ public: SkScalar fInnerRadius; SkScalar fOuterRadius; bool fStroke; - SkRect fDevBounds; + SkRect fBounds; }; static GrBatch* Create(const Geometry& geometry) { @@ -775,7 +775,7 @@ public: SkScalar innerRadius = args.fInnerRadius; SkScalar outerRadius = args.fOuterRadius; - const SkRect& bounds = args.fDevBounds; + const SkRect& bounds = args.fBounds; // The inner radius in the vertex data must be specified in normalized space. innerRadius = innerRadius / outerRadius; @@ -930,7 +930,9 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target, geometry.fInnerRadius = innerRadius; geometry.fOuterRadius = outerRadius; geometry.fStroke = isStrokeOnly && innerRadius > 0; - geometry.fDevBounds = bounds; + geometry.fBounds = bounds; + + viewMatrix.mapRect(&bounds); SkAutoTUnref batch(CircleBatch::Create(geometry)); target->drawBatch(pipelineBuilder, batch, &bounds); @@ -948,7 +950,7 @@ public: SkScalar fInnerXRadius; SkScalar fInnerYRadius; bool fStroke; - SkRect fDevBounds; + SkRect fBounds; }; static GrBatch* Create(const Geometry& geometry) { @@ -1036,7 +1038,7 @@ public: SkScalar xInnerRadRecip = SkScalarInvert(args.fInnerXRadius); SkScalar yInnerRadRecip = SkScalarInvert(args.fInnerYRadius); - const SkRect& bounds = args.fDevBounds; + const SkRect& bounds = args.fBounds; // The inner radius in the vertex data must be specified in normalized space. verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); @@ -1227,7 +1229,9 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, geometry.fInnerXRadius = innerXRadius; geometry.fInnerYRadius = innerYRadius; geometry.fStroke = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; - geometry.fDevBounds = bounds; + geometry.fBounds = bounds; + + viewMatrix.mapRect(&bounds); SkAutoTUnref batch(EllipseBatch::Create(geometry)); target->drawBatch(pipelineBuilder, batch, &bounds); @@ -1249,7 +1253,7 @@ public: SkScalar fGeoDx; SkScalar fGeoDy; DIEllipseEdgeEffect::Mode fMode; - SkRect fDevBounds; + SkRect fBounds; }; static GrBatch* Create(const Geometry& geometry) { @@ -1326,7 +1330,7 @@ public: SkScalar xRadius = args.fXRadius; SkScalar yRadius = args.fYRadius; - const SkRect& bounds = args.fDevBounds; + const SkRect& bounds = args.fBounds; // This adjusts the "radius" to include the half-pixel border SkScalar offsetDx = SkScalarDiv(args.fGeoDx, xRadius); @@ -1508,7 +1512,9 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, geometry.fGeoDx = geoDx; geometry.fGeoDy = geoDy; geometry.fMode = mode; - geometry.fDevBounds = bounds; + geometry.fBounds = bounds; + + viewMatrix.mapRect(&bounds); SkAutoTUnref batch(DIEllipseBatch::Create(geometry)); target->drawBatch(pipelineBuilder, batch, &bounds); @@ -1636,7 +1642,7 @@ public: SkScalar fInnerRadius; SkScalar fOuterRadius; bool fStroke; - SkRect fDevBounds; + SkRect fBounds; }; static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexBuffer) { @@ -1719,7 +1725,7 @@ public: SkScalar outerRadius = args.fOuterRadius; - const SkRect& bounds = args.fDevBounds; + const SkRect& bounds = args.fBounds; SkScalar yCoords[4] = { bounds.fTop, @@ -1845,7 +1851,7 @@ public: SkScalar fInnerXRadius; SkScalar fInnerYRadius; bool fStroke; - SkRect fDevBounds; + SkRect fBounds; }; static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexBuffer) { @@ -1936,7 +1942,7 @@ public: SkScalar xOuterRadius = args.fXRadius + SK_ScalarHalf; SkScalar yOuterRadius = args.fYRadius + SK_ScalarHalf; - const SkRect& bounds = args.fDevBounds; + const SkRect& bounds = args.fBounds; SkScalar yCoords[4] = { bounds.fTop, @@ -2168,7 +2174,9 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, geometry.fInnerRadius = innerRadius; geometry.fOuterRadius = outerRadius; geometry.fStroke = isStrokeOnly; - geometry.fDevBounds = bounds; + geometry.fBounds = bounds; + + viewMatrix.mapRect(&bounds); SkAutoTUnref batch(RRectCircleRendererBatch::Create(geometry, indexBuffer)); target->drawBatch(pipelineBuilder, batch, &bounds); @@ -2220,7 +2228,9 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, geometry.fInnerXRadius = innerXRadius; geometry.fInnerYRadius = innerYRadius; geometry.fStroke = isStrokeOnly; - geometry.fDevBounds = bounds; + geometry.fBounds = bounds; + + viewMatrix.mapRect(&bounds); SkAutoTUnref batch(RRectEllipseRendererBatch::Create(geometry, indexBuffer)); target->drawBatch(pipelineBuilder, batch, &bounds);