blob: cfce7a7ba0aaf84980e24585dadc335e5773fae9 [file] [log] [blame]
reed499abab2015-08-20 12:30:20 -07001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
9#include "include/core/SkCanvas.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040010#include "include/core/SkColor.h"
11#include "include/core/SkColorSpace.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkData.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040013#include "include/core/SkEncodedImageFormat.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkImage.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040015#include "include/core/SkImageInfo.h"
16#include "include/core/SkMatrix.h"
17#include "include/core/SkPaint.h"
18#include "include/core/SkPicture.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "include/core/SkPictureRecorder.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040020#include "include/core/SkRect.h"
21#include "include/core/SkRefCnt.h"
22#include "include/core/SkShader.h"
23#include "include/core/SkSize.h"
24#include "include/core/SkString.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "include/core/SkSurface.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040026#include "include/core/SkTileMode.h"
27#include "include/core/SkTypes.h"
28
29#include <utility>
30
31class GrContext;
reed499abab2015-08-20 12:30:20 -070032
33static void draw_something(SkCanvas* canvas, const SkRect& bounds) {
34 SkPaint paint;
35 paint.setAntiAlias(true);
36 paint.setColor(SK_ColorRED);
37 paint.setStyle(SkPaint::kStroke_Style);
38 paint.setStrokeWidth(10);
39 canvas->drawRect(bounds, paint);
40 paint.setStyle(SkPaint::kFill_Style);
41 paint.setColor(SK_ColorBLUE);
42 canvas->drawOval(bounds, paint);
43}
44
reed9ce9d672016-03-17 10:51:11 -070045typedef sk_sp<SkImage> (*ImageMakerProc)(GrContext*, SkPicture*, const SkImageInfo&);
reed499abab2015-08-20 12:30:20 -070046
reed9ce9d672016-03-17 10:51:11 -070047static sk_sp<SkImage> make_raster(GrContext*, SkPicture* pic, const SkImageInfo& info) {
reede8f30622016-03-23 18:59:25 -070048 auto surface(SkSurface::MakeRaster(info));
reed499abab2015-08-20 12:30:20 -070049 surface->getCanvas()->clear(0);
50 surface->getCanvas()->drawPicture(pic);
reed9ce9d672016-03-17 10:51:11 -070051 return surface->makeImageSnapshot();
reed499abab2015-08-20 12:30:20 -070052}
53
reed9ce9d672016-03-17 10:51:11 -070054static sk_sp<SkImage> make_texture(GrContext* ctx, SkPicture* pic, const SkImageInfo& info) {
reed499abab2015-08-20 12:30:20 -070055 if (!ctx) {
56 return nullptr;
57 }
reede8f30622016-03-23 18:59:25 -070058 auto surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info));
scroggoa1b28332016-05-12 06:19:37 -070059 if (!surface) {
60 return nullptr;
61 }
reed499abab2015-08-20 12:30:20 -070062 surface->getCanvas()->clear(0);
63 surface->getCanvas()->drawPicture(pic);
reed9ce9d672016-03-17 10:51:11 -070064 return surface->makeImageSnapshot();
reed499abab2015-08-20 12:30:20 -070065}
66
reed9ce9d672016-03-17 10:51:11 -070067static sk_sp<SkImage> make_pict_gen(GrContext*, SkPicture* pic, const SkImageInfo& info) {
Brian Osman138ea972016-12-16 11:55:18 -050068 return SkImage::MakeFromPicture(sk_ref_sp(pic), info.dimensions(), nullptr, nullptr,
Matt Sarette94255d2017-01-09 12:38:59 -050069 SkImage::BitDepth::kU8,
Matt Sarett77a7a1b2017-02-07 13:56:11 -050070 SkColorSpace::MakeSRGB());
reed499abab2015-08-20 12:30:20 -070071}
72
reed9ce9d672016-03-17 10:51:11 -070073static sk_sp<SkImage> make_encode_gen(GrContext* ctx, SkPicture* pic, const SkImageInfo& info) {
74 sk_sp<SkImage> src(make_raster(ctx, pic, info));
reed499abab2015-08-20 12:30:20 -070075 if (!src) {
76 return nullptr;
77 }
Mike Reed6409f842017-07-11 16:03:13 -040078 sk_sp<SkData> encoded = src->encodeToData(SkEncodedImageFormat::kPNG, 100);
reed499abab2015-08-20 12:30:20 -070079 if (!encoded) {
80 return nullptr;
81 }
reed9ce9d672016-03-17 10:51:11 -070082 return SkImage::MakeFromEncoded(std::move(encoded));
reed499abab2015-08-20 12:30:20 -070083}
84
85const ImageMakerProc gProcs[] = {
86 make_raster,
87 make_texture,
88 make_pict_gen,
89 make_encode_gen,
90};
91
92/*
93 * Exercise drawing pictures inside an image, showing that the image version is pixelated
94 * (correctly) when it is inside an image.
95 */
96class ImageShaderGM : public skiagm::GM {
reedca2622b2016-03-18 07:25:55 -070097 sk_sp<SkPicture> fPicture;
reed499abab2015-08-20 12:30:20 -070098
99public:
100 ImageShaderGM() {}
101
102protected:
103 SkString onShortName() override {
104 return SkString("image-shader");
105 }
106
107 SkISize onISize() override {
108 return SkISize::Make(850, 450);
109 }
110
111 void onOnceBeforeDraw() override {
112 const SkRect bounds = SkRect::MakeWH(100, 100);
113 SkPictureRecorder recorder;
114 draw_something(recorder.beginRecording(bounds), bounds);
reedca2622b2016-03-18 07:25:55 -0700115 fPicture = recorder.finishRecordingAsPicture();
reed499abab2015-08-20 12:30:20 -0700116 }
117
118 void testImage(SkCanvas* canvas, SkImage* image) {
119 SkAutoCanvasRestore acr(canvas, true);
120
121 canvas->drawImage(image, 0, 0);
122 canvas->translate(0, 120);
123
Mike Reedfae8fce2019-04-03 10:27:45 -0400124 const SkTileMode tile = SkTileMode::kRepeat;
reed499abab2015-08-20 12:30:20 -0700125 const SkMatrix localM = SkMatrix::MakeTrans(-50, -50);
reed499abab2015-08-20 12:30:20 -0700126 SkPaint paint;
reed5671c5b2016-03-09 14:47:34 -0800127 paint.setShader(image->makeShader(tile, tile, &localM));
reed499abab2015-08-20 12:30:20 -0700128 paint.setAntiAlias(true);
reed499abab2015-08-20 12:30:20 -0700129 canvas->drawCircle(50, 50, 50, paint);
130 }
131
132 void onDraw(SkCanvas* canvas) override {
133 canvas->translate(20, 20);
134
135 const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
136
137 for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) {
reedca2622b2016-03-18 07:25:55 -0700138 sk_sp<SkImage> image(gProcs[i](canvas->getGrContext(), fPicture.get(), info));
reed499abab2015-08-20 12:30:20 -0700139 if (image) {
reed9ce9d672016-03-17 10:51:11 -0700140 this->testImage(canvas, image.get());
reed499abab2015-08-20 12:30:20 -0700141 }
142 canvas->translate(120, 0);
143 }
144 }
145
146private:
147 typedef skiagm::GM INHERITED;
148};
149DEF_GM( return new ImageShaderGM; )