blob: d496ae8c27fae415a4ba3b3bc3321a3714d86b14 [file] [log] [blame]
Leon Scroggins III1adcac52020-05-28 17:12:59 -04001/*
2 * Copyright 2020 Google LLC
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/gm.h"
9#include "include/core/SkCanvas.h"
10#include "include/core/SkData.h"
11#include "include/core/SkEncodedImageFormat.h"
12#include "include/core/SkImage.h"
13#include "include/core/SkImageInfo.h"
14#include "include/core/SkSize.h"
15#include "include/core/SkString.h"
16#include "include/core/SkSurface.h"
17#include "tools/Resources.h"
18
19namespace skiagm {
20
21static const int imageWidth = 128;
22static const int imageHeight = 128;
23
24static sk_sp<SkImage> make_image(SkColorType colorType, SkAlphaType alphaType) {
25 const char* resource;
26 switch (colorType) {
27 case kGray_8_SkColorType:
28 if (alphaType != kOpaque_SkAlphaType) {
29 return nullptr;
30 }
31 resource = "images/grayscale.jpg";
32 break;
33 case kRGB_565_SkColorType:
34 case kRGB_888x_SkColorType:
35 case kRGB_101010x_SkColorType:
36 case kBGR_101010x_SkColorType:
37 if (alphaType != kOpaque_SkAlphaType) {
38 return nullptr;
39 }
40 resource = "images/color_wheel.jpg";
41 break;
42 default:
43 resource = (kOpaque_SkAlphaType == alphaType) ? "images/color_wheel.jpg"
44 : "images/rainbow-gradient.png";
45 break;
46 }
47
48 auto image = GetResourceAsImage(resource);
49 if (!image) {
50 return nullptr;
51 }
52
53 auto surface = SkSurface::MakeRaster(SkImageInfo::Make(image->width(), image->height(),
54 colorType, alphaType, image->refColorSpace()));
55 surface->getCanvas()->drawImage(image, 0, 0);
56 return surface->makeImageSnapshot();
57}
58
59// This GM looks different depending on the colortype used, so we use different
60// names to treat them as different GMs.
61// All Variants draw images in pairs:
62// - First as an image of the SkColorType of the destination
63// - Next as the result of encoding and decoding the first image
64enum class Variant {
65 // One pair, using an opaque image.
66 kOpaque,
67 // One pair, using a grayscale image.
68 kGray,
69 // An opaque pair followed by two more for premul and unpremul.
70 kNormal,
71};
72
73class EncodeColorTypesGM : public GM {
74public:
75 EncodeColorTypesGM(SkEncodedImageFormat format, int quality, Variant variant, const char* name)
76 : fFormat(format)
77 , fQuality(quality)
78 , fVariant(variant)
79 , fName(name)
80 {}
81
82protected:
83 SkString onShortName() override {
84 const char* variant = fVariant == Variant::kOpaque ? "opaque-":
85 fVariant == Variant::kGray ? "gray-" :
86 "" ;
87 return SkStringPrintf("encode-%scolor-types-%s", variant, fName);
88 }
89
90 SkISize onISize() override {
91 const int width = fVariant == Variant::kNormal ? imageWidth * 7 : imageWidth * 2;
92 return SkISize::Make(width, imageHeight);
93 }
94
95 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
96 const auto colorType = canvas->imageInfo().colorType();
97 switch (fVariant) {
98 case Variant::kGray:
99 if (colorType != kGray_8_SkColorType) {
100 return DrawResult::kSkip;
101 }
102 break;
103 case Variant::kOpaque:
104 if (colorType != kRGB_565_SkColorType &&
105 colorType != kRGB_888x_SkColorType &&
106 colorType != kRGB_101010x_SkColorType &&
107 colorType != kBGR_101010x_SkColorType)
108 {
109 return DrawResult::kSkip;
110 }
111 break;
112 case Variant::kNormal:
113 if (colorType != kARGB_4444_SkColorType &&
114 colorType != kRGBA_8888_SkColorType &&
115 colorType != kBGRA_8888_SkColorType &&
116 colorType != kRGBA_1010102_SkColorType &&
117 colorType != kBGRA_1010102_SkColorType &&
118 colorType != kRGBA_F16Norm_SkColorType &&
119 colorType != kRGBA_F16_SkColorType &&
120 colorType != kRGBA_F32_SkColorType)
121 {
122 return DrawResult::kSkip;
123 }
124 break;
125 }
126 const SkAlphaType alphaTypes[] = {
127 kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType,
128 };
129
130 for (SkAlphaType alphaType : alphaTypes) {
131 auto src = make_image(colorType, alphaType);
132 auto decoded = src ? SkImage::MakeFromEncoded(src->encodeToData(fFormat, fQuality))
133 : nullptr;
134 if (!src || !decoded) {
135 break;
136 }
137
138 canvas->drawImage(src, 0.0f, 0.0f);
139 canvas->translate((float) imageWidth, 0.0f);
140
141 canvas->drawImage(decoded, 0.0f, 0.0f);
142 canvas->translate((float) imageWidth * 1.5, 0.0f);
143 }
144 return DrawResult::kOk;
145 }
146
147private:
148 const SkEncodedImageFormat fFormat;
149 const int fQuality;
150 const Variant fVariant;
151 const char* fName;
152
153 typedef GM INHERITED;
154};
155
156
157#define DEF_ENCODE_GM(format, quality, variant, name) \
158 static skiagm::GMRegistry SK_MACRO_CONCAT(SK_MACRO_APPEND_LINE(REG_), variant)(\
159 [](){return std::unique_ptr<skiagm::GM>([](){\
160 return new EncodeColorTypesGM(format, quality, Variant::variant, name);\
161 }());});
162
163#define DEF_VARIANTS(format, quality, name) \
164 DEF_ENCODE_GM(format, quality, kNormal, name); \
165 DEF_ENCODE_GM(format, quality, kOpaque, name); \
166 DEF_ENCODE_GM(format, quality, kGray, name);
167
168DEF_VARIANTS(SkEncodedImageFormat::kWEBP, 100, "webp-lossless")
169DEF_VARIANTS(SkEncodedImageFormat::kWEBP, 80, "webp-lossy")
170}