blob: 83a989da718907cf5e070db719346bebadd641a4 [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
mtkleine71cd542014-10-29 14:17:13 -070028struct DrawTileArgs {
29 int x, y;
30 const SkPicture* picture;
31 SkBitmap* quilt;
mtkleinec2ae582014-07-01 07:46:50 -070032};
33
mtkleine71cd542014-10-29 14:17:13 -070034static void draw_tile(DrawTileArgs* arg) {
35 const DrawTileArgs& a = *arg;
36 SkBitmap tile;
37 a.quilt->extractSubset(&tile, SkIRect::MakeXYWH(a.x, a.y, FLAGS_quiltTile, FLAGS_quiltTile));
38 SkCanvas tileCanvas(tile);
39 tileCanvas.translate(SkIntToScalar(-a.x), SkIntToScalar(-a.y));
40 a.picture->playback(&tileCanvas);
41 tileCanvas.flush();
42}
43
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000044void QuiltTask::draw() {
mtkleine4636aa2014-07-09 13:10:58 -070045 SkAutoTDelete<SkBBHFactory> factory;
mtklein5ad6ee12014-08-11 08:08:43 -070046 switch (fBBH) {
47 case kNone_BBH: break;
48 case kRTree_BBH:
mtkleine4636aa2014-07-09 13:10:58 -070049 factory.reset(SkNEW(SkRTreeFactory));
50 break;
mtkleine4636aa2014-07-09 13:10:58 -070051 }
52
53 // A couple GMs draw wrong when using a bounding box hierarchy.
54 // This almost certainly means we have a bug to fix, but for now
55 // just draw without a bounding box hierarchy.
56 if (fGM->getFlags() & skiagm::GM::kNoBBH_Flag) {
57 factory.reset(NULL);
58 }
59
mtkleina9ceaf52014-09-29 08:44:46 -070060 SkAutoTUnref<const SkPicture> recorded(RecordPicture(fGM.get(), factory.get()));
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000061
62 SkBitmap full;
commit-bot@chromium.org26642072014-05-15 17:33:31 +000063 AllocatePixels(fReference, &full);
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000064
mtkleine4636aa2014-07-09 13:10:58 -070065 if (fGM->getFlags() & skiagm::GM::kSkipTiled_Flag) {
66 // Some GMs don't draw exactly the same when tiled. Draw them in one go.
67 SkCanvas canvas(full);
robertphillipsc5ba71d2014-09-04 08:42:50 -070068 recorded->playback(&canvas);
mtkleine4636aa2014-07-09 13:10:58 -070069 canvas.flush();
70 } else {
71 // Draw tiles in parallel into the same bitmap, simulating aggressive impl-side painting.
mtkleine71cd542014-10-29 14:17:13 -070072 int xTiles = tiles_needed(full.width(), FLAGS_quiltTile),
73 yTiles = tiles_needed(full.height(), FLAGS_quiltTile);
74 SkTDArray<DrawTileArgs> args;
75 args.setCount(xTiles*yTiles);
76 for (int y = 0; y < yTiles; y++) {
77 for (int x = 0; x < xTiles; x++) {
78 DrawTileArgs arg = { x*FLAGS_quiltTile, y*FLAGS_quiltTile, recorded, &full };
79 args[y*xTiles + x] = arg;
mtkleine4636aa2014-07-09 13:10:58 -070080 }
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000081 }
mtkleine71cd542014-10-29 14:17:13 -070082 SkTaskGroup().batch(draw_tile, args.begin(), args.count());
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000083 }
84
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000085 if (!BitmapsEqual(full, fReference)) {
86 this->fail();
mtkleinea65bfa2014-09-09 07:59:46 -070087 this->spawnChild(SkNEW_ARGS(WriteTask, (*this, "GM", full)));
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000088 }
89}
90
91bool QuiltTask::shouldSkip() const {
92 if (fGM->getFlags() & skiagm::GM::kSkipPicture_Flag) {
93 return true;
94 }
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000095 return !FLAGS_quilt;
96}
97
98} // namespace DM