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