• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
draw_something(SkCanvas * canvas,const SkRect & bounds)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 
make_raster(GrContext *,SkPicture * pic,const SkImageInfo & info)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 
make_texture(GrContext * ctx,SkPicture * pic,const SkImageInfo & info)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 
make_pict_gen(GrContext *,SkPicture * pic,const SkImageInfo & info)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 
make_encode_gen(GrContext * ctx,SkPicture * pic,const SkImageInfo & info)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:
ImageShaderGM()82     ImageShaderGM() {}
83 
84 protected:
onShortName()85     SkString onShortName() override {
86         return SkString("image-shader");
87     }
88 
onISize()89     SkISize onISize() override {
90         return SkISize::Make(850, 450);
91     }
92 
onOnceBeforeDraw()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 
testImage(SkCanvas * canvas,SkImage * image)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 
onDraw(SkCanvas * canvas)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