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 SkImage* (*ImageMakerProc)(GrContext*, const SkPicture*, const SkImageInfo&); 28 29 static SkImage* make_raster(GrContext*, const SkPicture* pic, const SkImageInfo& info) { 30 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info)); 31 surface->getCanvas()->clear(0); 32 surface->getCanvas()->drawPicture(pic); 33 return surface->newImageSnapshot(); 34 } 35 36 static SkImage* make_texture(GrContext* ctx, const SkPicture* pic, const SkImageInfo& info) { 37 if (!ctx) { 38 return nullptr; 39 } 40 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkBudgeted::kNo, 41 info, 0)); 42 surface->getCanvas()->clear(0); 43 surface->getCanvas()->drawPicture(pic); 44 return surface->newImageSnapshot(); 45 } 46 47 static SkImage* make_pict_gen(GrContext*, const SkPicture* pic, const SkImageInfo& info) { 48 return SkImage::NewFromPicture(pic, info.dimensions(), nullptr, nullptr); 49 } 50 51 static SkImage* make_encode_gen(GrContext* ctx, const SkPicture* pic, const SkImageInfo& info) { 52 SkAutoTUnref<SkImage> src(make_raster(ctx, pic, info)); 53 if (!src) { 54 return nullptr; 55 } 56 SkAutoTUnref<SkData> encoded(src->encode(SkImageEncoder::kPNG_Type, 100)); 57 if (!encoded) { 58 return nullptr; 59 } 60 return SkImage::NewFromEncoded(encoded); 61 } 62 63 const ImageMakerProc gProcs[] = { 64 make_raster, 65 make_texture, 66 make_pict_gen, 67 make_encode_gen, 68 }; 69 70 /* 71 * Exercise drawing pictures inside an image, showing that the image version is pixelated 72 * (correctly) when it is inside an image. 73 */ 74 class ImageShaderGM : public skiagm::GM { 75 SkAutoTUnref<SkPicture> fPicture; 76 77 public: 78 ImageShaderGM() {} 79 80 protected: 81 SkString onShortName() override { 82 return SkString("image-shader"); 83 } 84 85 SkISize onISize() override { 86 return SkISize::Make(850, 450); 87 } 88 89 void onOnceBeforeDraw() override { 90 const SkRect bounds = SkRect::MakeWH(100, 100); 91 SkPictureRecorder recorder; 92 draw_something(recorder.beginRecording(bounds), bounds); 93 fPicture.reset(recorder.endRecording()); 94 } 95 96 void testImage(SkCanvas* canvas, SkImage* image) { 97 SkAutoCanvasRestore acr(canvas, true); 98 99 canvas->drawImage(image, 0, 0); 100 canvas->translate(0, 120); 101 102 const SkShader::TileMode tile = SkShader::kRepeat_TileMode; 103 const SkMatrix localM = SkMatrix::MakeTrans(-50, -50); 104 SkAutoTUnref<SkShader> shader(image->newShader(tile, tile, &localM)); 105 SkPaint paint; 106 paint.setAntiAlias(true); 107 paint.setShader(shader); 108 canvas->drawCircle(50, 50, 50, paint); 109 } 110 111 void onDraw(SkCanvas* canvas) override { 112 canvas->translate(20, 20); 113 114 const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100); 115 116 for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) { 117 SkAutoTUnref<SkImage> image(gProcs[i](canvas->getGrContext(), fPicture, info)); 118 if (image) { 119 this->testImage(canvas, image); 120 } 121 canvas->translate(120, 0); 122 } 123 } 124 125 private: 126 typedef skiagm::GM INHERITED; 127 }; 128 DEF_GM( return new ImageShaderGM; ) 129 130