blob: 114b36525aa1892b2569f8bb9dfbe3a08a1f9345 [file] [log] [blame]
Matt Sarett909d3792016-12-22 10:52:25 -05001/*
2 * Copyright 2016 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/codec/SkCodec.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040010#include "include/core/SkBitmap.h"
11#include "include/core/SkCanvas.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkColorSpace.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040013#include "include/core/SkData.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/SkPaint.h"
17#include "include/core/SkPicture.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "include/core/SkPictureRecorder.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040019#include "include/core/SkRect.h"
20#include "include/core/SkRefCnt.h"
21#include "include/core/SkSize.h"
22#include "include/core/SkStream.h"
23#include "include/core/SkString.h"
24#include "include/core/SkTypes.h"
Adlai Holler4caa9352020-07-16 10:58:58 -040025#include "include/gpu/GrDirectContext.h"
Kevin Lubick7a2d1b32023-04-04 09:50:57 -040026#include "include/gpu/ganesh/SkImageGanesh.h"
Kevin Lubick52904d32022-06-29 15:34:49 -040027#include "modules/skcms/skcms.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050028#include "tools/Resources.h"
Matt Sarett909d3792016-12-22 10:52:25 -050029
Ben Wagner7fde8e12019-05-01 17:28:53 -040030#include <string.h>
31#include <memory>
32#include <utility>
33
Matt Sarett909d3792016-12-22 10:52:25 -050034static const int kWidth = 64;
35static const int kHeight = 64;
36
Brian Osmanb1168a72017-03-20 14:21:18 -040037static sk_sp<SkImage> make_raster_image(SkColorType colorType) {
Hal Canaryc465d132017-12-08 10:21:31 -050038 std::unique_ptr<SkStream> stream(GetResourceAsStream("images/google_chrome.ico"));
Mike Reedede7bac2017-07-23 15:30:02 -040039 std::unique_ptr<SkCodec> codec = SkCodec::MakeFromStream(std::move(stream));
Hal Canarybaa2a282018-11-26 15:34:12 -050040 if (!codec) {
41 return nullptr;
42 }
Matt Sarett909d3792016-12-22 10:52:25 -050043
Matt Sarett909d3792016-12-22 10:52:25 -050044 SkImageInfo info = codec->getInfo().makeWH(kWidth, kHeight)
45 .makeColorType(colorType)
Brian Osman6b622962018-08-27 19:16:02 +000046 .makeAlphaType(kPremul_SkAlphaType);
Mike Reed844beb52021-01-25 15:36:09 -050047 return std::get<0>(codec->getImage(info));
Matt Sarett909d3792016-12-22 10:52:25 -050048}
49
Matt Sarett34855f92017-01-10 17:41:53 -050050static sk_sp<SkImage> make_codec_image() {
Hal Canaryc465d132017-12-08 10:21:31 -050051 sk_sp<SkData> encoded = GetResourceAsData("images/randPixels.png");
Kevin Lubick77472bf2023-03-24 07:11:17 -040052 return SkImages::DeferredFromEncodedData(encoded);
Matt Sarett34855f92017-01-10 17:41:53 -050053}
54
55static void draw_contents(SkCanvas* canvas) {
56 SkPaint paint;
57 paint.setStyle(SkPaint::kStroke_Style);
58 paint.setStrokeWidth(20);
59 paint.setColor(0xFF800000);
60 canvas->drawCircle(40, 40, 35, paint);
61 paint.setColor(0xFF008000);
62 canvas->drawCircle(50, 50, 35, paint);
63 paint.setColor(0xFF000080);
64 canvas->drawCircle(60, 60, 35, paint);
65}
66
Matt Sarett9df70bb2017-02-14 13:50:43 -050067static sk_sp<SkImage> make_picture_image() {
Matt Sarett34855f92017-01-10 17:41:53 -050068 SkPictureRecorder recorder;
69 draw_contents(recorder.beginRecording(SkRect::MakeIWH(kWidth, kHeight)));
Kevin Lubick77472bf2023-03-24 07:11:17 -040070 return SkImages::DeferredFromPicture(recorder.finishRecordingAsPicture(),
71 SkISize::Make(kWidth, kHeight),
72 nullptr,
73 nullptr,
74 SkImages::BitDepth::kU8,
75 SkColorSpace::MakeSRGB());
Matt Sarett34855f92017-01-10 17:41:53 -050076}
77
Matt Sarett733340a2017-05-02 16:19:51 -040078static sk_sp<SkColorSpace> make_parametric_transfer_fn(const SkColorSpacePrimaries& primaries) {
Brian Osman82ebe042019-01-04 17:03:00 -050079 skcms_Matrix3x3 toXYZD50;
Matt Sarett909d3792016-12-22 10:52:25 -050080 SkAssertResult(primaries.toXYZD50(&toXYZD50));
Brian Osman82ebe042019-01-04 17:03:00 -050081 skcms_TransferFunction fn = { 1.8f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f };
Matt Sarett733340a2017-05-02 16:19:51 -040082 return SkColorSpace::MakeRGB(fn, toXYZD50);
Matt Sarett909d3792016-12-22 10:52:25 -050083}
84
85static sk_sp<SkColorSpace> make_wide_gamut() {
86 // ProPhoto
87 SkColorSpacePrimaries primaries;
88 primaries.fRX = 0.7347f;
89 primaries.fRY = 0.2653f;
90 primaries.fGX = 0.1596f;
91 primaries.fGY = 0.8404f;
92 primaries.fBX = 0.0366f;
93 primaries.fBY = 0.0001f;
94 primaries.fWX = 0.34567f;
95 primaries.fWY = 0.35850f;
Matt Sarett733340a2017-05-02 16:19:51 -040096 return make_parametric_transfer_fn(primaries);
Matt Sarett909d3792016-12-22 10:52:25 -050097}
98
99static sk_sp<SkColorSpace> make_small_gamut() {
100 SkColorSpacePrimaries primaries;
101 primaries.fRX = 0.50f;
102 primaries.fRY = 0.33f;
103 primaries.fGX = 0.30f;
104 primaries.fGY = 0.50f;
105 primaries.fBX = 0.25f;
106 primaries.fBY = 0.16f;
107 primaries.fWX = 0.3127f;
108 primaries.fWY = 0.3290f;
Matt Sarett733340a2017-05-02 16:19:51 -0400109 return make_parametric_transfer_fn(primaries);
Matt Sarett909d3792016-12-22 10:52:25 -0500110}
111
Adlai Hollerbcfc5542020-08-27 12:44:07 -0400112static void draw_image(GrDirectContext* dContext, SkCanvas* canvas, SkImage* image,
113 SkColorType dstColorType, SkAlphaType dstAlphaType,
114 sk_sp<SkColorSpace> dstColorSpace, SkImage::CachingHint hint) {
Matt Sarett909d3792016-12-22 10:52:25 -0500115 size_t rowBytes = image->width() * SkColorTypeBytesPerPixel(dstColorType);
116 sk_sp<SkData> data = SkData::MakeUninitialized(rowBytes * image->height());
Matt Sarett909d3792016-12-22 10:52:25 -0500117 SkImageInfo dstInfo = SkImageInfo::Make(image->width(), image->height(), dstColorType,
118 dstAlphaType, dstColorSpace);
Adlai Hollerbcfc5542020-08-27 12:44:07 -0400119 if (!image->readPixels(dContext, dstInfo, data->writable_data(), rowBytes, 0, 0, hint)) {
Brian Osman89150582017-03-20 16:54:28 -0400120 memset(data->writable_data(), 0, rowBytes * image->height());
121 }
Matt Sarett909d3792016-12-22 10:52:25 -0500122
Matt Sarett909d3792016-12-22 10:52:25 -0500123 // Now that we have called readPixels(), dump the raw pixels into an srgb image.
Brian Osman6b622962018-08-27 19:16:02 +0000124 sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
Kevin Lubick77472bf2023-03-24 07:11:17 -0400125 sk_sp<SkImage> raw = SkImages::RasterFromData(dstInfo.makeColorSpace(srgb), data, rowBytes);
Mike Reed8d29ab62021-01-23 18:10:39 -0500126 canvas->drawImage(raw.get(), 0.0f, 0.0f);
Matt Sarett909d3792016-12-22 10:52:25 -0500127}
128
129class ReadPixelsGM : public skiagm::GM {
130public:
131 ReadPixelsGM() {}
132
133protected:
Leandro Lovisolo24fa2112023-08-15 19:05:17 +0000134 SkString getName() const override { return SkString("readpixels"); }
Matt Sarett909d3792016-12-22 10:52:25 -0500135
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000136 SkISize getISize() override { return SkISize::Make(6 * kWidth, 9 * kHeight); }
Matt Sarett909d3792016-12-22 10:52:25 -0500137
138 void onDraw(SkCanvas* canvas) override {
Matt Sarett909d3792016-12-22 10:52:25 -0500139 const SkAlphaType alphaTypes[] = {
140 kUnpremul_SkAlphaType,
141 kPremul_SkAlphaType,
142 };
143 const SkColorType colorTypes[] = {
144 kRGBA_8888_SkColorType,
145 kBGRA_8888_SkColorType,
146 kRGBA_F16_SkColorType,
147 };
148 const sk_sp<SkColorSpace> colorSpaces[] = {
149 make_wide_gamut(),
Matt Sarett77a7a1b2017-02-07 13:56:11 -0500150 SkColorSpace::MakeSRGB(),
Matt Sarett909d3792016-12-22 10:52:25 -0500151 make_small_gamut(),
152 };
153
John Stilesbd3ffa42020-07-30 20:24:57 -0400154 for (const sk_sp<SkColorSpace>& dstColorSpace : colorSpaces) {
Matt Sarett909d3792016-12-22 10:52:25 -0500155 for (SkColorType srcColorType : colorTypes) {
Brian Osmanb1168a72017-03-20 14:21:18 -0400156 canvas->save();
157 sk_sp<SkImage> image = make_raster_image(srcColorType);
Hal Canarybaa2a282018-11-26 15:34:12 -0500158 if (!image) {
159 continue;
160 }
Adlai Hollerbcfc5542020-08-27 12:44:07 -0400161 auto dContext = GrAsDirectContext(canvas->recordingContext());
162 if (dContext) {
Kevin Lubick7a2d1b32023-04-04 09:50:57 -0400163 image = SkImages::TextureFromImage(dContext, image);
Brian Osman89150582017-03-20 16:54:28 -0400164 }
165 if (image) {
166 for (SkColorType dstColorType : colorTypes) {
167 for (SkAlphaType dstAlphaType : alphaTypes) {
Adlai Hollerbcfc5542020-08-27 12:44:07 -0400168 draw_image(dContext, canvas, image.get(), dstColorType, dstAlphaType,
Brian Osman89150582017-03-20 16:54:28 -0400169 dstColorSpace, SkImage::kAllow_CachingHint);
170 canvas->translate((float)kWidth, 0.0f);
171 }
Matt Sarett909d3792016-12-22 10:52:25 -0500172 }
Matt Sarett909d3792016-12-22 10:52:25 -0500173 }
Brian Osmanb1168a72017-03-20 14:21:18 -0400174 canvas->restore();
175 canvas->translate(0.0f, (float) kHeight);
Matt Sarett909d3792016-12-22 10:52:25 -0500176 }
177 }
178 }
179
180private:
John Stiles7571f9e2020-09-02 22:42:33 -0400181 using INHERITED = skiagm::GM;
Matt Sarett909d3792016-12-22 10:52:25 -0500182};
183DEF_GM( return new ReadPixelsGM; )
Matt Sarett34855f92017-01-10 17:41:53 -0500184
185class ReadPixelsCodecGM : public skiagm::GM {
186public:
187 ReadPixelsCodecGM() {}
188
189protected:
Leandro Lovisolo24fa2112023-08-15 19:05:17 +0000190 SkString getName() const override { return SkString("readpixelscodec"); }
Matt Sarett34855f92017-01-10 17:41:53 -0500191
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000192 SkISize getISize() override {
Matt Sarett34855f92017-01-10 17:41:53 -0500193 return SkISize::Make(3 * (kEncodedWidth + 1), 12 * (kEncodedHeight + 1));
194 }
195
Chris Dalton50e24d72019-02-07 16:20:09 -0700196 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
Matt Sarett34855f92017-01-10 17:41:53 -0500197 if (!canvas->imageInfo().colorSpace()) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700198 *errorMsg = "This gm is only interesting in color correct modes.";
199 return DrawResult::kSkip;
Matt Sarett34855f92017-01-10 17:41:53 -0500200 }
201
202 const SkAlphaType alphaTypes[] = {
203 kUnpremul_SkAlphaType,
204 kPremul_SkAlphaType,
205 };
206 const SkColorType colorTypes[] = {
207 kRGBA_8888_SkColorType,
208 kBGRA_8888_SkColorType,
209 kRGBA_F16_SkColorType,
210 };
211 const sk_sp<SkColorSpace> colorSpaces[] = {
212 make_wide_gamut(),
Matt Sarett77a7a1b2017-02-07 13:56:11 -0500213 SkColorSpace::MakeSRGB(),
Matt Sarett34855f92017-01-10 17:41:53 -0500214 make_small_gamut(),
215 };
216 const SkImage::CachingHint hints[] = {
217 SkImage::kAllow_CachingHint,
218 SkImage::kDisallow_CachingHint,
219 };
220
221 sk_sp<SkImage> image = make_codec_image();
John Stilesbd3ffa42020-07-30 20:24:57 -0400222 for (const sk_sp<SkColorSpace>& dstColorSpace : colorSpaces) {
Matt Sarett34855f92017-01-10 17:41:53 -0500223 canvas->save();
224 for (SkColorType dstColorType : colorTypes) {
225 for (SkAlphaType dstAlphaType : alphaTypes) {
226 for (SkImage::CachingHint hint : hints) {
Adlai Hollerbcfc5542020-08-27 12:44:07 -0400227 draw_image(nullptr, canvas, image.get(), dstColorType, dstAlphaType,
228 dstColorSpace, hint);
Matt Sarett34855f92017-01-10 17:41:53 -0500229 canvas->translate(0.0f, (float) kEncodedHeight + 1);
230 }
231 }
232 }
233 canvas->restore();
234 canvas->translate((float) kEncodedWidth + 1, 0.0f);
235 }
Chris Dalton50e24d72019-02-07 16:20:09 -0700236 return DrawResult::kOk;
Matt Sarett34855f92017-01-10 17:41:53 -0500237 }
238
239private:
240 static const int kEncodedWidth = 8;
241 static const int kEncodedHeight = 8;
242
John Stiles7571f9e2020-09-02 22:42:33 -0400243 using INHERITED = skiagm::GM;
Matt Sarett34855f92017-01-10 17:41:53 -0500244};
245DEF_GM( return new ReadPixelsCodecGM; )
246
247class ReadPixelsPictureGM : public skiagm::GM {
248public:
249 ReadPixelsPictureGM() {}
250
251protected:
Leandro Lovisolo24fa2112023-08-15 19:05:17 +0000252 SkString getName() const override { return SkString("readpixelspicture"); }
Matt Sarett34855f92017-01-10 17:41:53 -0500253
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000254 SkISize getISize() override { return SkISize::Make(3 * kWidth, 12 * kHeight); }
Matt Sarett34855f92017-01-10 17:41:53 -0500255
Chris Dalton50e24d72019-02-07 16:20:09 -0700256 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
Matt Sarett34855f92017-01-10 17:41:53 -0500257 if (!canvas->imageInfo().colorSpace()) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700258 *errorMsg = "This gm is only interesting in color correct modes.";
259 return DrawResult::kSkip;
Matt Sarett34855f92017-01-10 17:41:53 -0500260 }
261
262 const sk_sp<SkImage> images[] = {
Matt Sarett9df70bb2017-02-14 13:50:43 -0500263 make_picture_image(),
Matt Sarett34855f92017-01-10 17:41:53 -0500264 };
265 const SkAlphaType alphaTypes[] = {
266 kUnpremul_SkAlphaType,
267 kPremul_SkAlphaType,
268 };
269 const SkColorType colorTypes[] = {
270 kRGBA_8888_SkColorType,
271 kBGRA_8888_SkColorType,
272 kRGBA_F16_SkColorType,
273 };
274 const sk_sp<SkColorSpace> colorSpaces[] = {
275 make_wide_gamut(),
Matt Sarett77a7a1b2017-02-07 13:56:11 -0500276 SkColorSpace::MakeSRGB(),
Matt Sarett34855f92017-01-10 17:41:53 -0500277 make_small_gamut(),
278 };
279 const SkImage::CachingHint hints[] = {
280 SkImage::kAllow_CachingHint,
281 SkImage::kDisallow_CachingHint,
282 };
283
John Stilesbd3ffa42020-07-30 20:24:57 -0400284 for (const sk_sp<SkImage>& image : images) {
285 for (const sk_sp<SkColorSpace>& dstColorSpace : colorSpaces) {
Matt Sarett34855f92017-01-10 17:41:53 -0500286 canvas->save();
287 for (SkColorType dstColorType : colorTypes) {
288 for (SkAlphaType dstAlphaType : alphaTypes) {
289 for (SkImage::CachingHint hint : hints) {
Adlai Hollerbcfc5542020-08-27 12:44:07 -0400290 draw_image(nullptr, canvas, image.get(), dstColorType, dstAlphaType,
Matt Sarett34855f92017-01-10 17:41:53 -0500291 dstColorSpace, hint);
292 canvas->translate(0.0f, (float) kHeight);
293 }
294 }
295 }
296 canvas->restore();
297 canvas->translate((float) kWidth, 0.0f);
298 }
299 }
Chris Dalton50e24d72019-02-07 16:20:09 -0700300 return DrawResult::kOk;
Matt Sarett34855f92017-01-10 17:41:53 -0500301 }
302
303private:
304
John Stiles7571f9e2020-09-02 22:42:33 -0400305 using INHERITED = skiagm::GM;
Matt Sarett34855f92017-01-10 17:41:53 -0500306};
307DEF_GM( return new ReadPixelsPictureGM; )