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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 const TessInfo* info = static_cast<const TessInfo*>(data->data()); | 54 const TessInfo* info = static_cast<const TessInfo*>(data->data()); |
55 if (info->fTolerance == 0 || info->fTolerance < 3.0f * tol) { | 55 if (info->fTolerance == 0 || info->fTolerance < 3.0f * tol) { |
56 *actualCount = info->fCount; | 56 *actualCount = info->fCount; |
57 return true; | 57 return true; |
58 } | 58 } |
59 return false; | 59 return false; |
60 } | 60 } |
61 | 61 |
62 class StaticVertexAllocator : public GrTessellator::VertexAllocator { | 62 class StaticVertexAllocator : public GrTessellator::VertexAllocator { |
63 public: | 63 public: |
64 StaticVertexAllocator(SkAutoTUnref<GrVertexBuffer>& vertexBuffer, | 64 StaticVertexAllocator(GrResourceProvider* resourceProvider, bool canMapVB) |
65 GrResourceProvider* resourceProvider, | 65 : fResourceProvider(resourceProvider) |
66 bool canMapVB) | |
67 : fVertexBuffer(vertexBuffer) | |
68 , fResourceProvider(resourceProvider) | |
69 , fCanMapVB(canMapVB) | 66 , fCanMapVB(canMapVB) |
70 , fVertices(nullptr) { | 67 , fVertices(nullptr) { |
71 } | 68 } |
72 SkPoint* lock(int vertexCount) override { | 69 SkPoint* lock(int vertexCount) override { |
73 size_t size = vertexCount * sizeof(SkPoint); | 70 size_t size = vertexCount * sizeof(SkPoint); |
74 if (!fVertexBuffer.get() || fVertexBuffer->gpuMemorySize() < size) { | 71 fVertexBuffer.reset(fResourceProvider->createVertexBuffer( |
75 fVertexBuffer.reset(fResourceProvider->createVertexBuffer( | 72 size, GrResourceProvider::kStatic_BufferUsage, 0)); |
76 size, GrResourceProvider::kStatic_BufferUsage, 0)); | |
77 } | |
78 if (!fVertexBuffer.get()) { | 73 if (!fVertexBuffer.get()) { |
79 return nullptr; | 74 return nullptr; |
80 } | 75 } |
81 if (fCanMapVB) { | 76 if (fCanMapVB) { |
82 fVertices = static_cast<SkPoint*>(fVertexBuffer->map()); | 77 fVertices = static_cast<SkPoint*>(fVertexBuffer->map()); |
83 } else { | 78 } else { |
84 fVertices = new SkPoint[vertexCount]; | 79 fVertices = new SkPoint[vertexCount]; |
85 } | 80 } |
86 return fVertices; | 81 return fVertices; |
87 } | 82 } |
88 void unlock(int actualCount) override { | 83 void unlock(int actualCount) override { |
89 if (fCanMapVB) { | 84 if (fCanMapVB) { |
90 fVertexBuffer->unmap(); | 85 fVertexBuffer->unmap(); |
91 } else { | 86 } else { |
92 fVertexBuffer->updateData(fVertices, actualCount * sizeof(SkPoint)); | 87 fVertexBuffer->updateData(fVertices, actualCount * sizeof(SkPoint)); |
93 delete[] fVertices; | 88 delete[] fVertices; |
94 } | 89 } |
95 fVertices = nullptr; | 90 fVertices = nullptr; |
96 } | 91 } |
| 92 GrVertexBuffer* vertexBuffer() { return fVertexBuffer.get(); } |
97 private: | 93 private: |
98 SkAutoTUnref<GrVertexBuffer>& fVertexBuffer; | 94 SkAutoTUnref<GrVertexBuffer> fVertexBuffer; |
99 GrResourceProvider* fResourceProvider; | 95 GrResourceProvider* fResourceProvider; |
100 bool fCanMapVB; | 96 bool fCanMapVB; |
101 SkPoint* fVertices; | 97 SkPoint* fVertices; |
102 }; | 98 }; |
103 | 99 |
104 } // namespace | 100 } // namespace |
105 | 101 |
106 GrTessellatingPathRenderer::GrTessellatingPathRenderer() { | 102 GrTessellatingPathRenderer::GrTessellatingPathRenderer() { |
107 } | 103 } |
108 | 104 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32 + strok
eDataSize32); | 151 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32 + strok
eDataSize32); |
156 builder[0] = fPath.getGenerationID(); | 152 builder[0] = fPath.getGenerationID(); |
157 builder[1] = fPath.getFillType(); | 153 builder[1] = fPath.getFillType(); |
158 // For inverse fills, the tessellation is dependent on clip bounds. | 154 // For inverse fills, the tessellation is dependent on clip bounds. |
159 if (fPath.isInverseFillType()) { | 155 if (fPath.isInverseFillType()) { |
160 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); | 156 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); |
161 } | 157 } |
162 fStroke.asUniqueKeyFragment(&builder[2 + clipBoundsSize32]); | 158 fStroke.asUniqueKeyFragment(&builder[2 + clipBoundsSize32]); |
163 builder.finish(); | 159 builder.finish(); |
164 GrResourceProvider* rp = target->resourceProvider(); | 160 GrResourceProvider* rp = target->resourceProvider(); |
165 SkAutoTUnref<GrVertexBuffer> vertexBuffer(rp->findAndRefTByUniqueKey<GrV
ertexBuffer>(key)); | 161 SkAutoTUnref<GrVertexBuffer> cachedVertexBuffer( |
| 162 rp->findAndRefTByUniqueKey<GrVertexBuffer>(key)); |
166 int actualCount; | 163 int actualCount; |
167 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; | 164 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; |
168 SkScalar tol = GrPathUtils::scaleToleranceToSrc( | 165 SkScalar tol = GrPathUtils::scaleToleranceToSrc( |
169 screenSpaceTol, fViewMatrix, fPath.getBounds()); | 166 screenSpaceTol, fViewMatrix, fPath.getBounds()); |
170 if (cache_match(vertexBuffer.get(), tol, &actualCount)) { | 167 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) { |
171 this->drawVertices(target, gp, vertexBuffer.get(), 0, actualCount); | 168 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCo
unt); |
172 return; | 169 return; |
173 } | 170 } |
174 | 171 |
175 SkPath path; | 172 SkPath path; |
176 GrStrokeInfo stroke(fStroke); | 173 GrStrokeInfo stroke(fStroke); |
177 if (stroke.isDashed()) { | 174 if (stroke.isDashed()) { |
178 if (!stroke.applyDashToPath(&path, &stroke, fPath)) { | 175 if (!stroke.applyDashToPath(&path, &stroke, fPath)) { |
179 return; | 176 return; |
180 } | 177 } |
181 } else { | 178 } else { |
182 path = fPath; | 179 path = fPath; |
183 } | 180 } |
184 if (!stroke.isFillStyle()) { | 181 if (!stroke.isFillStyle()) { |
185 stroke.setResScale(SkScalarAbs(fViewMatrix.getMaxScale())); | 182 stroke.setResScale(SkScalarAbs(fViewMatrix.getMaxScale())); |
186 if (!stroke.applyToPath(&path, path)) { | 183 if (!stroke.applyToPath(&path, path)) { |
187 return; | 184 return; |
188 } | 185 } |
189 stroke.setFillStyle(); | 186 stroke.setFillStyle(); |
190 } | 187 } |
191 bool isLinear; | 188 bool isLinear; |
192 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags(
); | 189 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags(
); |
193 StaticVertexAllocator allocator(vertexBuffer, target->resourceProvider()
, canMapVB); | 190 StaticVertexAllocator allocator(rp, canMapVB); |
194 int count = GrTessellator::PathToTriangles(path, tol, fClipBounds, &allo
cator, &isLinear); | 191 int count = GrTessellator::PathToTriangles(path, tol, fClipBounds, &allo
cator, &isLinear); |
195 if (count == 0) { | 192 if (count == 0) { |
196 return; | 193 return; |
197 } | 194 } |
198 this->drawVertices(target, gp, vertexBuffer.get(), 0, count); | 195 this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count); |
199 if (!fPath.isVolatile()) { | 196 if (!fPath.isVolatile()) { |
200 TessInfo info; | 197 TessInfo info; |
201 info.fTolerance = isLinear ? 0 : tol; | 198 info.fTolerance = isLinear ? 0 : tol; |
202 info.fCount = count; | 199 info.fCount = count; |
203 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info))); | 200 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info))); |
204 key.setCustomData(data.get()); | 201 key.setCustomData(data.get()); |
205 target->resourceProvider()->assignUniqueKeyToResource(key, vertexBuf
fer.get()); | 202 rp->assignUniqueKeyToResource(key, allocator.vertexBuffer()); |
206 SkPathPriv::AddGenIDChangeListener(fPath, new PathInvalidator(key)); | 203 SkPathPriv::AddGenIDChangeListener(fPath, new PathInvalidator(key)); |
207 } | 204 } |
208 } | 205 } |
209 | 206 |
210 void onPrepareDraws(Target* target) const override { | 207 void onPrepareDraws(Target* target) const override { |
211 SkAutoTUnref<const GrGeometryProcessor> gp; | 208 SkAutoTUnref<const GrGeometryProcessor> gp; |
212 { | 209 { |
213 using namespace GrDefaultGeoProcFactory; | 210 using namespace GrDefaultGeoProcFactory; |
214 | 211 |
215 Color color(fColor); | 212 Color color(fColor); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 bool result = viewMatrix.invert(&vmi); | 321 bool result = viewMatrix.invert(&vmi); |
325 if (!result) { | 322 if (!result) { |
326 SkFAIL("Cannot invert matrix\n"); | 323 SkFAIL("Cannot invert matrix\n"); |
327 } | 324 } |
328 vmi.mapRect(&clipBounds); | 325 vmi.mapRect(&clipBounds); |
329 GrStrokeInfo strokeInfo = GrTest::TestStrokeInfo(random); | 326 GrStrokeInfo strokeInfo = GrTest::TestStrokeInfo(random); |
330 return TessellatingPathBatch::Create(color, path, strokeInfo, viewMatrix, cl
ipBounds); | 327 return TessellatingPathBatch::Create(color, path, strokeInfo, viewMatrix, cl
ipBounds); |
331 } | 328 } |
332 | 329 |
333 #endif | 330 #endif |
OLD | NEW |