• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 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 #include "gm.h"
8 #include "sk_tool_utils.h"
9 
10 #include "SkBitmap.h"
11 #include "SkPaint.h"
12 #include "SkShader.h"
13 #include "GrContext.h"
14 
15 namespace skiagm {
16 
draw_bm(SkBitmap * bm)17 static void draw_bm(SkBitmap* bm) {
18     SkPaint bluePaint;
19     bluePaint.setColor(SK_ColorBLUE);
20 
21     bm->allocN32Pixels(20, 20);
22     bm->eraseColor(SK_ColorRED);
23 
24     SkCanvas canvas(*bm);
25     canvas.drawCircle(10, 10, 5, bluePaint);
26 }
27 
draw_mask(SkBitmap * bm)28 static void draw_mask(SkBitmap* bm) {
29     SkPaint circlePaint;
30     circlePaint.setColor(SK_ColorBLACK);
31 
32     bm->allocPixels(SkImageInfo::MakeA8(20, 20));
33     bm->eraseColor(SK_ColorTRANSPARENT);
34 
35     SkCanvas canvas(*bm);
36     canvas.drawCircle(10, 10, 10, circlePaint);
37 }
38 
39 class BitmapShaderGM : public GM {
40 
41 protected:
onOnceBeforeDraw()42     void onOnceBeforeDraw() override {
43         this->setBGColor(sk_tool_utils::color_to_565(SK_ColorGRAY));
44         draw_bm(&fBitmap);
45         draw_mask(&fMask);
46     }
47 
onShortName()48     SkString onShortName() override {
49         return SkString("bitmapshaders");
50     }
51 
onISize()52     SkISize onISize() override {
53         return SkISize::Make(150, 100);
54     }
55 
onDraw(SkCanvas * canvas)56     void onDraw(SkCanvas* canvas) override {
57         SkPaint paint;
58 
59         for (int i = 0; i < 2; i++) {
60             SkMatrix s;
61             s.reset();
62             if (1 == i) {
63                 s.setScale(1.5f, 1.5f);
64                 s.postTranslate(2, 2);
65             }
66 
67             canvas->save();
68             paint.setShader(SkShader::MakeBitmapShader(fBitmap, SkShader::kClamp_TileMode,
69                                                        SkShader::kClamp_TileMode, &s));
70 
71             // draw the shader with a bitmap mask
72             canvas->drawBitmap(fMask, 0, 0, &paint);
73             canvas->drawBitmap(fMask, 30, 0, &paint);
74 
75             canvas->translate(0, 25);
76 
77             canvas->drawCircle(10, 10, 10, paint);
78             canvas->drawCircle(40, 10, 10, paint); // no blue circle expected
79 
80             canvas->translate(0, 25);
81 
82             // clear the shader, colorized by a solid color with a bitmap mask
83             paint.setShader(nullptr);
84             paint.setColor(SK_ColorGREEN);
85             canvas->drawBitmap(fMask, 0, 0, &paint);
86             canvas->drawBitmap(fMask, 30, 0, &paint);
87 
88             canvas->translate(0, 25);
89 
90             paint.setShader(SkShader::MakeBitmapShader(fMask, SkShader::kRepeat_TileMode,
91                                                        SkShader::kRepeat_TileMode, &s));
92             paint.setColor(SK_ColorRED);
93 
94             // draw the mask using the shader and a color
95             canvas->drawRect(SkRect::MakeXYWH(0, 0, 20, 20), paint);
96             canvas->drawRect(SkRect::MakeXYWH(30, 0, 20, 20), paint);
97             canvas->restore();
98             canvas->translate(60, 0);
99         }
100     }
101 
102 private:
103     SkBitmap fBitmap;
104     SkBitmap fMask;
105 
106     typedef GM INHERITED;
107 };
108 
109 DEF_SIMPLE_GM(hugebitmapshader, canvas, 100, 100) {
110     SkPaint paint;
111     SkBitmap bitmap;
112 
113     // The huge height will exceed GL_MAX_TEXTURE_SIZE. We test that the GL backend will at least
114     // draw something with a default paint instead of drawing nothing.
115     //
116     // (See https://skia-review.googlesource.com/c/skia/+/73200)
117     int bitmapW = 1;
118     int bitmapH = 60000;
119     if (auto* ctx = canvas->getGrContext()) {
120         bitmapH = ctx->caps()->maxTextureSize() + 1;
121     }
122     bitmap.setInfo(SkImageInfo::MakeA8(bitmapW, bitmapH), bitmapW);
123     uint8_t* pixels = new uint8_t[bitmapH];
124     for(int i = 0; i < bitmapH; ++i) {
125         pixels[i] = i & 0xff;
126     }
127     bitmap.setPixels(pixels);
128 
129     paint.setShader(SkShader::MakeBitmapShader(bitmap,
130              SkShader::kMirror_TileMode, SkShader::kMirror_TileMode));
131     paint.setColor(SK_ColorRED);
132     paint.setAntiAlias(true);
133     canvas->drawCircle(50, 50, 50, paint);
134     delete [] pixels;
135 }
136 
137 //////////////////////////////////////////////////////////////////////////////
138 
MyFactory(void *)139 static GM* MyFactory(void*) { return new BitmapShaderGM; }
140 static GMRegistry reg(MyFactory);
141 
142 }
143