Index: dm/DMQuiltTask.cpp |
diff --git a/dm/DMQuiltTask.cpp b/dm/DMQuiltTask.cpp |
index f184980c1d870bd9e9f1b5f72979a2cefbaf3c9b..44c4341a7d79de5475c92b7116fa0ef09d84b8da 100644 |
--- a/dm/DMQuiltTask.cpp |
+++ b/dm/DMQuiltTask.cpp |
@@ -4,9 +4,11 @@ |
#include "SkCommandLineFlags.h" |
#include "SkPicture.h" |
+#include "SkThreadPool.h" |
DEFINE_bool(quilt, true, "If true, draw into a quilt of small tiles and compare."); |
DEFINE_int32(quiltTile, 16, "Dimension of (square) quilt tile."); |
+DEFINE_bool(quiltThreaded, false, "If true, draw quilt tiles with multiple threads."); |
namespace DM { |
@@ -21,34 +23,65 @@ static int tiles_needed(int fullDimension, int tileDimension) { |
return (fullDimension + tileDimension - 1) / tileDimension; |
} |
+class Tile : public SkRunnable { |
+public: |
+ Tile(int x, int y, SkColorType colorType, |
+ const SkPicture& picture, SkCanvas* canvas, SkMutex* mutex) |
+ : fX(x) |
+ , fY(y) |
+ , fColorType(colorType) |
+ , fPicture(picture) |
+ , fCanvas(canvas) |
+ , fMutex(mutex) {} |
+ |
+ virtual void run() SK_OVERRIDE { |
+ SkBitmap tile; |
+ tile.allocPixels(SkImageInfo::Make(FLAGS_quiltTile, FLAGS_quiltTile, |
+ fColorType, kPremul_SkAlphaType)); |
+ SkCanvas tileCanvas(tile); |
+ |
+ const SkScalar xOffset = SkIntToScalar(fX * tile.width()), |
+ yOffset = SkIntToScalar(fY * tile.height()); |
+ tileCanvas.translate(-xOffset, -yOffset); |
+ fPicture.draw(&tileCanvas); |
+ tileCanvas.flush(); |
+ |
+ { |
+ SkAutoMutexAcquire lock(fMutex); |
+ fCanvas->drawBitmap(tile, xOffset, yOffset, NULL); |
+ } |
+ |
+ delete this; |
+ } |
+ |
+private: |
+ const int fX, fY; |
+ const SkColorType fColorType; |
+ const SkPicture& fPicture; |
+ SkCanvas* fCanvas; |
+ SkMutex* fMutex; // Guards fCanvas. |
+}; |
+ |
void QuiltTask::draw() { |
SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get())); |
SkBitmap full; |
AllocatePixels(fReference, &full); |
SkCanvas fullCanvas(full); |
+ SkMutex mutex; // Guards fullCanvas. |
- SkBitmap tile; |
- tile.allocPixels(SkImageInfo::Make(FLAGS_quiltTile, FLAGS_quiltTile, |
- fReference.colorType(), kPremul_SkAlphaType)); |
- SkCanvas tileCanvas(tile); |
- |
- for (int y = 0; y < tiles_needed(full.height(), tile.height()); y++) { |
- for (int x = 0; x < tiles_needed(full.width(), tile.width()); x++) { |
- SkAutoCanvasRestore ar(&tileCanvas, true/*also save now*/); |
+ SkThreadPool pool(FLAGS_quiltThreaded ? SkThreadPool::kThreadPerCore : 0); |
- const SkScalar xOffset = SkIntToScalar(x * tile.width()), |
- yOffset = SkIntToScalar(y * tile.height()); |
- SkMatrix matrix = tileCanvas.getTotalMatrix(); |
- matrix.postTranslate(-xOffset, -yOffset); |
- tileCanvas.setMatrix(matrix); |
- |
- recorded->draw(&tileCanvas); |
- tileCanvas.flush(); |
- fullCanvas.drawBitmap(tile, xOffset, yOffset, NULL); |
+ for (int y = 0; y < tiles_needed(full.height(), FLAGS_quiltTile); y++) { |
+ for (int x = 0; x < tiles_needed(full.width(), FLAGS_quiltTile); x++) { |
+ // Deletes itself when done. |
+ pool.add(new Tile(x, y, fReference.colorType(), *recorded, &fullCanvas, &mutex)); |
} |
} |
+ pool.wait(); |
+ fullCanvas.flush(); |
+ |
if (!BitmapsEqual(full, fReference)) { |
this->fail(); |
this->spawnChild(SkNEW_ARGS(WriteTask, (*this, full))); |