1#include "DMPipeTask.h"
2#include "DMUtil.h"
3#include "DMWriteTask.h"
4
5#include "SamplePipeControllers.h"
6#include "SkCommandLineFlags.h"
7#include "SkGPipe.h"
8
9DEFINE_bool(pipe, true, "If true, check several pipe variants against the reference bitmap.");
10
11namespace DM {
12
13static uint32_t get_flags(PipeTask::Mode mode) {
14    uint32_t flags = 0;
15    if (mode != PipeTask::kInProcess_Mode) {
16        flags |= SkGPipeWriter::kCrossProcess_Flag;
17    }
18    if (mode == PipeTask::kSharedAddress_Mode) {
19        flags |= SkGPipeWriter::kSharedAddressSpace_Flag;
20    }
21    return flags;
22}
23
24static const char* get_name(const uint32_t flags) {
25    if (flags & SkGPipeWriter::kCrossProcess_Flag &&
26        flags & SkGPipeWriter::kSharedAddressSpace_Flag) {
27        return "shared_address_space_pipe";
28    } else if (flags & SkGPipeWriter::kCrossProcess_Flag) {
29        return "cross_process_pipe";
30    } else {
31        return "pipe";
32    }
33}
34
35PipeTask::PipeTask(const Task& parent,
36                   skiagm::GM* gm,
37                   SkBitmap reference,
38                   Mode mode)
39    : CpuTask(parent)
40    , fFlags(get_flags(mode))
41    , fName(UnderJoin(parent.name().c_str(), get_name(fFlags)))
42    , fGM(gm)
43    , fReference(reference)
44    {}
45
46void PipeTask::draw() {
47    SkBitmap bitmap;
48    AllocatePixels(fReference, &bitmap);
49
50    SkCanvas canvas(bitmap);
51    PipeController pipeController(&canvas, &SkImageDecoder::DecodeMemory);
52    SkGPipeWriter writer;
53
54    SkCanvas* pipeCanvas = writer.startRecording(&pipeController,
55                                                 fFlags,
56                                                 bitmap.width(),
57                                                 bitmap.height());
58    pipeCanvas->concat(fGM->getInitialTransform());
59    fGM->draw(pipeCanvas);
60    writer.endRecording();
61
62    if (!BitmapsEqual(bitmap, fReference)) {
63        this->fail();
64        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
65    }
66}
67
68bool PipeTask::shouldSkip() const {
69    if (!FLAGS_pipe) {
70        return true;
71    }
72    if (fGM->getFlags() & skiagm::GM::kSkipPipe_Flag) {
73        return true;
74    }
75    if (fFlags == SkGPipeWriter::kCrossProcess_Flag &&
76        fGM->getFlags() & skiagm::GM::kSkipPipeCrossProcess_Flag) {
77        return true;
78    }
79    return false;
80}
81
82}  // namespace DM
83