| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrSoftwarePathRenderer.h" | 8 #include "GrSoftwarePathRenderer.h" |
| 9 #include "GrContext.h" | 9 #include "GrContext.h" |
| 10 #include "GrSWMaskHelper.h" | 10 #include "GrSWMaskHelper.h" |
| 11 #include "batches/GrRectBatchFactory.h" | 11 #include "batches/GrRectBatchFactory.h" |
| 12 | 12 |
| 13 //////////////////////////////////////////////////////////////////////////////// | 13 //////////////////////////////////////////////////////////////////////////////// |
| 14 bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { | 14 bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { |
| 15 return SkToBool(fContext); | 15 return SkToBool(fContext); |
| 16 } | 16 } |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 //////////////////////////////////////////////////////////////////////////////// | 20 //////////////////////////////////////////////////////////////////////////////// |
| 21 // gets device coord bounds of path (not considering the fill) and clip. The | 21 // gets device coord bounds of path (not considering the fill) and clip. The |
| 22 // path bounds will be a subset of the clip bounds. returns false if | 22 // path bounds will be a subset of the clip bounds. returns false if |
| 23 // path bounds would be empty. | 23 // path bounds would be empty. |
| 24 bool get_path_and_clip_bounds(const GrPipelineBuilder* pipelineBuilder, | 24 bool get_path_and_clip_bounds(const GrPipelineBuilder* pipelineBuilder, |
| 25 const GrClip& clip, |
| 25 const SkPath& path, | 26 const SkPath& path, |
| 26 const SkMatrix& matrix, | 27 const SkMatrix& matrix, |
| 27 SkIRect* devPathBounds, | 28 SkIRect* devPathBounds, |
| 28 SkIRect* devClipBounds) { | 29 SkIRect* devClipBounds) { |
| 29 // compute bounds as intersection of rt size, clip, and path | 30 // compute bounds as intersection of rt size, clip, and path |
| 30 const GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); | 31 const GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); |
| 31 if (nullptr == rt) { | 32 if (nullptr == rt) { |
| 32 return false; | 33 return false; |
| 33 } | 34 } |
| 34 | 35 |
| 35 pipelineBuilder->clip().getConservativeBounds(rt->width(), rt->height(), dev
ClipBounds); | 36 clip.getConservativeBounds(rt->width(), rt->height(), devClipBounds); |
| 36 | 37 |
| 37 if (devClipBounds->isEmpty()) { | 38 if (devClipBounds->isEmpty()) { |
| 38 *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height()); | 39 *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height()); |
| 39 return false; | 40 return false; |
| 40 } | 41 } |
| 41 | 42 |
| 42 if (!path.getBounds().isEmpty()) { | 43 if (!path.getBounds().isEmpty()) { |
| 43 SkRect pathSBounds; | 44 SkRect pathSBounds; |
| 44 matrix.mapRect(&pathSBounds, path.getBounds()); | 45 matrix.mapRect(&pathSBounds, path.getBounds()); |
| 45 SkIRect pathIBounds; | 46 SkIRect pathIBounds; |
| 46 pathSBounds.roundOut(&pathIBounds); | 47 pathSBounds.roundOut(&pathIBounds); |
| 47 *devPathBounds = *devClipBounds; | 48 *devPathBounds = *devClipBounds; |
| 48 if (!devPathBounds->intersect(pathIBounds)) { | 49 if (!devPathBounds->intersect(pathIBounds)) { |
| 49 // set the correct path bounds, as this would be used later. | 50 // set the correct path bounds, as this would be used later. |
| 50 *devPathBounds = pathIBounds; | 51 *devPathBounds = pathIBounds; |
| 51 return false; | 52 return false; |
| 52 } | 53 } |
| 53 } else { | 54 } else { |
| 54 *devPathBounds = SkIRect::EmptyIRect(); | 55 *devPathBounds = SkIRect::EmptyIRect(); |
| 55 return false; | 56 return false; |
| 56 } | 57 } |
| 57 return true; | 58 return true; |
| 58 } | 59 } |
| 59 | 60 |
| 60 //////////////////////////////////////////////////////////////////////////////// | 61 //////////////////////////////////////////////////////////////////////////////// |
| 61 static void draw_non_aa_rect(GrDrawTarget* drawTarget, | 62 static void draw_non_aa_rect(GrDrawTarget* drawTarget, |
| 62 const GrPipelineBuilder& pipelineBuilder, | 63 const GrPipelineBuilder& pipelineBuilder, |
| 64 const GrClip& clip, |
| 63 GrColor color, | 65 GrColor color, |
| 64 const SkMatrix& viewMatrix, | 66 const SkMatrix& viewMatrix, |
| 65 const SkRect& rect, | 67 const SkRect& rect, |
| 66 const SkMatrix& localMatrix) { | 68 const SkMatrix& localMatrix) { |
| 67 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, v
iewMatrix, rect, | 69 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, v
iewMatrix, rect, |
| 68 nullptr,
&localMatrix)); | 70 nullptr,
&localMatrix)); |
| 69 drawTarget->drawBatch(pipelineBuilder, batch); | 71 drawTarget->drawBatch(pipelineBuilder, clip, batch); |
| 70 } | 72 } |
| 71 | 73 |
| 72 void draw_around_inv_path(GrDrawTarget* target, | 74 void draw_around_inv_path(GrDrawTarget* target, |
| 73 GrPipelineBuilder* pipelineBuilder, | 75 GrPipelineBuilder* pipelineBuilder, |
| 76 const GrClip& clip, |
| 74 GrColor color, | 77 GrColor color, |
| 75 const SkMatrix& viewMatrix, | 78 const SkMatrix& viewMatrix, |
| 76 const SkIRect& devClipBounds, | 79 const SkIRect& devClipBounds, |
| 77 const SkIRect& devPathBounds) { | 80 const SkIRect& devPathBounds) { |
| 78 SkMatrix invert; | 81 SkMatrix invert; |
| 79 if (!viewMatrix.invert(&invert)) { | 82 if (!viewMatrix.invert(&invert)) { |
| 80 return; | 83 return; |
| 81 } | 84 } |
| 82 | 85 |
| 83 SkRect rect; | 86 SkRect rect; |
| 84 if (devClipBounds.fTop < devPathBounds.fTop) { | 87 if (devClipBounds.fTop < devPathBounds.fTop) { |
| 85 rect.iset(devClipBounds.fLeft, devClipBounds.fTop, | 88 rect.iset(devClipBounds.fLeft, devClipBounds.fTop, |
| 86 devClipBounds.fRight, devPathBounds.fTop); | 89 devClipBounds.fRight, devPathBounds.fTop); |
| 87 draw_non_aa_rect(target, *pipelineBuilder, color, SkMatrix::I(), rect, i
nvert); | 90 draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), r
ect, invert); |
| 88 } | 91 } |
| 89 if (devClipBounds.fLeft < devPathBounds.fLeft) { | 92 if (devClipBounds.fLeft < devPathBounds.fLeft) { |
| 90 rect.iset(devClipBounds.fLeft, devPathBounds.fTop, | 93 rect.iset(devClipBounds.fLeft, devPathBounds.fTop, |
| 91 devPathBounds.fLeft, devPathBounds.fBottom); | 94 devPathBounds.fLeft, devPathBounds.fBottom); |
| 92 draw_non_aa_rect(target, *pipelineBuilder, color, SkMatrix::I(), rect, i
nvert); | 95 draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), r
ect, invert); |
| 93 } | 96 } |
| 94 if (devClipBounds.fRight > devPathBounds.fRight) { | 97 if (devClipBounds.fRight > devPathBounds.fRight) { |
| 95 rect.iset(devPathBounds.fRight, devPathBounds.fTop, | 98 rect.iset(devPathBounds.fRight, devPathBounds.fTop, |
| 96 devClipBounds.fRight, devPathBounds.fBottom); | 99 devClipBounds.fRight, devPathBounds.fBottom); |
| 97 draw_non_aa_rect(target, *pipelineBuilder, color, SkMatrix::I(), rect, i
nvert); | 100 draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), r
ect, invert); |
| 98 } | 101 } |
| 99 if (devClipBounds.fBottom > devPathBounds.fBottom) { | 102 if (devClipBounds.fBottom > devPathBounds.fBottom) { |
| 100 rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, | 103 rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, |
| 101 devClipBounds.fRight, devClipBounds.fBottom); | 104 devClipBounds.fRight, devClipBounds.fBottom); |
| 102 draw_non_aa_rect(target, *pipelineBuilder, color, SkMatrix::I(), rect, i
nvert); | 105 draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), r
ect, invert); |
| 103 } | 106 } |
| 104 } | 107 } |
| 105 | 108 |
| 106 } | 109 } |
| 107 | 110 |
| 108 //////////////////////////////////////////////////////////////////////////////// | 111 //////////////////////////////////////////////////////////////////////////////// |
| 109 // return true on success; false on failure | 112 // return true on success; false on failure |
| 110 bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) { | 113 bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) { |
| 111 GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrSoftwarePathRend
erer::onDrawPath"); | 114 GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrSoftwarePathRend
erer::onDrawPath"); |
| 112 if (nullptr == fContext) { | 115 if (nullptr == fContext) { |
| 113 return false; | 116 return false; |
| 114 } | 117 } |
| 115 | 118 |
| 116 SkIRect devPathBounds, devClipBounds; | 119 SkIRect devPathBounds, devClipBounds; |
| 117 if (!get_path_and_clip_bounds(args.fPipelineBuilder, *args.fPath, | 120 if (!get_path_and_clip_bounds(args.fPipelineBuilder, *args.fClip, *args.fPat
h, |
| 118 *args.fViewMatrix, &devPathBounds, &devClipBou
nds)) { | 121 *args.fViewMatrix, &devPathBounds, &devClipBou
nds)) { |
| 119 if (args.fPath->isInverseFillType()) { | 122 if (args.fPath->isInverseFillType()) { |
| 120 draw_around_inv_path(args.fTarget, args.fPipelineBuilder, args.fColo
r, | 123 draw_around_inv_path(args.fTarget, args.fPipelineBuilder, *args.fCli
p, args.fColor, |
| 121 *args.fViewMatrix, devClipBounds, devPathBounds
); | 124 *args.fViewMatrix, devClipBounds, devPathBounds
); |
| 122 } | 125 } |
| 123 return true; | 126 return true; |
| 124 } | 127 } |
| 125 | 128 |
| 126 SkAutoTUnref<GrTexture> texture( | 129 SkAutoTUnref<GrTexture> texture( |
| 127 GrSWMaskHelper::DrawPathMaskToTexture(fContext, *args.fPath, *args.f
Style, | 130 GrSWMaskHelper::DrawPathMaskToTexture(fContext, *args.fPath, *args.f
Style, |
| 128 devPathBounds, | 131 devPathBounds, |
| 129 args.fAntiAlias, args.fViewMat
rix)); | 132 args.fAntiAlias, args.fViewMat
rix)); |
| 130 if (nullptr == texture) { | 133 if (nullptr == texture) { |
| 131 return false; | 134 return false; |
| 132 } | 135 } |
| 133 | 136 |
| 134 GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fTarget, args.fPipeli
neBuilder, | 137 GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fTarget, args.fPipeli
neBuilder, |
| 135 args.fColor, *args.fViewMatrix, dev
PathBounds); | 138 *args.fClip, args.fColor, *args.fVi
ewMatrix, |
| 139 devPathBounds); |
| 136 | 140 |
| 137 if (args.fPath->isInverseFillType()) { | 141 if (args.fPath->isInverseFillType()) { |
| 138 draw_around_inv_path(args.fTarget, args.fPipelineBuilder, args.fColor, *
args.fViewMatrix, | 142 draw_around_inv_path(args.fTarget, args.fPipelineBuilder, *args.fClip, a
rgs.fColor, |
| 139 devClipBounds, devPathBounds); | 143 *args.fViewMatrix, devClipBounds, devPathBounds); |
| 140 } | 144 } |
| 141 | 145 |
| 142 return true; | 146 return true; |
| 143 } | 147 } |
| OLD | NEW |