perspshaders.cpp revision dbfd7ab10883f173f5c1b653a233e18dc6142002
1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm.h"
9#include "SkGradientShader.h"
10#include "SkImage.h"
11#include "SkPath.h"
12#include "SkSurface.h"
13
14static sk_sp<SkImage> make_image(SkCanvas* origCanvas, int w, int h) {
15    SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);
16    auto surface(origCanvas->makeSurface(info));
17    if (nullptr == surface) {
18        surface = SkSurface::MakeRaster(info);
19    }
20    SkCanvas* canvas = surface->getCanvas();
21
22    sk_tool_utils::draw_checkerboard(canvas, SK_ColorRED, SK_ColorGREEN, w/10);
23    return surface->makeImageSnapshot();
24}
25
26namespace skiagm {
27
28class PerspShadersGM : public GM {
29public:
30    PerspShadersGM(bool doAA) : fDoAA(doAA) { }
31
32protected:
33    SkString onShortName() override {
34        SkString name;
35        name.printf("persp_shaders_%s",
36                     fDoAA ? "aa" : "bw");
37        return name;
38    }
39
40    SkISize onISize() override {
41        return SkISize::Make(kCellSize*kNumCols, kCellSize*kNumRows);
42    }
43
44    void onOnceBeforeDraw() override {
45        fBitmap = sk_tool_utils::create_checkerboard_bitmap(kCellSize, kCellSize,
46                                                            SK_ColorBLUE, SK_ColorYELLOW,
47                                                            kCellSize/10);
48
49        fBitmapShader = SkShader::MakeBitmapShader(fBitmap, SkShader::kClamp_TileMode,
50                                                   SkShader::kClamp_TileMode);
51        SkPoint pts1[] = {
52            { 0, 0 },
53            { SkIntToScalar(kCellSize), SkIntToScalar(kCellSize) }
54        };
55        SkPoint pts2[] = {
56            { 0, 0 },
57            { 0, SkIntToScalar(kCellSize) }
58        };
59        constexpr SkColor colors[] = {
60            SK_ColorRED, SK_ColorGREEN, SK_ColorRED, SK_ColorGREEN, SK_ColorRED
61        };
62        constexpr SkScalar pos[] = { 0, 0.25f, 0.5f, 0.75f, SK_Scalar1 };
63
64        fLinearGrad1 = SkGradientShader::MakeLinear(pts1, colors, pos, SK_ARRAY_COUNT(colors),
65                                                    SkShader::kClamp_TileMode);
66        fLinearGrad2 = SkGradientShader::MakeLinear(pts2, colors, pos, SK_ARRAY_COUNT(colors),
67                                                    SkShader::kClamp_TileMode);
68
69        fPerspMatrix.reset();
70        fPerspMatrix.setPerspY(SK_Scalar1 / 50);
71
72        fPath.moveTo(0, 0);
73        fPath.lineTo(0, SkIntToScalar(kCellSize));
74        fPath.lineTo(kCellSize/2.0f, kCellSize/2.0f);
75        fPath.lineTo(SkIntToScalar(kCellSize), SkIntToScalar(kCellSize));
76        fPath.lineTo(SkIntToScalar(kCellSize), 0);
77        fPath.close();
78    }
79
80    void drawRow(SkCanvas* canvas, SkFilterQuality filterQ) {
81        SkPaint filterPaint;
82        filterPaint.setFilterQuality(filterQ);
83        filterPaint.setAntiAlias(fDoAA);
84
85        SkPaint pathPaint;
86        pathPaint.setShader(fBitmapShader);
87        pathPaint.setFilterQuality(filterQ);
88        pathPaint.setAntiAlias(fDoAA);
89
90        SkPaint gradPaint1;
91        gradPaint1.setShader(fLinearGrad1);
92        gradPaint1.setAntiAlias(fDoAA);
93        SkPaint gradPaint2;
94        gradPaint2.setShader(fLinearGrad2);
95        gradPaint2.setAntiAlias(fDoAA);
96
97        SkRect r = SkRect::MakeWH(SkIntToScalar(kCellSize), SkIntToScalar(kCellSize));
98
99        canvas->save();
100
101        canvas->save();
102        canvas->concat(fPerspMatrix);
103        canvas->drawBitmapRect(fBitmap, r, &filterPaint);
104        canvas->restore();
105
106        canvas->translate(SkIntToScalar(kCellSize), 0);
107        canvas->save();
108        canvas->concat(fPerspMatrix);
109        canvas->drawImage(fImage.get(), 0, 0, &filterPaint);
110        canvas->restore();
111
112        canvas->translate(SkIntToScalar(kCellSize), 0);
113        canvas->save();
114        canvas->concat(fPerspMatrix);
115        canvas->drawRect(r, pathPaint);
116        canvas->restore();
117
118        canvas->translate(SkIntToScalar(kCellSize), 0);
119        canvas->save();
120        canvas->concat(fPerspMatrix);
121        canvas->drawPath(fPath, pathPaint);
122        canvas->restore();
123
124        canvas->translate(SkIntToScalar(kCellSize), 0);
125        canvas->save();
126        canvas->concat(fPerspMatrix);
127        canvas->drawRect(r, gradPaint1);
128        canvas->restore();
129
130        canvas->translate(SkIntToScalar(kCellSize), 0);
131        canvas->save();
132        canvas->concat(fPerspMatrix);
133        canvas->drawPath(fPath, gradPaint2);
134        canvas->restore();
135
136        canvas->restore();
137    }
138
139    void onDraw(SkCanvas* canvas) override {
140        if (!fImage) {
141            fImage = make_image(canvas, kCellSize, kCellSize);
142        }
143
144        this->drawRow(canvas, kNone_SkFilterQuality);
145        canvas->translate(0, SkIntToScalar(kCellSize));
146        this->drawRow(canvas, kLow_SkFilterQuality);
147        canvas->translate(0, SkIntToScalar(kCellSize));
148        this->drawRow(canvas, kMedium_SkFilterQuality);
149        canvas->translate(0, SkIntToScalar(kCellSize));
150        this->drawRow(canvas, kHigh_SkFilterQuality);
151        canvas->translate(0, SkIntToScalar(kCellSize));
152    }
153private:
154    static constexpr int kCellSize = 50;
155    static constexpr int kNumRows = 4;
156    static constexpr int kNumCols = 6;
157
158    bool            fDoAA;
159    SkPath          fPath;
160    sk_sp<SkShader> fBitmapShader;
161    sk_sp<SkShader> fLinearGrad1;
162    sk_sp<SkShader> fLinearGrad2;
163    SkMatrix        fPerspMatrix;
164    sk_sp<SkImage>  fImage;
165    SkBitmap        fBitmap;
166
167    typedef GM INHERITED;
168};
169
170//////////////////////////////////////////////////////////////////////////////
171
172DEF_GM(return new PerspShadersGM(true);)
173DEF_GM(return new PerspShadersGM(false);)
174}
175