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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 }; | 98 }; |
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. Similarly, we skip the non-hairlines that can be trea
ted 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. We also skip | 109 // An arbitrary path effect could produce a hairline result so we pass on th
ose. |
110 // volatile paths since they are not cacheable. | 110 return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullpt
r) && |
111 return !args.fAntiAlias && !args.fPath->isVolatile() && | |
112 !args.fStyle->strokeRec().isHairlineStyle() && | 111 !args.fStyle->strokeRec().isHairlineStyle() && |
113 !args.fStyle->hasNonDashPathEffect() && | 112 !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias && !args.fPa
th->isConvex(); |
114 !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullpt
r) && | |
115 !args.fPath->isConvex(); | |
116 } | 113 } |
117 | 114 |
118 class TessellatingPathBatch : public GrVertexBatch { | 115 class TessellatingPathBatch : public GrVertexBatch { |
119 public: | 116 public: |
120 DEFINE_BATCH_CLASS_ID | 117 DEFINE_BATCH_CLASS_ID |
121 | 118 |
122 static GrDrawBatch* Create(const GrColor& color, | 119 static GrDrawBatch* Create(const GrColor& color, |
123 const SkPath& path, | 120 const SkPath& path, |
124 const GrStyle& style, | 121 const GrStyle& style, |
125 const SkMatrix& viewMatrix, | 122 const SkMatrix& viewMatrix, |
(...skipping 30 matching lines...) Expand all Loading... |
156 if (fStyle.applies()) { | 153 if (fStyle.applies()) { |
157 styleScale = GrStyle::MatrixToScaleFactor(fViewMatrix); | 154 styleScale = GrStyle::MatrixToScaleFactor(fViewMatrix); |
158 } | 155 } |
159 | 156 |
160 // construct a cache key from the path's genID and the view matrix | 157 // construct a cache key from the path's genID and the view matrix |
161 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain()
; | 158 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain()
; |
162 GrUniqueKey key; | 159 GrUniqueKey key; |
163 int clipBoundsCnt = | 160 int clipBoundsCnt = |
164 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) :
0; | 161 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) :
0; |
165 int styleDataCnt = GrStyle::KeySize(fStyle, GrStyle::Apply::kPathEffectA
ndStrokeRec); | 162 int styleDataCnt = GrStyle::KeySize(fStyle, GrStyle::Apply::kPathEffectA
ndStrokeRec); |
166 // We should have excluded anything we wouldn't know how to cache. | 163 if (styleDataCnt >= 0) { |
167 SkASSERT(styleDataCnt >= 0); | 164 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsCnt + styl
eDataCnt); |
168 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsCnt + styleDat
aCnt); | 165 builder[0] = fPath.getGenerationID(); |
169 builder[0] = fPath.getGenerationID(); | 166 builder[1] = fPath.getFillType(); |
170 builder[1] = fPath.getFillType(); | 167 // For inverse fills, the tessellation is dependent on clip bounds. |
171 // For inverse fills, the tessellation is dependent on clip bounds. | 168 if (fPath.isInverseFillType()) { |
172 if (fPath.isInverseFillType()) { | 169 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); |
173 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); | 170 } |
174 } | 171 if (styleDataCnt) { |
175 if (styleDataCnt) { | 172 GrStyle::WriteKey(&builder[2 + clipBoundsCnt], fStyle, |
176 GrStyle::WriteKey(&builder[2 + clipBoundsCnt], fStyle, | 173 GrStyle::Apply::kPathEffectAndStrokeRec, style
Scale); |
177 GrStyle::Apply::kPathEffectAndStrokeRec, styleScal
e); | 174 } |
178 } | 175 builder.finish(); |
179 builder.finish(); | 176 SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey
<GrBuffer>(key)); |
180 SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrB
uffer>(key)); | 177 int actualCount; |
181 int actualCount; | 178 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) { |
182 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) { | 179 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actu
alCount); |
183 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCo
unt); | 180 return; |
184 return; | 181 } |
185 } | 182 } |
186 | 183 |
187 SkPath path; | 184 SkPath path; |
188 if (fStyle.applies()) { | 185 if (fStyle.applies()) { |
189 SkStrokeRec::InitStyle fill; | 186 SkStrokeRec::InitStyle fill; |
190 SkAssertResult(fStyle.applyToPath(&path, &fill, fPath, styleScale)); | 187 SkAssertResult(fStyle.applyToPath(&path, &fill, fPath, styleScale)); |
191 SkASSERT(SkStrokeRec::kFill_InitStyle == fill); | 188 SkASSERT(SkStrokeRec::kFill_InitStyle == fill); |
192 } else { | 189 } else { |
193 path = fPath; | 190 path = fPath; |
194 } | 191 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 } | 318 } |
322 vmi.mapRect(&clipBounds); | 319 vmi.mapRect(&clipBounds); |
323 GrStyle style; | 320 GrStyle style; |
324 do { | 321 do { |
325 GrTest::TestStyle(random, &style); | 322 GrTest::TestStyle(random, &style); |
326 } while (style.strokeRec().isHairlineStyle()); | 323 } while (style.strokeRec().isHairlineStyle()); |
327 return TessellatingPathBatch::Create(color, path, style, viewMatrix, clipBou
nds); | 324 return TessellatingPathBatch::Create(color, path, style, viewMatrix, clipBou
nds); |
328 } | 325 } |
329 | 326 |
330 #endif | 327 #endif |
OLD | NEW |