129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips/*
229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips * Copyright 2015 Google Inc.
329ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips *
429ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips * Use of this source code is governed by a BSD-style license that can be
529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips * found in the LICENSE file.
629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips */
729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips#include "gm.h"
933d2055e594177b27360f84e0631b26d74a55a9bMike Klein#include "sk_tool_utils.h"
1029ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips#include "SkCanvas.h"
1129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips#include "SkRSXform.h"
1229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips#include "SkSurface.h"
1329ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
1429ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips// Create a square atlas of:
1529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips//   opaque white  |     opaque red
1629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips//  ------------------------------------
1729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips//   opaque green  |  transparent black
1829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips//
199ce9d6772df650ceb0511f275e1a83dffa78ff72reedstatic sk_sp<SkImage> make_atlas(SkCanvas* caller, int atlasSize) {
2029ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    const int kBlockSize = atlasSize/2;
2129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
2229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize);
2346596ae50559e89a0a2462573ac9448cf309cf56Mike Reed    auto surface(sk_tool_utils::makeSurface(caller, info));
2429ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    SkCanvas* canvas = surface->getCanvas();
2529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
2629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    SkPaint paint;
27374772bd61951f01bf84fe17bf53d8867681c9aereed    paint.setBlendMode(SkBlendMode::kSrc);
2829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
2929ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    paint.setColor(SK_ColorWHITE);
309d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    SkRect r = SkRect::MakeXYWH(0, 0,
3129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips                                SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
3229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    canvas->drawRect(r, paint);
3329ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
3429ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    paint.setColor(SK_ColorRED);
359d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), 0,
3629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
3729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    canvas->drawRect(r, paint);
3829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
3929ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    paint.setColor(SK_ColorGREEN);
409d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    r = SkRect::MakeXYWH(0, SkIntToScalar(kBlockSize),
4129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
4229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    canvas->drawRect(r, paint);
4329ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
4429ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    paint.setColor(SK_ColorTRANSPARENT);
459d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize),
4629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
4729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    canvas->drawRect(r, paint);
4829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
499ce9d6772df650ceb0511f275e1a83dffa78ff72reed    return surface->makeImageSnapshot();
5029ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips}
5129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
5229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips// This GM tests the drawAtlas API with colors, different xfer modes
5329ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips// and transparency in the atlas image
5429ccdf86ab0a1649fd775c9431891bacb1391e99robertphillipsclass DrawAtlasColorsGM : public skiagm::GM {
5529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillipspublic:
5629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    DrawAtlasColorsGM() {
5729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
5829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    }
599d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
6029ccdf86ab0a1649fd775c9431891bacb1391e99robertphillipsprotected:
6129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    SkString onShortName() override {
6229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        return SkString("draw-atlas-colors");
6329ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    }
649d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
6529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    SkISize onISize() override {
6629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        return SkISize::Make(kNumXferModes * (kAtlasSize + kPad) + kPad,
6729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips                             2 * kNumColors * (kAtlasSize + kPad) + kTextPad + kPad);
6829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    }
699d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
7029ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    void onDraw(SkCanvas* canvas) override {
7129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        const SkRect target = SkRect::MakeWH(SkIntToScalar(kAtlasSize), SkIntToScalar(kAtlasSize));
7229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
7395e8d0a4ae3c755fd9ffbd0c276fc657999feceebrianosman        auto atlas = make_atlas(canvas, kAtlasSize);
7429ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
75d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman        const SkBlendMode gModes[] = {
76d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kClear,
77d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kSrc,
78d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kDst,
79d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kSrcOver,
80d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kDstOver,
81d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kSrcIn,
82d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kDstIn,
83d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kSrcOut,
84d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kDstOut,
85d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kSrcATop,
86d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kDstATop,
87d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kXor,
88d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kPlus,
89d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kModulate,
90d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kScreen,
91d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kOverlay,
92d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kDarken,
93d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kLighten,
94d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kColorDodge,
95d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kColorBurn,
96d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kHardLight,
97d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kSoftLight,
98d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kDifference,
99d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kExclusion,
100d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kMultiply,
101d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kHue,
102d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kSaturation,
103d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kColor,
104d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            SkBlendMode::kLuminosity,
10529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        };
10629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
10729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        SkColor gColors[] = {
10829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            SK_ColorWHITE,
10929ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            SK_ColorRED,
11029ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            0x88888888,         // transparent grey
11129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            0x88000088          // transparent blue
11229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        };
11329ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
11429ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        const int numModes = SK_ARRAY_COUNT(gModes);
11529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        SkASSERT(numModes == kNumXferModes);
11629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        const int numColors = SK_ARRAY_COUNT(gColors);
11729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        SkASSERT(numColors == kNumColors);
11829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        SkRSXform xforms[numColors];
11929ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        SkRect rects[numColors];
12029ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        SkColor quadColors[numColors];
12129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
12229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        SkPaint paint;
12329ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        paint.setAntiAlias(true);
12429ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
12529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        for (int i = 0; i < numColors; ++i) {
12629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            xforms[i].set(1.0f, 0.0f, SkIntToScalar(kPad), i*(target.width()+kPad));
12729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            rects[i] = target;
12829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            quadColors[i] = gColors[i];
12929ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        }
13029ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
13129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        SkPaint textP;
13229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        textP.setTextSize(SkIntToScalar(kTextPad));
13329ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        textP.setAntiAlias(true);
13496fcdcc219d2a0d3579719b84b28bede76efba64halcanary        sk_tool_utils::set_portable_typeface(&textP, nullptr);
13529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
13629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        for (int i = 0; i < numModes; ++i) {
137d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman            const char* label = SkBlendMode_Name(gModes[i]);
1382a475eae622adc1e8fa29206be1eaf862c23548eCary Clark            canvas->drawString(label,
13929ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips                             i*(target.width()+kPad)+kPad, SkIntToScalar(kTextPad),
14029ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips                             textP);
14129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        }
14229ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
14329ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        for (int i = 0; i < numModes; ++i) {
1449d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary            canvas->save();
14529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            canvas->translate(SkIntToScalar(i*(target.height()+kPad)),
14629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips                              SkIntToScalar(kTextPad+kPad));
14729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            // w/o a paint
14895e8d0a4ae3c755fd9ffbd0c276fc657999feceebrianosman            canvas->drawAtlas(atlas.get(), xforms, rects, quadColors, numColors,
149d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman                              gModes[i], nullptr, nullptr);
15029ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            canvas->translate(0.0f, numColors*(target.height()+kPad));
15129ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips            // w a paint
15295e8d0a4ae3c755fd9ffbd0c276fc657999feceebrianosman            canvas->drawAtlas(atlas.get(), xforms, rects, quadColors, numColors,
153d1e67e70ae566bd841a2926eb07446ad99c64e59Brian Osman                              gModes[i], nullptr, &paint);
1549d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary            canvas->restore();
15529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips        }
15629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    }
1579d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
15829ccdf86ab0a1649fd775c9431891bacb1391e99robertphillipsprivate:
159dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein    static constexpr int kNumXferModes = 29;
160dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein    static constexpr int kNumColors = 4;
161dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein    static constexpr int kAtlasSize = 30;
162dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein    static constexpr int kPad = 2;
163dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein    static constexpr int kTextPad = 8;
16429ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips
16529ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips    typedef GM INHERITED;
16629ccdf86ab0a1649fd775c9431891bacb1391e99robertphillips};
16729ccdf86ab0a1649fd775c9431891bacb1391e99robertphillipsDEF_GM( return new DrawAtlasColorsGM; )
168