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 "SkCanvas.h" 10 #include "SkData.h" 11 #include "SkImage.h" 12 #include "SkPictureRecorder.h" 13 #include "SkSurface.h" 14 15 static void draw_something(SkCanvas* canvas, const SkRect& bounds) { 16 SkPaint paint; 17 paint.setAntiAlias(true); 18 paint.setColor(SK_ColorRED); 19 paint.setStyle(SkPaint::kStroke_Style); 20 paint.setStrokeWidth(10); 21 canvas->drawRect(bounds, paint); 22 paint.setStyle(SkPaint::kFill_Style); 23 paint.setColor(SK_ColorBLUE); 24 canvas->drawOval(bounds, paint); 25 } 26 27 typedef sk_sp<SkImage> (*ImageMakerProc)(GrContext*, SkPicture*, const SkImageInfo&); 28 29 static sk_sp<SkImage> make_raster(GrContext*, SkPicture* pic, const SkImageInfo& info) { 30 auto surface(SkSurface::MakeRaster(info)); 31 surface->getCanvas()->clear(0); 32 surface->getCanvas()->drawPicture(pic); 33 return surface->makeImageSnapshot(); 34 } 35 36 static sk_sp<SkImage> make_texture(GrContext* ctx, SkPicture* pic, const SkImageInfo& info) { 37 if (!ctx) { 38 return nullptr; 39 } 40 auto surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info)); 41 if (!surface) { 42 return nullptr; 43 } 44 surface->getCanvas()->clear(0); 45 surface->getCanvas()->drawPicture(pic); 46 return surface->makeImageSnapshot(); 47 } 48 49 static sk_sp<SkImage> make_pict_gen(GrContext*, SkPicture* pic, const SkImageInfo& info) { 50 return SkImage::MakeFromPicture(sk_ref_sp(pic), info.dimensions(), nullptr, nullptr, 51 SkImage::BitDepth::kU8, 52 SkColorSpace::MakeSRGB()); 53 } 54 55 static sk_sp<SkImage> make_encode_gen(GrContext* ctx, SkPicture* pic, const SkImageInfo& info) { 56 sk_sp<SkImage> src(make_raster(ctx, pic, info)); 57 if (!src) { 58 return nullptr; 59 } 60 sk_sp<SkData> encoded = src->encodeToData(SkEncodedImageFormat::kPNG, 100); 61 if (!encoded) { 62 return nullptr; 63 } 64 return SkImage::MakeFromEncoded(std::move(encoded)); 65 } 66 67 const ImageMakerProc gProcs[] = { 68 make_raster, 69 make_texture, 70 make_pict_gen, 71 make_encode_gen, 72 }; 73 74 /* 75 * Exercise drawing pictures inside an image, showing that the image version is pixelated 76 * (correctly) when it is inside an image. 77 */ 78 class ImageShaderGM : public skiagm::GM { 79 sk_sp<SkPicture> fPicture; 80 81 public: 82 ImageShaderGM() {} 83 84 protected: 85 SkString onShortName() override { 86 return SkString("image-shader"); 87 } 88 89 SkISize onISize() override { 90 return SkISize::Make(850, 450); 91 } 92 93 void onOnceBeforeDraw() override { 94 const SkRect bounds = SkRect::MakeWH(100, 100); 95 SkPictureRecorder recorder; 96 draw_something(recorder.beginRecording(bounds), bounds); 97 fPicture = recorder.finishRecordingAsPicture(); 98 } 99 100 void testImage(SkCanvas* canvas, SkImage* image) { 101 SkAutoCanvasRestore acr(canvas, true); 102 103 canvas->drawImage(image, 0, 0); 104 canvas->translate(0, 120); 105 106 const SkShader::TileMode tile = SkShader::kRepeat_TileMode; 107 const SkMatrix localM = SkMatrix::MakeTrans(-50, -50); 108 SkPaint paint; 109 paint.setShader(image->makeShader(tile, tile, &localM)); 110 paint.setAntiAlias(true); 111 canvas->drawCircle(50, 50, 50, paint); 112 } 113 114 void onDraw(SkCanvas* canvas) override { 115 canvas->translate(20, 20); 116 117 const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100); 118 119 for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) { 120 sk_sp<SkImage> image(gProcs[i](canvas->getGrContext(), fPicture.get(), info)); 121 if (image) { 122 this->testImage(canvas, image.get()); 123 } 124 canvas->translate(120, 0); 125 } 126 } 127 128 private: 129 typedef skiagm::GM INHERITED; 130 }; 131 DEF_GM( return new ImageShaderGM; ) 132