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