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()); | |
robertphillips
2014/07/01 13:59:56
Why not just "tileCanvas.translate(-xOffset, -yOff
mtklein_C
2014/07/01 14:07:18
Good point! Done.
| |
45 SkMatrix matrix = tileCanvas.getTotalMatrix(); | |
46 matrix.postTranslate(-xOffset, -yOffset); | |
47 tileCanvas.setMatrix(matrix); | |
48 fPicture.draw(&tileCanvas); | |
49 tileCanvas.flush(); | |
50 | |
51 { | |
52 SkAutoMutexAcquire lock(fMutex); | |
53 fCanvas->drawBitmap(tile, xOffset, yOffset, NULL); | |
54 } | |
55 | |
56 delete this; | |
57 } | |
58 | |
59 private: | |
60 const int fX, fY; | |
61 const SkColorType fColorType; | |
62 const SkPicture& fPicture; | |
63 SkCanvas* fCanvas; | |
64 SkMutex* fMutex; // Guards fCanvas. | |
robertphillips
2014/07/01 13:59:56
INHERITED ?
mtklein_C
2014/07/01 14:07:18
Would have, but seems silly to have it if it's not
| |
65 }; | |
66 | |
24 void QuiltTask::draw() { | 67 void QuiltTask::draw() { |
25 SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get())); | 68 SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get())); |
26 | 69 |
27 SkBitmap full; | 70 SkBitmap full; |
28 AllocatePixels(fReference, &full); | 71 AllocatePixels(fReference, &full); |
29 SkCanvas fullCanvas(full); | 72 SkCanvas fullCanvas(full); |
73 SkMutex mutex; // Guards fullCanvas. | |
30 | 74 |
31 SkBitmap tile; | 75 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 | 76 |
36 for (int y = 0; y < tiles_needed(full.height(), tile.height()); y++) { | 77 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++) { | 78 for (int x = 0; x < tiles_needed(full.width(), FLAGS_quiltTile); x++) { |
38 SkAutoCanvasRestore ar(&tileCanvas, true/*also save now*/); | 79 // Deletes itself when done. |
39 | 80 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 } | 81 } |
50 } | 82 } |
51 | 83 |
84 pool.wait(); | |
85 fullCanvas.flush(); | |
86 | |
52 if (!BitmapsEqual(full, fReference)) { | 87 if (!BitmapsEqual(full, fReference)) { |
53 this->fail(); | 88 this->fail(); |
54 this->spawnChild(SkNEW_ARGS(WriteTask, (*this, full))); | 89 this->spawnChild(SkNEW_ARGS(WriteTask, (*this, full))); |
55 } | 90 } |
56 } | 91 } |
57 | 92 |
58 bool QuiltTask::shouldSkip() const { | 93 bool QuiltTask::shouldSkip() const { |
59 if (fGM->getFlags() & skiagm::GM::kSkipPicture_Flag) { | 94 if (fGM->getFlags() & skiagm::GM::kSkipPicture_Flag) { |
60 return true; | 95 return true; |
61 } | 96 } |
62 if (fGM->getFlags() & skiagm::GM::kSkipTiled_Flag) { | 97 if (fGM->getFlags() & skiagm::GM::kSkipTiled_Flag) { |
63 return true; | 98 return true; |
64 } | 99 } |
65 return !FLAGS_quilt; | 100 return !FLAGS_quilt; |
66 } | 101 } |
67 | 102 |
68 } // namespace DM | 103 } // namespace DM |
OLD | NEW |