OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrTessellatingPathRenderer.h" | 8 #include "GrTessellatingPathRenderer.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 | 99 |
100 } // namespace | 100 } // namespace |
101 | 101 |
102 GrTessellatingPathRenderer::GrTessellatingPathRenderer() { | 102 GrTessellatingPathRenderer::GrTessellatingPathRenderer() { |
103 } | 103 } |
104 | 104 |
105 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t { | 105 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t { |
106 // This path renderer can draw all fill styles, all stroke styles except hai rlines, but does | 106 // This path renderer can draw all fill styles, all stroke styles except hai rlines, but does |
107 // not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to | 107 // not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to |
108 // simpler algorithms. Similary, we skip the non-hairlines that can be treat ed as hairline. | 108 // simpler algorithms. Similary, we skip the non-hairlines that can be treat ed as hairline. |
109 // An arbitrary path effect could produce a hairline result so we pass on th ose. | 109 // An arbitrary path effect could produce a hairline result so we pass on th ose. We also skip |
110 // volatile paths since they are not cacheable. | |
110 return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullpt r) && | 111 return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullpt r) && |
111 !args.fStyle->strokeRec().isHairlineStyle() && | 112 !args.fStyle->strokeRec().isHairlineStyle() && |
112 !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias && !args.fPa th->isConvex(); | 113 !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias && !args.fPa th->isConvex() && |
114 !args.fPath->isVolatile(); | |
Stephen White
2016/05/18 13:45:49
Could you put this ahead of the other tests? (Vari
bsalomon
2016/05/18 13:53:43
Because it is a fast check, right? I reordered the
| |
113 } | 115 } |
114 | 116 |
115 class TessellatingPathBatch : public GrVertexBatch { | 117 class TessellatingPathBatch : public GrVertexBatch { |
116 public: | 118 public: |
117 DEFINE_BATCH_CLASS_ID | 119 DEFINE_BATCH_CLASS_ID |
118 | 120 |
119 static GrDrawBatch* Create(const GrColor& color, | 121 static GrDrawBatch* Create(const GrColor& color, |
120 const SkPath& path, | 122 const SkPath& path, |
121 const GrStyle& style, | 123 const GrStyle& style, |
122 const SkMatrix& viewMatrix, | 124 const SkMatrix& viewMatrix, |
(...skipping 30 matching lines...) Expand all Loading... | |
153 if (fStyle.applies()) { | 155 if (fStyle.applies()) { |
154 styleScale = GrStyle::MatrixToScaleFactor(fViewMatrix); | 156 styleScale = GrStyle::MatrixToScaleFactor(fViewMatrix); |
155 } | 157 } |
156 | 158 |
157 // construct a cache key from the path's genID and the view matrix | 159 // construct a cache key from the path's genID and the view matrix |
158 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; | 160 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; |
159 GrUniqueKey key; | 161 GrUniqueKey key; |
160 int clipBoundsCnt = | 162 int clipBoundsCnt = |
161 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0; | 163 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0; |
162 int styleDataCnt = GrStyle::KeySize(fStyle, GrStyle::Apply::kPathEffectA ndStrokeRec); | 164 int styleDataCnt = GrStyle::KeySize(fStyle, GrStyle::Apply::kPathEffectA ndStrokeRec); |
163 if (styleDataCnt >= 0) { | 165 // We should have excluded anything we wouldn't know how to cache. |
164 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsCnt + styl eDataCnt); | 166 SkASSERT(styleDataCnt >= 0); |
165 builder[0] = fPath.getGenerationID(); | 167 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsCnt + styleDat aCnt); |
166 builder[1] = fPath.getFillType(); | 168 builder[0] = fPath.getGenerationID(); |
167 // For inverse fills, the tessellation is dependent on clip bounds. | 169 builder[1] = fPath.getFillType(); |
168 if (fPath.isInverseFillType()) { | 170 // For inverse fills, the tessellation is dependent on clip bounds. |
169 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); | 171 if (fPath.isInverseFillType()) { |
170 } | 172 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); |
171 if (styleDataCnt) { | 173 } |
172 GrStyle::WriteKey(&builder[2 + clipBoundsCnt], fStyle, | 174 if (styleDataCnt) { |
173 GrStyle::Apply::kPathEffectAndStrokeRec, style Scale); | 175 GrStyle::WriteKey(&builder[2 + clipBoundsCnt], fStyle, |
174 } | 176 GrStyle::Apply::kPathEffectAndStrokeRec, styleScal e); |
175 builder.finish(); | 177 } |
176 SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey <GrBuffer>(key)); | 178 builder.finish(); |
177 int actualCount; | 179 SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrB uffer>(key)); |
178 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) { | 180 int actualCount; |
179 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actu alCount); | 181 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) { |
180 return; | 182 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCo unt); |
181 } | 183 return; |
182 } | 184 } |
183 | 185 |
184 SkPath path; | 186 SkPath path; |
185 if (fStyle.applies()) { | 187 if (fStyle.applies()) { |
186 SkStrokeRec::InitStyle fill; | 188 SkStrokeRec::InitStyle fill; |
187 SkAssertResult(fStyle.applyToPath(&path, &fill, fPath, styleScale)); | 189 SkAssertResult(fStyle.applyToPath(&path, &fill, fPath, styleScale)); |
188 SkASSERT(SkStrokeRec::kFill_InitStyle == fill); | 190 SkASSERT(SkStrokeRec::kFill_InitStyle == fill); |
189 } else { | 191 } else { |
190 path = fPath; | 192 path = fPath; |
191 } | 193 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 } | 320 } |
319 vmi.mapRect(&clipBounds); | 321 vmi.mapRect(&clipBounds); |
320 GrStyle style; | 322 GrStyle style; |
321 do { | 323 do { |
322 GrTest::TestStyle(random, &style); | 324 GrTest::TestStyle(random, &style); |
323 } while (style.strokeRec().isHairlineStyle()); | 325 } while (style.strokeRec().isHairlineStyle()); |
324 return TessellatingPathBatch::Create(color, path, style, viewMatrix, clipBou nds); | 326 return TessellatingPathBatch::Create(color, path, style, viewMatrix, clipBou nds); |
325 } | 327 } |
326 | 328 |
327 #endif | 329 #endif |
OLD | NEW |