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