OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2014 Google Inc. | 3 * Copyright 2014 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrAADistanceFieldPathRenderer.h" | 9 #include "GrAADistanceFieldPathRenderer.h" |
10 | 10 |
11 #include "GrBatchTarget.h" | 11 #include "GrBatchFlushState.h" |
12 #include "GrBatchTest.h" | 12 #include "GrBatchTest.h" |
13 #include "GrContext.h" | 13 #include "GrContext.h" |
14 #include "GrPipelineBuilder.h" | 14 #include "GrPipelineBuilder.h" |
15 #include "GrResourceProvider.h" | 15 #include "GrResourceProvider.h" |
16 #include "GrSurfacePriv.h" | 16 #include "GrSurfacePriv.h" |
17 #include "GrSWMaskHelper.h" | 17 #include "GrSWMaskHelper.h" |
18 #include "GrTexturePriv.h" | 18 #include "GrTexturePriv.h" |
19 #include "GrVertexBuffer.h" | 19 #include "GrVertexBuffer.h" |
20 #include "batches/GrVertexBatch.h" | 20 #include "batches/GrVertexBatch.h" |
21 #include "effects/GrDistanceFieldGeoProc.h" | 21 #include "effects/GrDistanceFieldGeoProc.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 fBatch.fCoverageIgnored = !opt.readsCoverage(); | 152 fBatch.fCoverageIgnored = !opt.readsCoverage(); |
153 } | 153 } |
154 | 154 |
155 struct FlushInfo { | 155 struct FlushInfo { |
156 SkAutoTUnref<const GrVertexBuffer> fVertexBuffer; | 156 SkAutoTUnref<const GrVertexBuffer> fVertexBuffer; |
157 SkAutoTUnref<const GrIndexBuffer> fIndexBuffer; | 157 SkAutoTUnref<const GrIndexBuffer> fIndexBuffer; |
158 int fVertexOffset; | 158 int fVertexOffset; |
159 int fInstancesToFlush; | 159 int fInstancesToFlush; |
160 }; | 160 }; |
161 | 161 |
162 void generateGeometry(GrBatchTarget* batchTarget) override { | 162 void onPrepareDraws(Target* target) override { |
163 int instanceCount = fGeoData.count(); | 163 int instanceCount = fGeoData.count(); |
164 | 164 |
165 SkMatrix invert; | 165 SkMatrix invert; |
166 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { | 166 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { |
167 SkDebugf("Could not invert viewmatrix\n"); | 167 SkDebugf("Could not invert viewmatrix\n"); |
168 return; | 168 return; |
169 } | 169 } |
170 | 170 |
171 uint32_t flags = 0; | 171 uint32_t flags = 0; |
172 flags |= this->viewMatrix().isSimilarity() ? kSimilarity_DistanceFieldEf
fectFlag : 0; | 172 flags |= this->viewMatrix().isSimilarity() ? kSimilarity_DistanceFieldEf
fectFlag : 0; |
173 | 173 |
174 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil
erp_FilterMode); | 174 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil
erp_FilterMode); |
175 | 175 |
176 // Setup GrGeometryProcessor | 176 // Setup GrGeometryProcessor |
177 GrBatchAtlas* atlas = fAtlas; | 177 GrBatchAtlas* atlas = fAtlas; |
178 SkAutoTUnref<GrGeometryProcessor> dfProcessor( | 178 SkAutoTUnref<GrGeometryProcessor> dfProcessor( |
179 GrDistanceFieldPathGeoProc::Create(this->color(), | 179 GrDistanceFieldPathGeoProc::Create(this->color(), |
180 this->viewMatrix(), | 180 this->viewMatrix(), |
181 atlas->getTexture(), | 181 atlas->getTexture(), |
182 params, | 182 params, |
183 flags, | 183 flags, |
184 this->usesLocalCoords())); | 184 this->usesLocalCoords())); |
185 | 185 |
186 batchTarget->initDraw(dfProcessor, this->pipeline()); | 186 target->initDraw(dfProcessor, this->pipeline()); |
187 | 187 |
188 FlushInfo flushInfo; | 188 FlushInfo flushInfo; |
189 | 189 |
190 // allocate vertices | 190 // allocate vertices |
191 size_t vertexStride = dfProcessor->getVertexStride(); | 191 size_t vertexStride = dfProcessor->getVertexStride(); |
192 SkASSERT(vertexStride == 2 * sizeof(SkPoint)); | 192 SkASSERT(vertexStride == 2 * sizeof(SkPoint)); |
193 | 193 |
194 const GrVertexBuffer* vertexBuffer; | 194 const GrVertexBuffer* vertexBuffer; |
195 void* vertices = batchTarget->makeVertSpace(vertexStride, | 195 void* vertices = target->makeVertexSpace(vertexStride, |
196 kVerticesPerQuad * instanceC
ount, | 196 kVerticesPerQuad * instanceCoun
t, |
197 &vertexBuffer, | 197 &vertexBuffer, |
198 &flushInfo.fVertexOffset); | 198 &flushInfo.fVertexOffset); |
199 flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer)); | 199 flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer)); |
200 flushInfo.fIndexBuffer.reset(batchTarget->resourceProvider()->refQuadInd
exBuffer()); | 200 flushInfo.fIndexBuffer.reset(target->resourceProvider()->refQuadIndexBuf
fer()); |
201 if (!vertices || !flushInfo.fIndexBuffer) { | 201 if (!vertices || !flushInfo.fIndexBuffer) { |
202 SkDebugf("Could not allocate vertices\n"); | 202 SkDebugf("Could not allocate vertices\n"); |
203 return; | 203 return; |
204 } | 204 } |
205 | 205 |
206 flushInfo.fInstancesToFlush = 0; | 206 flushInfo.fInstancesToFlush = 0; |
207 for (int i = 0; i < instanceCount; i++) { | 207 for (int i = 0; i < instanceCount; i++) { |
208 Geometry& args = fGeoData[i]; | 208 Geometry& args = fGeoData[i]; |
209 | 209 |
210 // get mip level | 210 // get mip level |
(...skipping 16 matching lines...) Expand all Loading... |
227 args.fPathData = fPathCache->find(key); | 227 args.fPathData = fPathCache->find(key); |
228 if (NULL == args.fPathData || !atlas->hasID(args.fPathData->fID)) { | 228 if (NULL == args.fPathData || !atlas->hasID(args.fPathData->fID)) { |
229 // Remove the stale cache entry | 229 // Remove the stale cache entry |
230 if (args.fPathData) { | 230 if (args.fPathData) { |
231 fPathCache->remove(args.fPathData->fKey); | 231 fPathCache->remove(args.fPathData->fKey); |
232 fPathList->remove(args.fPathData); | 232 fPathList->remove(args.fPathData); |
233 SkDELETE(args.fPathData); | 233 SkDELETE(args.fPathData); |
234 } | 234 } |
235 SkScalar scale = desiredDimension/maxDim; | 235 SkScalar scale = desiredDimension/maxDim; |
236 args.fPathData = SkNEW(PathData); | 236 args.fPathData = SkNEW(PathData); |
237 if (!this->addPathToAtlas(batchTarget, | 237 if (!this->addPathToAtlas(target, |
238 dfProcessor, | 238 dfProcessor, |
239 this->pipeline(), | 239 this->pipeline(), |
240 &flushInfo, | 240 &flushInfo, |
241 atlas, | 241 atlas, |
242 args.fPathData, | 242 args.fPathData, |
243 args.fPath, | 243 args.fPath, |
244 args.fStroke, | 244 args.fStroke, |
245 args.fAntiAlias, | 245 args.fAntiAlias, |
246 desiredDimension, | 246 desiredDimension, |
247 scale)) { | 247 scale)) { |
248 SkDebugf("Can't rasterize path\n"); | 248 SkDebugf("Can't rasterize path\n"); |
249 return; | 249 return; |
250 } | 250 } |
251 } | 251 } |
252 | 252 |
253 atlas->setLastUseToken(args.fPathData->fID, batchTarget->currentToke
n()); | 253 atlas->setLastUseToken(args.fPathData->fID, target->currentToken()); |
254 | 254 |
255 // Now set vertices | 255 // Now set vertices |
256 intptr_t offset = reinterpret_cast<intptr_t>(vertices); | 256 intptr_t offset = reinterpret_cast<intptr_t>(vertices); |
257 offset += i * kVerticesPerQuad * vertexStride; | 257 offset += i * kVerticesPerQuad * vertexStride; |
258 SkPoint* positions = reinterpret_cast<SkPoint*>(offset); | 258 SkPoint* positions = reinterpret_cast<SkPoint*>(offset); |
259 this->writePathVertices(batchTarget, | 259 this->writePathVertices(target, |
260 atlas, | 260 atlas, |
261 this->pipeline(), | 261 this->pipeline(), |
262 dfProcessor, | 262 dfProcessor, |
263 positions, | 263 positions, |
264 vertexStride, | 264 vertexStride, |
265 this->viewMatrix(), | 265 this->viewMatrix(), |
266 args.fPath, | 266 args.fPath, |
267 args.fPathData); | 267 args.fPathData); |
268 flushInfo.fInstancesToFlush++; | 268 flushInfo.fInstancesToFlush++; |
269 } | 269 } |
270 | 270 |
271 this->flush(batchTarget, &flushInfo); | 271 this->flush(target, &flushInfo); |
272 } | 272 } |
273 | 273 |
274 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 274 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
275 | 275 |
276 private: | 276 private: |
277 AADistanceFieldPathBatch(const Geometry& geometry, GrColor color, const SkMa
trix& viewMatrix, | 277 AADistanceFieldPathBatch(const Geometry& geometry, GrColor color, const SkMa
trix& viewMatrix, |
278 GrBatchAtlas* atlas, | 278 GrBatchAtlas* atlas, |
279 PathCache* pathCache, PathDataList* pathList) { | 279 PathCache* pathCache, PathDataList* pathList) { |
280 this->initClassID<AADistanceFieldPathBatch>(); | 280 this->initClassID<AADistanceFieldPathBatch>(); |
281 fBatch.fColor = color; | 281 fBatch.fColor = color; |
282 fBatch.fViewMatrix = viewMatrix; | 282 fBatch.fViewMatrix = viewMatrix; |
283 fGeoData.push_back(geometry); | 283 fGeoData.push_back(geometry); |
284 fGeoData.back().fPathData = NULL; | 284 fGeoData.back().fPathData = NULL; |
285 | 285 |
286 fAtlas = atlas; | 286 fAtlas = atlas; |
287 fPathCache = pathCache; | 287 fPathCache = pathCache; |
288 fPathList = pathList; | 288 fPathList = pathList; |
289 | 289 |
290 // Compute bounds | 290 // Compute bounds |
291 fBounds = geometry.fPath.getBounds(); | 291 fBounds = geometry.fPath.getBounds(); |
292 viewMatrix.mapRect(&fBounds); | 292 viewMatrix.mapRect(&fBounds); |
293 } | 293 } |
294 | 294 |
295 bool addPathToAtlas(GrBatchTarget* batchTarget, | 295 bool addPathToAtlas(GrVertexBatch::Target* target, |
296 const GrGeometryProcessor* dfProcessor, | 296 const GrGeometryProcessor* dfProcessor, |
297 const GrPipeline* pipeline, | 297 const GrPipeline* pipeline, |
298 FlushInfo* flushInfo, | 298 FlushInfo* flushInfo, |
299 GrBatchAtlas* atlas, | 299 GrBatchAtlas* atlas, |
300 PathData* pathData, | 300 PathData* pathData, |
301 const SkPath& path, | 301 const SkPath& path, |
302 const SkStrokeRec& | 302 const SkStrokeRec& |
303 stroke, bool antiAlias, | 303 stroke, bool antiAlias, |
304 uint32_t dimension, | 304 uint32_t dimension, |
305 SkScalar scale) { | 305 SkScalar scale) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 SkAutoSMalloc<1024> dfStorage(width * height * sizeof(unsigned char)); | 381 SkAutoSMalloc<1024> dfStorage(width * height * sizeof(unsigned char)); |
382 | 382 |
383 // Generate signed distance field | 383 // Generate signed distance field |
384 SkGenerateDistanceFieldFromA8Image((unsigned char*)dfStorage.get(), | 384 SkGenerateDistanceFieldFromA8Image((unsigned char*)dfStorage.get(), |
385 (const unsigned char*)dst.addr(), | 385 (const unsigned char*)dst.addr(), |
386 dst.width(), dst.height(), dst.rowByt
es()); | 386 dst.width(), dst.height(), dst.rowByt
es()); |
387 | 387 |
388 // add to atlas | 388 // add to atlas |
389 SkIPoint16 atlasLocation; | 389 SkIPoint16 atlasLocation; |
390 GrBatchAtlas::AtlasID id; | 390 GrBatchAtlas::AtlasID id; |
391 bool success = atlas->addToAtlas(&id, batchTarget, width, height, dfStor
age.get(), | 391 bool success = atlas->addToAtlas(&id, target, width, height, dfStorage.g
et(), |
392 &atlasLocation); | 392 &atlasLocation); |
393 if (!success) { | 393 if (!success) { |
394 this->flush(batchTarget, flushInfo); | 394 this->flush(target, flushInfo); |
395 batchTarget->initDraw(dfProcessor, pipeline); | 395 target->initDraw(dfProcessor, pipeline); |
396 | 396 |
397 SkDEBUGCODE(success =) atlas->addToAtlas(&id, batchTarget, width, he
ight, | 397 SkDEBUGCODE(success =) atlas->addToAtlas(&id, target, width, height, |
398 dfStorage.get(), &atlasLoca
tion); | 398 dfStorage.get(), &atlasLoca
tion); |
399 SkASSERT(success); | 399 SkASSERT(success); |
400 | 400 |
401 } | 401 } |
402 | 402 |
403 // add to cache | 403 // add to cache |
404 pathData->fKey.fGenID = path.getGenerationID(); | 404 pathData->fKey.fGenID = path.getGenerationID(); |
405 pathData->fKey.fDimension = dimension; | 405 pathData->fKey.fDimension = dimension; |
406 pathData->fScale = scale; | 406 pathData->fScale = scale; |
407 pathData->fID = id; | 407 pathData->fID = id; |
(...skipping 13 matching lines...) Expand all Loading... |
421 pathData->fAtlasLocation = atlasLocation; | 421 pathData->fAtlasLocation = atlasLocation; |
422 | 422 |
423 fPathCache->add(pathData); | 423 fPathCache->add(pathData); |
424 fPathList->addToTail(pathData); | 424 fPathList->addToTail(pathData); |
425 #ifdef DF_PATH_TRACKING | 425 #ifdef DF_PATH_TRACKING |
426 ++g_NumCachedPaths; | 426 ++g_NumCachedPaths; |
427 #endif | 427 #endif |
428 return true; | 428 return true; |
429 } | 429 } |
430 | 430 |
431 void writePathVertices(GrBatchTarget* target, | 431 void writePathVertices(GrDrawBatch::Target* target, |
432 GrBatchAtlas* atlas, | 432 GrBatchAtlas* atlas, |
433 const GrPipeline* pipeline, | 433 const GrPipeline* pipeline, |
434 const GrGeometryProcessor* gp, | 434 const GrGeometryProcessor* gp, |
435 SkPoint* positions, | 435 SkPoint* positions, |
436 size_t vertexStride, | 436 size_t vertexStride, |
437 const SkMatrix& viewMatrix, | 437 const SkMatrix& viewMatrix, |
438 const SkPath& path, | 438 const SkPath& path, |
439 const PathData* pathData) { | 439 const PathData* pathData) { |
440 GrTexture* texture = atlas->getTexture(); | 440 GrTexture* texture = atlas->getTexture(); |
441 | 441 |
(...skipping 20 matching lines...) Expand all Loading... |
462 | 462 |
463 // vertex texture coords | 463 // vertex texture coords |
464 SkPoint* textureCoords = positions + 1; | 464 SkPoint* textureCoords = positions + 1; |
465 textureCoords->setRectFan(SkFixedToFloat(texture->texturePriv().normaliz
eFixedX(tx)), | 465 textureCoords->setRectFan(SkFixedToFloat(texture->texturePriv().normaliz
eFixedX(tx)), |
466 SkFixedToFloat(texture->texturePriv().normaliz
eFixedY(ty)), | 466 SkFixedToFloat(texture->texturePriv().normaliz
eFixedY(ty)), |
467 SkFixedToFloat(texture->texturePriv().normaliz
eFixedX(tx + tw)), | 467 SkFixedToFloat(texture->texturePriv().normaliz
eFixedX(tx + tw)), |
468 SkFixedToFloat(texture->texturePriv().normaliz
eFixedY(ty + th)), | 468 SkFixedToFloat(texture->texturePriv().normaliz
eFixedY(ty + th)), |
469 vertexStride); | 469 vertexStride); |
470 } | 470 } |
471 | 471 |
472 void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) { | 472 void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) { |
473 GrVertices vertices; | 473 GrVertices vertices; |
474 int maxInstancesPerDraw = flushInfo->fIndexBuffer->maxQuads(); | 474 int maxInstancesPerDraw = flushInfo->fIndexBuffer->maxQuads(); |
475 vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuf
fer, | 475 vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuf
fer, |
476 flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad, | 476 flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad, |
477 kIndicesPerQuad, flushInfo->fInstancesToFlush, maxInstancesPerDraw); | 477 kIndicesPerQuad, flushInfo->fInstancesToFlush, maxInstancesPerDraw); |
478 batchTarget->draw(vertices); | 478 target->draw(vertices); |
479 flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFl
ush; | 479 flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFl
ush; |
480 flushInfo->fInstancesToFlush = 0; | 480 flushInfo->fInstancesToFlush = 0; |
481 } | 481 } |
482 | 482 |
483 GrColor color() const { return fBatch.fColor; } | 483 GrColor color() const { return fBatch.fColor; } |
484 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } | 484 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } |
485 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 485 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
486 | 486 |
487 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 487 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
488 AADistanceFieldPathBatch* that = t->cast<AADistanceFieldPathBatch>(); | 488 AADistanceFieldPathBatch* that = t->cast<AADistanceFieldPathBatch>(); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 geometry.fPath = GrTest::TestPath(random); | 617 geometry.fPath = GrTest::TestPath(random); |
618 geometry.fAntiAlias = random->nextBool(); | 618 geometry.fAntiAlias = random->nextBool(); |
619 | 619 |
620 return AADistanceFieldPathBatch::Create(geometry, color, viewMatrix, | 620 return AADistanceFieldPathBatch::Create(geometry, color, viewMatrix, |
621 gTestStruct.fAtlas, | 621 gTestStruct.fAtlas, |
622 &gTestStruct.fPathCache, | 622 &gTestStruct.fPathCache, |
623 &gTestStruct.fPathList); | 623 &gTestStruct.fPathList); |
624 } | 624 } |
625 | 625 |
626 #endif | 626 #endif |
OLD | NEW |