blob: 3d7daf27eb0003e07670ed370dc8703da52c753a [file] [log] [blame]
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +00001#include "DMQuiltTask.h"
2#include "DMUtil.h"
3#include "DMWriteTask.h"
4
mtkleine4636aa2014-07-09 13:10:58 -07005#include "SkBBHFactory.h"
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +00006#include "SkCommandLineFlags.h"
7#include "SkPicture.h"
mtklein406654b2014-09-03 15:34:37 -07008#include "SkTaskGroup.h"
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +00009
mtkleine4636aa2014-07-09 13:10:58 -070010DEFINE_bool(quilt, true, "If true, draw GM via a picture into a quilt of small tiles and compare.");
mtklein7cdc1ee2014-07-07 10:41:04 -070011DEFINE_int32(quiltTile, 256, "Dimension of (square) quilt tile.");
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000012
13namespace DM {
14
mtkleina9ceaf52014-09-29 08:44:46 -070015static const char* kBBHs[] = { "nobbh", "rtree", "tilegrid" };
16QuiltTask::QuiltTask(const Task& parent, skiagm::GM* gm, SkBitmap reference, QuiltTask::BBH bbh)
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000017 : CpuTask(parent)
mtklein5ad6ee12014-08-11 08:08:43 -070018 , fBBH(bbh)
mtkleina9ceaf52014-09-29 08:44:46 -070019 , fName(UnderJoin(parent.name().c_str(), kBBHs[bbh]))
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000020 , fGM(gm)
21 , fReference(reference)
22 {}
23
24static int tiles_needed(int fullDimension, int tileDimension) {
25 return (fullDimension + tileDimension - 1) / tileDimension;
26}
27
mtkleinec2ae582014-07-01 07:46:50 -070028class Tile : public SkRunnable {
29public:
mtklein7cdc1ee2014-07-07 10:41:04 -070030 Tile(int x, int y, const SkPicture& picture, SkBitmap* quilt)
31 : fX(x * FLAGS_quiltTile)
32 , fY(y * FLAGS_quiltTile)
mtkleinec2ae582014-07-01 07:46:50 -070033 , fPicture(picture)
mtklein7cdc1ee2014-07-07 10:41:04 -070034 , fQuilt(quilt) {}
mtkleinec2ae582014-07-01 07:46:50 -070035
36 virtual void run() SK_OVERRIDE {
37 SkBitmap tile;
mtklein7cdc1ee2014-07-07 10:41:04 -070038 fQuilt->extractSubset(&tile, SkIRect::MakeXYWH(fX, fY, FLAGS_quiltTile, FLAGS_quiltTile));
mtkleinec2ae582014-07-01 07:46:50 -070039 SkCanvas tileCanvas(tile);
40
mtklein7cdc1ee2014-07-07 10:41:04 -070041 tileCanvas.translate(SkIntToScalar(-fX), SkIntToScalar(-fY));
robertphillipsc5ba71d2014-09-04 08:42:50 -070042 fPicture.playback(&tileCanvas);
mtkleinec2ae582014-07-01 07:46:50 -070043 tileCanvas.flush();
44
mtkleinec2ae582014-07-01 07:46:50 -070045 delete this;
46 }
47
48private:
49 const int fX, fY;
mtkleinec2ae582014-07-01 07:46:50 -070050 const SkPicture& fPicture;
mtklein7cdc1ee2014-07-07 10:41:04 -070051 SkBitmap* fQuilt;
mtkleinec2ae582014-07-01 07:46:50 -070052};
53
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000054void QuiltTask::draw() {
mtkleine4636aa2014-07-09 13:10:58 -070055 SkAutoTDelete<SkBBHFactory> factory;
mtklein5ad6ee12014-08-11 08:08:43 -070056 switch (fBBH) {
57 case kNone_BBH: break;
58 case kRTree_BBH:
mtkleine4636aa2014-07-09 13:10:58 -070059 factory.reset(SkNEW(SkRTreeFactory));
60 break;
mtklein5ad6ee12014-08-11 08:08:43 -070061 case kTileGrid_BBH: {
mtkleine4636aa2014-07-09 13:10:58 -070062 const SkTileGridFactory::TileGridInfo tiles = {
63 { FLAGS_quiltTile, FLAGS_quiltTile },
64 /*overlap: */{0, 0},
65 /*offset: */{0, 0},
66 };
67 factory.reset(SkNEW_ARGS(SkTileGridFactory, (tiles)));
68 break;
69 }
mtkleine4636aa2014-07-09 13:10:58 -070070 }
71
72 // A couple GMs draw wrong when using a bounding box hierarchy.
73 // This almost certainly means we have a bug to fix, but for now
74 // just draw without a bounding box hierarchy.
75 if (fGM->getFlags() & skiagm::GM::kNoBBH_Flag) {
76 factory.reset(NULL);
77 }
78
mtkleina9ceaf52014-09-29 08:44:46 -070079 SkAutoTUnref<const SkPicture> recorded(RecordPicture(fGM.get(), factory.get()));
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000080
81 SkBitmap full;
commit-bot@chromium.org26642072014-05-15 17:33:31 +000082 AllocatePixels(fReference, &full);
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000083
mtkleine4636aa2014-07-09 13:10:58 -070084 if (fGM->getFlags() & skiagm::GM::kSkipTiled_Flag) {
85 // Some GMs don't draw exactly the same when tiled. Draw them in one go.
86 SkCanvas canvas(full);
robertphillipsc5ba71d2014-09-04 08:42:50 -070087 recorded->playback(&canvas);
mtkleine4636aa2014-07-09 13:10:58 -070088 canvas.flush();
89 } else {
90 // Draw tiles in parallel into the same bitmap, simulating aggressive impl-side painting.
mtklein406654b2014-09-03 15:34:37 -070091 SkTaskGroup tg;
mtkleine4636aa2014-07-09 13:10:58 -070092 for (int y = 0; y < tiles_needed(full.height(), FLAGS_quiltTile); y++) {
93 for (int x = 0; x < tiles_needed(full.width(), FLAGS_quiltTile); x++) {
94 // Deletes itself when done.
mtklein406654b2014-09-03 15:34:37 -070095 tg.add(new Tile(x, y, *recorded, &full));
mtkleine4636aa2014-07-09 13:10:58 -070096 }
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000097 }
98 }
99
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000100 if (!BitmapsEqual(full, fReference)) {
101 this->fail();
mtkleinea65bfa2014-09-09 07:59:46 -0700102 this->spawnChild(SkNEW_ARGS(WriteTask, (*this, "GM", full)));
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000103 }
104}
105
106bool QuiltTask::shouldSkip() const {
107 if (fGM->getFlags() & skiagm::GM::kSkipPicture_Flag) {
108 return true;
109 }
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000110 return !FLAGS_quilt;
111}
112
113} // namespace DM