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 "SkColorPriv.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGradientShader.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImage.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMathPriv.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRandom.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkShader.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkImage> makebm(int w, int h) {
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto surface(SkSurface::MakeRaster(info));
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkCanvas* canvas = surface->getCanvas();
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkScalar wScalar = SkIntToScalar(w);
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkScalar hScalar = SkIntToScalar(h);
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkPoint     pt = { wScalar / 2, hScalar / 2 };
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkScalar    radius = 4 * SkMaxScalar(wScalar, hScalar);
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    constexpr SkColor     colors[] = { SK_ColorRED, SK_ColorYELLOW,
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          SK_ColorGREEN, SK_ColorMAGENTA,
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          SK_ColorBLUE, SK_ColorCYAN,
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          SK_ColorRED};
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    constexpr SkScalar    pos[] = {0,
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      SK_Scalar1 / 6,
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      2 * SK_Scalar1 / 6,
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      3 * SK_Scalar1 / 6,
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      4 * SK_Scalar1 / 6,
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      5 * SK_Scalar1 / 6,
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      SK_Scalar1};
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(SK_ARRAY_COUNT(colors) == SK_ARRAY_COUNT(pos));
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint     paint;
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRect rect = SkRect::MakeWH(wScalar, hScalar);
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkMatrix mat = SkMatrix::I();
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 4; ++i) {
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setShader(SkGradientShader::MakeRadial(
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        pt, radius,
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        colors, pos,
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SK_ARRAY_COUNT(colors),
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkShader::kRepeat_TileMode,
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        0, &mat));
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(rect, paint);
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        rect.inset(wScalar / 8, hScalar / 8);
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        mat.postScale(SK_Scalar1 / 4, SK_Scalar1 / 4);
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return surface->makeImageSnapshot();
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr int gSize = 1024;
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr int gSurfaceSize = 2048;
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This GM calls drawImageRect several times using the same texture. This is intended to exercise
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// combining GrDrawOps during these calls.
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass DrawMiniBitmapRectGM : public skiagm::GM {
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    DrawMiniBitmapRectGM(bool antiAlias) : fAA(antiAlias) {
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fName.set("drawminibitmaprect");
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fAA) {
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fName.appendf("_aa");
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString onShortName() override { return fName; }
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkISize onISize() override { return SkISize::Make(gSize, gSize); }
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDraw(SkCanvas* canvas) override {
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (nullptr == fImage) {
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fImage = makebm(gSurfaceSize, gSurfaceSize);
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkRect dstRect = { 0, 0, SkIntToScalar(64), SkIntToScalar(64)};
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const int kMaxSrcRectSize = 1 << (SkNextLog2(gSurfaceSize) + 2);
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        constexpr int kPadX = 30;
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        constexpr int kPadY = 40;
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int rowCount = 0;
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->translate(SkIntToScalar(kPadX), SkIntToScalar(kPadY));
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->save();
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRandom random;
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setAntiAlias(fAA);
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int w = 1; w <= kMaxSrcRectSize; w *= 3) {
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int h = 1; h <= kMaxSrcRectSize; h *= 3) {
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                const SkIRect srcRect =
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkIRect::MakeXYWH((gSurfaceSize - w) / 2, (gSurfaceSize - h) / 2, w, h);
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->save();
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                switch (random.nextU() % 3) {
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case 0:
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        canvas->rotate(random.nextF() * 10.f);
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case 1:
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        canvas->rotate(-random.nextF() * 10.f);
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case 2:
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        // rect stays rect
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawImageRect(fImage.get(), srcRect, dstRect, &paint,
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      SkCanvas::kFast_SrcRectConstraint);
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->restore();
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->translate(dstRect.width() + SK_Scalar1 * kPadX, 0);
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                ++rowCount;
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if ((dstRect.width() + 2 * kPadX) * rowCount > gSize) {
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->restore();
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->translate(0, dstRect.height() + SK_Scalar1 * kPadY);
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->save();
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    rowCount = 0;
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->restore();
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool            fAA;
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkImage>  fImage;
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString        fName;
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef skiagm::GM INHERITED;
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new DrawMiniBitmapRectGM(true); )
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new DrawMiniBitmapRectGM(false); )
141