| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * Copyright 2016 ARM Ltd. | |
| 4 * | 3 * |
| 5 * 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 |
| 6 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 7 */ | 6 */ |
| 8 | 7 |
| 9 #include "GrAADistanceFieldPathRenderer.h" | 8 #include "GrAADistanceFieldPathRenderer.h" |
| 10 | 9 |
| 11 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
| 12 #include "GrBatchTest.h" | 11 #include "GrBatchTest.h" |
| 13 #include "GrBuffer.h" | 12 #include "GrBuffer.h" |
| 14 #include "GrContext.h" | 13 #include "GrContext.h" |
| 15 #include "GrPipelineBuilder.h" | 14 #include "GrPipelineBuilder.h" |
| 16 #include "GrResourceProvider.h" | 15 #include "GrResourceProvider.h" |
| 17 #include "GrSurfacePriv.h" | 16 #include "GrSurfacePriv.h" |
| 18 #include "GrSWMaskHelper.h" | 17 #include "GrSWMaskHelper.h" |
| 19 #include "GrTexturePriv.h" | 18 #include "GrTexturePriv.h" |
| 20 #include "batches/GrVertexBatch.h" | 19 #include "batches/GrVertexBatch.h" |
| 21 #include "effects/GrDistanceFieldGeoProc.h" | 20 #include "effects/GrDistanceFieldGeoProc.h" |
| 22 | 21 |
| 23 #include "SkPathOps.h" | |
| 24 #include "SkDistanceFieldGen.h" | 22 #include "SkDistanceFieldGen.h" |
| 25 #include "GrDistanceFieldGenFromVector.h" | |
| 26 | 23 |
| 27 #define ATLAS_TEXTURE_WIDTH 2048 | 24 #define ATLAS_TEXTURE_WIDTH 2048 |
| 28 #define ATLAS_TEXTURE_HEIGHT 2048 | 25 #define ATLAS_TEXTURE_HEIGHT 2048 |
| 29 #define PLOT_WIDTH 512 | 26 #define PLOT_WIDTH 512 |
| 30 #define PLOT_HEIGHT 256 | 27 #define PLOT_HEIGHT 256 |
| 31 | 28 |
| 32 #define NUM_PLOTS_X (ATLAS_TEXTURE_WIDTH / PLOT_WIDTH) | 29 #define NUM_PLOTS_X (ATLAS_TEXTURE_WIDTH / PLOT_WIDTH) |
| 33 #define NUM_PLOTS_Y (ATLAS_TEXTURE_HEIGHT / PLOT_HEIGHT) | 30 #define NUM_PLOTS_Y (ATLAS_TEXTURE_HEIGHT / PLOT_HEIGHT) |
| 34 | 31 |
| 35 #ifdef DF_PATH_TRACKING | 32 #ifdef DF_PATH_TRACKING |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 return false; | 104 return false; |
| 108 } | 105 } |
| 109 | 106 |
| 110 // only support paths with bounds within kMediumMIP by kMediumMIP, | 107 // only support paths with bounds within kMediumMIP by kMediumMIP, |
| 111 // scaled to have bounds within 2.0f*kLargeMIP by 2.0f*kLargeMIP | 108 // scaled to have bounds within 2.0f*kLargeMIP by 2.0f*kLargeMIP |
| 112 // the goal is to accelerate rendering of lots of small paths that may be sc
aling | 109 // the goal is to accelerate rendering of lots of small paths that may be sc
aling |
| 113 SkScalar maxScale = args.fViewMatrix->getMaxScale(); | 110 SkScalar maxScale = args.fViewMatrix->getMaxScale(); |
| 114 SkRect bounds = args.fShape->styledBounds(); | 111 SkRect bounds = args.fShape->styledBounds(); |
| 115 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); | 112 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); |
| 116 | 113 |
| 117 if (!(maxDim <= kMediumMIP && maxDim * maxScale <= 2.0f*kLargeMIP)) { | 114 return maxDim <= kMediumMIP && maxDim * maxScale <= 2.0f*kLargeMIP; |
| 118 return false; | |
| 119 } | |
| 120 | |
| 121 // Only support even-odd fill type. (Checked by the IsDistanceFieldSupported
FillType function) | |
| 122 // The Simplify operation can convert some paths into even-odd fill type. | |
| 123 // Check whether we can generate distance field from this path after Simplif
y. | |
| 124 // TODO: Cache the simplifiedPath/workingPath somewhere for later use. | |
| 125 SkPath path; | |
| 126 args.fShape->asPath(&path); | |
| 127 SkPath simplifiedPath; | |
| 128 const SkPath* workingPath; | |
| 129 if (Simplify(path, &simplifiedPath)) { | |
| 130 workingPath = &simplifiedPath; | |
| 131 } else { | |
| 132 workingPath = &path; | |
| 133 } | |
| 134 return IsDistanceFieldSupportedFillType(workingPath->getFillType()); | |
| 135 } | 115 } |
| 136 | 116 |
| 137 //////////////////////////////////////////////////////////////////////////////// | 117 //////////////////////////////////////////////////////////////////////////////// |
| 138 | 118 |
| 139 // padding around path bounds to allow for antialiased pixels | 119 // padding around path bounds to allow for antialiased pixels |
| 140 static const SkScalar kAntiAliasPad = 1.0f; | 120 static const SkScalar kAntiAliasPad = 1.0f; |
| 141 | 121 |
| 142 class AADistanceFieldPathBatch : public GrVertexBatch { | 122 class AADistanceFieldPathBatch : public GrVertexBatch { |
| 143 public: | 123 public: |
| 144 DEFINE_BATCH_CLASS_ID | 124 DEFINE_BATCH_CLASS_ID |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 devPathBounds.fRight = intPad + width; | 319 devPathBounds.fRight = intPad + width; |
| 340 devPathBounds.fBottom = intPad + height; | 320 devPathBounds.fBottom = intPad + height; |
| 341 devPathBounds.outset(intPad, intPad); | 321 devPathBounds.outset(intPad, intPad); |
| 342 | 322 |
| 343 // draw path to bitmap | 323 // draw path to bitmap |
| 344 SkMatrix drawMatrix; | 324 SkMatrix drawMatrix; |
| 345 drawMatrix.setTranslate(-bounds.left(), -bounds.top()); | 325 drawMatrix.setTranslate(-bounds.left(), -bounds.top()); |
| 346 drawMatrix.postScale(scale, scale); | 326 drawMatrix.postScale(scale, scale); |
| 347 drawMatrix.postTranslate(kAntiAliasPad, kAntiAliasPad); | 327 drawMatrix.postTranslate(kAntiAliasPad, kAntiAliasPad); |
| 348 | 328 |
| 329 // setup bitmap backing |
| 349 SkASSERT(devPathBounds.fLeft == 0); | 330 SkASSERT(devPathBounds.fLeft == 0); |
| 350 SkASSERT(devPathBounds.fTop == 0); | 331 SkASSERT(devPathBounds.fTop == 0); |
| 332 SkAutoPixmapStorage dst; |
| 333 if (!dst.tryAlloc(SkImageInfo::MakeA8(devPathBounds.width(), |
| 334 devPathBounds.height()))) { |
| 335 return false; |
| 336 } |
| 337 sk_bzero(dst.writable_addr(), dst.getSafeSize()); |
| 338 |
| 339 // rasterize path |
| 340 SkPaint paint; |
| 341 paint.setStyle(SkPaint::kFill_Style); |
| 342 paint.setAntiAlias(antiAlias); |
| 343 |
| 344 SkDraw draw; |
| 345 sk_bzero(&draw, sizeof(draw)); |
| 346 |
| 347 SkRasterClip rasterClip; |
| 348 rasterClip.setRect(devPathBounds); |
| 349 draw.fRC = &rasterClip; |
| 350 draw.fMatrix = &drawMatrix; |
| 351 draw.fDst = dst; |
| 351 | 352 |
| 352 SkPath path; | 353 SkPath path; |
| 353 shape.asPath(&path); | 354 shape.asPath(&path); |
| 355 draw.drawPathCoverage(path, paint); |
| 354 | 356 |
| 355 // setup signed distance field storage | 357 // generate signed distance field |
| 356 devPathBounds.outset(SK_DistanceFieldPad, SK_DistanceFieldPad); | 358 devPathBounds.outset(SK_DistanceFieldPad, SK_DistanceFieldPad); |
| 357 width = devPathBounds.width(); | 359 width = devPathBounds.width(); |
| 358 height = devPathBounds.height(); | 360 height = devPathBounds.height(); |
| 359 // TODO We should really generate this directly into the plot somehow | 361 // TODO We should really generate this directly into the plot somehow |
| 360 SkAutoSMalloc<1024> dfStorage(width * height * sizeof(unsigned char)); | 362 SkAutoSMalloc<1024> dfStorage(width * height * sizeof(unsigned char)); |
| 361 | 363 |
| 362 // Generate signed distance field directly from SkPath | 364 // Generate signed distance field |
| 363 GrGenerateDistanceFieldFromPath((unsigned char*)dfStorage.get(), | 365 SkGenerateDistanceFieldFromA8Image((unsigned char*)dfStorage.get(), |
| 364 path, drawMatrix, | 366 (const unsigned char*)dst.addr(), |
| 365 width, height, width * sizeof(unsigned c
har)); | 367 dst.width(), dst.height(), dst.rowByt
es()); |
| 366 | 368 |
| 367 // add to atlas | 369 // add to atlas |
| 368 SkIPoint16 atlasLocation; | 370 SkIPoint16 atlasLocation; |
| 369 GrBatchAtlas::AtlasID id; | 371 GrBatchAtlas::AtlasID id; |
| 370 if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(), &atla
sLocation)) { | 372 if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(), &atla
sLocation)) { |
| 371 this->flush(target, flushInfo); | 373 this->flush(target, flushInfo); |
| 372 if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(),
&atlasLocation)) { | 374 if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(),
&atlasLocation)) { |
| 373 return false; | 375 return false; |
| 374 } | 376 } |
| 375 } | 377 } |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 shape, | 612 shape, |
| 611 antiAlias, | 613 antiAlias, |
| 612 viewMatrix, | 614 viewMatrix, |
| 613 gTestStruct.fAtlas, | 615 gTestStruct.fAtlas, |
| 614 &gTestStruct.fShapeCache, | 616 &gTestStruct.fShapeCache, |
| 615 &gTestStruct.fShapeList, | 617 &gTestStruct.fShapeList, |
| 616 gammaCorrect); | 618 gammaCorrect); |
| 617 } | 619 } |
| 618 | 620 |
| 619 #endif | 621 #endif |
| OLD | NEW |