| OLD | NEW |
| 1 #include "DMQuiltTask.h" | 1 #include "DMQuiltTask.h" |
| 2 #include "DMUtil.h" | 2 #include "DMUtil.h" |
| 3 #include "DMWriteTask.h" | 3 #include "DMWriteTask.h" |
| 4 | 4 |
| 5 #include "SkCommandLineFlags.h" | 5 #include "SkCommandLineFlags.h" |
| 6 #include "SkPicture.h" | 6 #include "SkPicture.h" |
| 7 #include "SkThreadPool.h" |
| 7 | 8 |
| 8 DEFINE_bool(quilt, true, "If true, draw into a quilt of small tiles and compare.
"); | 9 DEFINE_bool(quilt, true, "If true, draw into a quilt of small tiles and compare.
"); |
| 9 DEFINE_int32(quiltTile, 16, "Dimension of (square) quilt tile."); | 10 DEFINE_int32(quiltTile, 16, "Dimension of (square) quilt tile."); |
| 11 DEFINE_bool(quiltThreaded, false, "If true, draw quilt tiles with multiple threa
ds."); |
| 10 | 12 |
| 11 namespace DM { | 13 namespace DM { |
| 12 | 14 |
| 13 QuiltTask::QuiltTask(const Task& parent, skiagm::GM* gm, SkBitmap reference) | 15 QuiltTask::QuiltTask(const Task& parent, skiagm::GM* gm, SkBitmap reference) |
| 14 : CpuTask(parent) | 16 : CpuTask(parent) |
| 15 , fName(UnderJoin(parent.name().c_str(), "quilt")) | 17 , fName(UnderJoin(parent.name().c_str(), "quilt")) |
| 16 , fGM(gm) | 18 , fGM(gm) |
| 17 , fReference(reference) | 19 , fReference(reference) |
| 18 {} | 20 {} |
| 19 | 21 |
| 20 static int tiles_needed(int fullDimension, int tileDimension) { | 22 static int tiles_needed(int fullDimension, int tileDimension) { |
| 21 return (fullDimension + tileDimension - 1) / tileDimension; | 23 return (fullDimension + tileDimension - 1) / tileDimension; |
| 22 } | 24 } |
| 23 | 25 |
| 26 class Tile : public SkRunnable { |
| 27 public: |
| 28 Tile(int x, int y, SkColorType colorType, |
| 29 const SkPicture& picture, SkCanvas* canvas, SkMutex* mutex) |
| 30 : fX(x) |
| 31 , fY(y) |
| 32 , fColorType(colorType) |
| 33 , fPicture(picture) |
| 34 , fCanvas(canvas) |
| 35 , fMutex(mutex) {} |
| 36 |
| 37 virtual void run() SK_OVERRIDE { |
| 38 SkBitmap tile; |
| 39 tile.allocPixels(SkImageInfo::Make(FLAGS_quiltTile, FLAGS_quiltTile, |
| 40 fColorType, kPremul_SkAlphaType)); |
| 41 SkCanvas tileCanvas(tile); |
| 42 |
| 43 const SkScalar xOffset = SkIntToScalar(fX * tile.width()), |
| 44 yOffset = SkIntToScalar(fY * tile.height()); |
| 45 tileCanvas.translate(-xOffset, -yOffset); |
| 46 fPicture.draw(&tileCanvas); |
| 47 tileCanvas.flush(); |
| 48 |
| 49 { |
| 50 SkAutoMutexAcquire lock(fMutex); |
| 51 fCanvas->drawBitmap(tile, xOffset, yOffset, NULL); |
| 52 } |
| 53 |
| 54 delete this; |
| 55 } |
| 56 |
| 57 private: |
| 58 const int fX, fY; |
| 59 const SkColorType fColorType; |
| 60 const SkPicture& fPicture; |
| 61 SkCanvas* fCanvas; |
| 62 SkMutex* fMutex; // Guards fCanvas. |
| 63 }; |
| 64 |
| 24 void QuiltTask::draw() { | 65 void QuiltTask::draw() { |
| 25 SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get())); | 66 SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get())); |
| 26 | 67 |
| 27 SkBitmap full; | 68 SkBitmap full; |
| 28 AllocatePixels(fReference, &full); | 69 AllocatePixels(fReference, &full); |
| 29 SkCanvas fullCanvas(full); | 70 SkCanvas fullCanvas(full); |
| 71 SkMutex mutex; // Guards fullCanvas. |
| 30 | 72 |
| 31 SkBitmap tile; | 73 SkThreadPool pool(FLAGS_quiltThreaded ? SkThreadPool::kThreadPerCore : 0); |
| 32 tile.allocPixels(SkImageInfo::Make(FLAGS_quiltTile, FLAGS_quiltTile, | |
| 33 fReference.colorType(), kPremul_SkAlphaTy
pe)); | |
| 34 SkCanvas tileCanvas(tile); | |
| 35 | 74 |
| 36 for (int y = 0; y < tiles_needed(full.height(), tile.height()); y++) { | 75 for (int y = 0; y < tiles_needed(full.height(), FLAGS_quiltTile); y++) { |
| 37 for (int x = 0; x < tiles_needed(full.width(), tile.width()); x++) { | 76 for (int x = 0; x < tiles_needed(full.width(), FLAGS_quiltTile); x++) { |
| 38 SkAutoCanvasRestore ar(&tileCanvas, true/*also save now*/); | 77 // Deletes itself when done. |
| 39 | 78 pool.add(new Tile(x, y, fReference.colorType(), *recorded, &fullCanv
as, &mutex)); |
| 40 const SkScalar xOffset = SkIntToScalar(x * tile.width()), | |
| 41 yOffset = SkIntToScalar(y * tile.height()); | |
| 42 SkMatrix matrix = tileCanvas.getTotalMatrix(); | |
| 43 matrix.postTranslate(-xOffset, -yOffset); | |
| 44 tileCanvas.setMatrix(matrix); | |
| 45 | |
| 46 recorded->draw(&tileCanvas); | |
| 47 tileCanvas.flush(); | |
| 48 fullCanvas.drawBitmap(tile, xOffset, yOffset, NULL); | |
| 49 } | 79 } |
| 50 } | 80 } |
| 51 | 81 |
| 82 pool.wait(); |
| 83 fullCanvas.flush(); |
| 84 |
| 52 if (!BitmapsEqual(full, fReference)) { | 85 if (!BitmapsEqual(full, fReference)) { |
| 53 this->fail(); | 86 this->fail(); |
| 54 this->spawnChild(SkNEW_ARGS(WriteTask, (*this, full))); | 87 this->spawnChild(SkNEW_ARGS(WriteTask, (*this, full))); |
| 55 } | 88 } |
| 56 } | 89 } |
| 57 | 90 |
| 58 bool QuiltTask::shouldSkip() const { | 91 bool QuiltTask::shouldSkip() const { |
| 59 if (fGM->getFlags() & skiagm::GM::kSkipPicture_Flag) { | 92 if (fGM->getFlags() & skiagm::GM::kSkipPicture_Flag) { |
| 60 return true; | 93 return true; |
| 61 } | 94 } |
| 62 if (fGM->getFlags() & skiagm::GM::kSkipTiled_Flag) { | 95 if (fGM->getFlags() & skiagm::GM::kSkipTiled_Flag) { |
| 63 return true; | 96 return true; |
| 64 } | 97 } |
| 65 return !FLAGS_quilt; | 98 return !FLAGS_quilt; |
| 66 } | 99 } |
| 67 | 100 |
| 68 } // namespace DM | 101 } // namespace DM |
| OLD | NEW |