1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2015 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gm.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "sk_tool_utils.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRSXform.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Create a square atlas of:
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//   opaque white  |     opaque red
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//  ------------------------------------
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//   opaque green  |  transparent black
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkImage> make_atlas(SkCanvas* caller, int atlasSize) {
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const int kBlockSize = atlasSize/2;
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize);
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto surface(sk_tool_utils::makeSurface(caller, info));
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkCanvas* canvas = surface->getCanvas();
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint;
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setBlendMode(SkBlendMode::kSrc);
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorWHITE);
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRect r = SkRect::MakeXYWH(0, 0,
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(r, paint);
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorRED);
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), 0,
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(r, paint);
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorGREEN);
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r = SkRect::MakeXYWH(0, SkIntToScalar(kBlockSize),
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(r, paint);
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(SK_ColorTRANSPARENT);
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize),
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(r, paint);
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return surface->makeImageSnapshot();
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This GM tests the drawAtlas API with colors, different xfer modes
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// and transparency in the atlas image
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass DrawAtlasColorsGM : public skiagm::GM {
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    DrawAtlasColorsGM() {
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString onShortName() override {
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkString("draw-atlas-colors");
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkISize onISize() override {
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkISize::Make(kNumXferModes * (kAtlasSize + kPad) + kPad,
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                             2 * kNumColors * (kAtlasSize + kPad) + kTextPad + kPad);
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDraw(SkCanvas* canvas) override {
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkRect target = SkRect::MakeWH(SkIntToScalar(kAtlasSize), SkIntToScalar(kAtlasSize));
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        auto atlas = make_atlas(canvas, kAtlasSize);
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkBlendMode gModes[] = {
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kClear,
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kSrc,
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kDst,
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kSrcOver,
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kDstOver,
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kSrcIn,
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kDstIn,
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kSrcOut,
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kDstOut,
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kSrcATop,
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kDstATop,
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kXor,
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kPlus,
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kModulate,
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kScreen,
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kOverlay,
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kDarken,
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kLighten,
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kColorDodge,
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kColorBurn,
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kHardLight,
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kSoftLight,
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kDifference,
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kExclusion,
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kMultiply,
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kHue,
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kSaturation,
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kColor,
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBlendMode::kLuminosity,
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkColor gColors[] = {
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SK_ColorWHITE,
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SK_ColorRED,
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0x88888888,         // transparent grey
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0x88000088          // transparent blue
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const int numModes = SK_ARRAY_COUNT(gModes);
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(numModes == kNumXferModes);
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const int numColors = SK_ARRAY_COUNT(gColors);
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(numColors == kNumColors);
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRSXform xforms[numColors];
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect rects[numColors];
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkColor quadColors[numColors];
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setAntiAlias(true);
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < numColors; ++i) {
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            xforms[i].set(1.0f, 0.0f, SkIntToScalar(kPad), i*(target.width()+kPad));
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            rects[i] = target;
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            quadColors[i] = gColors[i];
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint textP;
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        textP.setTextSize(SkIntToScalar(kTextPad));
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        textP.setAntiAlias(true);
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_tool_utils::set_portable_typeface(&textP, nullptr);
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < numModes; ++i) {
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* label = SkBlendMode_Name(gModes[i]);
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->drawString(label,
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                             i*(target.width()+kPad)+kPad, SkIntToScalar(kTextPad),
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                             textP);
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < numModes; ++i) {
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->save();
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->translate(SkIntToScalar(i*(target.height()+kPad)),
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              SkIntToScalar(kTextPad+kPad));
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // w/o a paint
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->drawAtlas(atlas.get(), xforms, rects, quadColors, numColors,
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              gModes[i], nullptr, nullptr);
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->translate(0.0f, numColors*(target.height()+kPad));
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // w a paint
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->drawAtlas(atlas.get(), xforms, rects, quadColors, numColors,
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              gModes[i], nullptr, &paint);
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->restore();
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int kNumXferModes = 29;
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int kNumColors = 4;
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int kAtlasSize = 30;
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int kPad = 2;
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int kTextPad = 8;
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GM INHERITED;
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new DrawAtlasColorsGM; )
168