xref: /aosp_15_r20/external/skia/tests/graphite/ImageProviderTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2022 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageGenerator.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPicture.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPictureRecorder.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Context.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Image.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Recording.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Surface.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkMipmapBuilder.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Caps.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RecorderPriv.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Surface_Graphite.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/image/SkImage_Base.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "tests/TestUtils.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "tools/graphite/GraphiteToolUtils.h"
29*c8dee2aaSAndroid Build Coastguard Worker 
30*c8dee2aaSAndroid Build Coastguard Worker using namespace skgpu::graphite;
31*c8dee2aaSAndroid Build Coastguard Worker using Mipmapped = skgpu::Mipmapped;
32*c8dee2aaSAndroid Build Coastguard Worker 
33*c8dee2aaSAndroid Build Coastguard Worker namespace {
34*c8dee2aaSAndroid Build Coastguard Worker 
35*c8dee2aaSAndroid Build Coastguard Worker const SkISize kSurfaceSize = { 16, 16 };
36*c8dee2aaSAndroid Build Coastguard Worker const SkISize kImageSize = { 32, 32 };
37*c8dee2aaSAndroid Build Coastguard Worker 
38*c8dee2aaSAndroid Build Coastguard Worker constexpr SkColor4f kBaseImageColor = SkColors::kYellow;
39*c8dee2aaSAndroid Build Coastguard Worker constexpr SkColor4f kFirstMipLevelColor = SkColors::kRed;
40*c8dee2aaSAndroid Build Coastguard Worker constexpr SkColor4f kBackgroundColor = SkColors::kBlue;
41*c8dee2aaSAndroid Build Coastguard Worker 
create_and_attach_mipmaps(sk_sp<SkImage> img)42*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> create_and_attach_mipmaps(sk_sp<SkImage> img) {
43*c8dee2aaSAndroid Build Coastguard Worker     constexpr SkColor4f mipLevelColors[] = {
44*c8dee2aaSAndroid Build Coastguard Worker             kFirstMipLevelColor,
45*c8dee2aaSAndroid Build Coastguard Worker             SkColors::kGreen,
46*c8dee2aaSAndroid Build Coastguard Worker             SkColors::kMagenta,
47*c8dee2aaSAndroid Build Coastguard Worker             SkColors::kCyan,
48*c8dee2aaSAndroid Build Coastguard Worker             SkColors::kWhite,
49*c8dee2aaSAndroid Build Coastguard Worker     };
50*c8dee2aaSAndroid Build Coastguard Worker 
51*c8dee2aaSAndroid Build Coastguard Worker     SkMipmapBuilder builder(img->imageInfo());
52*c8dee2aaSAndroid Build Coastguard Worker 
53*c8dee2aaSAndroid Build Coastguard Worker     int count = builder.countLevels();
54*c8dee2aaSAndroid Build Coastguard Worker 
55*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT_RELEASE(count == SkToInt(std::size(mipLevelColors)));
56*c8dee2aaSAndroid Build Coastguard Worker 
57*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < count; ++i) {
58*c8dee2aaSAndroid Build Coastguard Worker         SkPixmap pm = builder.level(i);
59*c8dee2aaSAndroid Build Coastguard Worker         pm.erase(mipLevelColors[i]);
60*c8dee2aaSAndroid Build Coastguard Worker     }
61*c8dee2aaSAndroid Build Coastguard Worker 
62*c8dee2aaSAndroid Build Coastguard Worker     return builder.attachTo(img);
63*c8dee2aaSAndroid Build Coastguard Worker }
64*c8dee2aaSAndroid Build Coastguard Worker 
create_raster(Mipmapped mipmapped)65*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> create_raster(Mipmapped mipmapped) {
66*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo ii = SkImageInfo::Make(kImageSize.width(),
67*c8dee2aaSAndroid Build Coastguard Worker                                        kImageSize.height(),
68*c8dee2aaSAndroid Build Coastguard Worker                                        kRGBA_8888_SkColorType,
69*c8dee2aaSAndroid Build Coastguard Worker                                        kPremul_SkAlphaType);
70*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap bm;
71*c8dee2aaSAndroid Build Coastguard Worker     if (!bm.tryAllocPixels(ii)) {
72*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
73*c8dee2aaSAndroid Build Coastguard Worker     }
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker     bm.eraseColor(kBaseImageColor);
76*c8dee2aaSAndroid Build Coastguard Worker 
77*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImage> img = SkImages::RasterFromBitmap(bm);
78*c8dee2aaSAndroid Build Coastguard Worker 
79*c8dee2aaSAndroid Build Coastguard Worker     if (mipmapped == Mipmapped::kYes) {
80*c8dee2aaSAndroid Build Coastguard Worker         img = create_and_attach_mipmaps(std::move(img));
81*c8dee2aaSAndroid Build Coastguard Worker     }
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker     return img;
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker 
86*c8dee2aaSAndroid Build Coastguard Worker /* 0 */
create_raster_backed_image_no_mipmaps(Recorder *)87*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> create_raster_backed_image_no_mipmaps(Recorder*) {
88*c8dee2aaSAndroid Build Coastguard Worker     return create_raster(Mipmapped::kNo);
89*c8dee2aaSAndroid Build Coastguard Worker }
90*c8dee2aaSAndroid Build Coastguard Worker 
91*c8dee2aaSAndroid Build Coastguard Worker /* 1 */
create_raster_backed_image_with_mipmaps(Recorder *)92*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> create_raster_backed_image_with_mipmaps(Recorder*) {
93*c8dee2aaSAndroid Build Coastguard Worker     return create_raster(Mipmapped::kYes);
94*c8dee2aaSAndroid Build Coastguard Worker }
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker /* 2 */
create_gpu_backed_image_no_mipmaps(Recorder * recorder)97*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> create_gpu_backed_image_no_mipmaps(Recorder* recorder) {
98*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImage> raster = create_raster(Mipmapped::kNo);
99*c8dee2aaSAndroid Build Coastguard Worker     return SkImages::TextureFromImage(recorder, raster, {false});
100*c8dee2aaSAndroid Build Coastguard Worker }
101*c8dee2aaSAndroid Build Coastguard Worker 
102*c8dee2aaSAndroid Build Coastguard Worker /* 3 */
create_gpu_backed_image_with_mipmaps(Recorder * recorder)103*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> create_gpu_backed_image_with_mipmaps(Recorder* recorder) {
104*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImage> raster = create_raster(Mipmapped::kYes);
105*c8dee2aaSAndroid Build Coastguard Worker     return SkImages::TextureFromImage(recorder, raster, {true});
106*c8dee2aaSAndroid Build Coastguard Worker }
107*c8dee2aaSAndroid Build Coastguard Worker 
108*c8dee2aaSAndroid Build Coastguard Worker /* 4 */
create_picture_backed_image(Recorder *)109*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> create_picture_backed_image(Recorder*) {
110*c8dee2aaSAndroid Build Coastguard Worker     SkIRect r = SkIRect::MakeWH(kImageSize.width(), kImageSize.height());
111*c8dee2aaSAndroid Build Coastguard Worker     SkPaint paint;
112*c8dee2aaSAndroid Build Coastguard Worker     paint.setColor(kBaseImageColor);
113*c8dee2aaSAndroid Build Coastguard Worker 
114*c8dee2aaSAndroid Build Coastguard Worker     SkPictureRecorder recorder;
115*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas* canvas = recorder.beginRecording(SkRect::Make(r));
116*c8dee2aaSAndroid Build Coastguard Worker     canvas->drawIRect(r, paint);
117*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
118*c8dee2aaSAndroid Build Coastguard Worker 
119*c8dee2aaSAndroid Build Coastguard Worker     return SkImages::DeferredFromPicture(std::move(picture),
120*c8dee2aaSAndroid Build Coastguard Worker                                          r.size(),
121*c8dee2aaSAndroid Build Coastguard Worker                                          /* matrix= */ nullptr,
122*c8dee2aaSAndroid Build Coastguard Worker                                          /* paint= */ nullptr,
123*c8dee2aaSAndroid Build Coastguard Worker                                          SkImages::BitDepth::kU8,
124*c8dee2aaSAndroid Build Coastguard Worker                                          SkColorSpace::MakeSRGB());
125*c8dee2aaSAndroid Build Coastguard Worker }
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker /* 5 */
create_bitmap_generator_backed_image(Recorder *)128*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> create_bitmap_generator_backed_image(Recorder*) {
129*c8dee2aaSAndroid Build Coastguard Worker 
130*c8dee2aaSAndroid Build Coastguard Worker     class BitmapBackedGenerator final : public SkImageGenerator {
131*c8dee2aaSAndroid Build Coastguard Worker     public:
132*c8dee2aaSAndroid Build Coastguard Worker         BitmapBackedGenerator()
133*c8dee2aaSAndroid Build Coastguard Worker                 : SkImageGenerator(SkImageInfo::Make(kImageSize.width(),
134*c8dee2aaSAndroid Build Coastguard Worker                                                      kImageSize.height(),
135*c8dee2aaSAndroid Build Coastguard Worker                                                      kRGBA_8888_SkColorType,
136*c8dee2aaSAndroid Build Coastguard Worker                                                      kPremul_SkAlphaType)) {
137*c8dee2aaSAndroid Build Coastguard Worker         }
138*c8dee2aaSAndroid Build Coastguard Worker 
139*c8dee2aaSAndroid Build Coastguard Worker         bool onGetPixels(const SkImageInfo& dstInfo,
140*c8dee2aaSAndroid Build Coastguard Worker                          void* pixels,
141*c8dee2aaSAndroid Build Coastguard Worker                          size_t rowBytes,
142*c8dee2aaSAndroid Build Coastguard Worker                          const Options&) override {
143*c8dee2aaSAndroid Build Coastguard Worker 
144*c8dee2aaSAndroid Build Coastguard Worker             if (dstInfo.dimensions() != kImageSize) {
145*c8dee2aaSAndroid Build Coastguard Worker                 return false;
146*c8dee2aaSAndroid Build Coastguard Worker             }
147*c8dee2aaSAndroid Build Coastguard Worker 
148*c8dee2aaSAndroid Build Coastguard Worker             SkBitmap bm;
149*c8dee2aaSAndroid Build Coastguard Worker             if (!bm.tryAllocPixels(dstInfo)) {
150*c8dee2aaSAndroid Build Coastguard Worker                 return false;
151*c8dee2aaSAndroid Build Coastguard Worker             }
152*c8dee2aaSAndroid Build Coastguard Worker 
153*c8dee2aaSAndroid Build Coastguard Worker             bm.eraseColor(kBaseImageColor);
154*c8dee2aaSAndroid Build Coastguard Worker 
155*c8dee2aaSAndroid Build Coastguard Worker             return bm.readPixels(dstInfo, pixels, rowBytes, 0, 0);
156*c8dee2aaSAndroid Build Coastguard Worker         }
157*c8dee2aaSAndroid Build Coastguard Worker     };
158*c8dee2aaSAndroid Build Coastguard Worker 
159*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkImageGenerator> gen(new BitmapBackedGenerator());
160*c8dee2aaSAndroid Build Coastguard Worker 
161*c8dee2aaSAndroid Build Coastguard Worker     return SkImages::DeferredFromGenerator(std::move(gen));
162*c8dee2aaSAndroid Build Coastguard Worker }
163*c8dee2aaSAndroid Build Coastguard Worker 
check_img(skiatest::Reporter * reporter,Context * context,Recorder * recorder,SkImage * imageToDraw,Mipmapped mipmapped,const char * testcase,const SkColor4f & expectedColor)164*c8dee2aaSAndroid Build Coastguard Worker bool check_img(skiatest::Reporter* reporter,
165*c8dee2aaSAndroid Build Coastguard Worker                Context* context,
166*c8dee2aaSAndroid Build Coastguard Worker                Recorder* recorder,
167*c8dee2aaSAndroid Build Coastguard Worker                SkImage* imageToDraw,
168*c8dee2aaSAndroid Build Coastguard Worker                Mipmapped mipmapped,
169*c8dee2aaSAndroid Build Coastguard Worker                const char* testcase,
170*c8dee2aaSAndroid Build Coastguard Worker                const SkColor4f& expectedColor) {
171*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo ii = SkImageInfo::Make(kSurfaceSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
172*c8dee2aaSAndroid Build Coastguard Worker 
173*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap result;
174*c8dee2aaSAndroid Build Coastguard Worker     result.allocPixels(ii);
175*c8dee2aaSAndroid Build Coastguard Worker     SkPixmap pm;
176*c8dee2aaSAndroid Build Coastguard Worker 
177*c8dee2aaSAndroid Build Coastguard Worker     SkAssertResult(result.peekPixels(&pm));
178*c8dee2aaSAndroid Build Coastguard Worker 
179*c8dee2aaSAndroid Build Coastguard Worker     {
180*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(recorder, ii);
181*c8dee2aaSAndroid Build Coastguard Worker         if (!surface) {
182*c8dee2aaSAndroid Build Coastguard Worker             ERRORF(reporter, "Surface creation failed");
183*c8dee2aaSAndroid Build Coastguard Worker             return false;
184*c8dee2aaSAndroid Build Coastguard Worker         }
185*c8dee2aaSAndroid Build Coastguard Worker 
186*c8dee2aaSAndroid Build Coastguard Worker         SkCanvas* canvas = surface->getCanvas();
187*c8dee2aaSAndroid Build Coastguard Worker 
188*c8dee2aaSAndroid Build Coastguard Worker         canvas->clear(kBackgroundColor);
189*c8dee2aaSAndroid Build Coastguard Worker 
190*c8dee2aaSAndroid Build Coastguard Worker         SkSamplingOptions sampling = (mipmapped == Mipmapped::kYes)
191*c8dee2aaSAndroid Build Coastguard Worker                 ? SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNearest)
192*c8dee2aaSAndroid Build Coastguard Worker                 : SkSamplingOptions(SkFilterMode::kLinear);
193*c8dee2aaSAndroid Build Coastguard Worker 
194*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawImageRect(imageToDraw,
195*c8dee2aaSAndroid Build Coastguard Worker                               SkRect::MakeWH(kSurfaceSize.width(), kSurfaceSize.height()),
196*c8dee2aaSAndroid Build Coastguard Worker                               sampling);
197*c8dee2aaSAndroid Build Coastguard Worker 
198*c8dee2aaSAndroid Build Coastguard Worker         if (!surface->readPixels(pm, 0, 0)) {
199*c8dee2aaSAndroid Build Coastguard Worker             ERRORF(reporter, "readPixels failed");
200*c8dee2aaSAndroid Build Coastguard Worker             return false;
201*c8dee2aaSAndroid Build Coastguard Worker         }
202*c8dee2aaSAndroid Build Coastguard Worker     }
203*c8dee2aaSAndroid Build Coastguard Worker 
204*c8dee2aaSAndroid Build Coastguard Worker     auto error = std::function<ComparePixmapsErrorReporter>(
205*c8dee2aaSAndroid Build Coastguard Worker             [&](int x, int y, const float diffs[4]) {
206*c8dee2aaSAndroid Build Coastguard Worker                 ERRORF(reporter,
207*c8dee2aaSAndroid Build Coastguard Worker                        "case %s %s: expected (%.1f %.1f %.1f %.1f) got (%.1f, %.1f, %.1f, %.1f)",
208*c8dee2aaSAndroid Build Coastguard Worker                        testcase,
209*c8dee2aaSAndroid Build Coastguard Worker                        (mipmapped == Mipmapped::kYes) ? "w/ mipmaps" : "w/o mipmaps",
210*c8dee2aaSAndroid Build Coastguard Worker                        expectedColor.fR, expectedColor.fG, expectedColor.fB, expectedColor.fA,
211*c8dee2aaSAndroid Build Coastguard Worker                        expectedColor.fR-diffs[0], expectedColor.fG-diffs[1],
212*c8dee2aaSAndroid Build Coastguard Worker                        expectedColor.fB-diffs[2], expectedColor.fA-diffs[3]);
213*c8dee2aaSAndroid Build Coastguard Worker             });
214*c8dee2aaSAndroid Build Coastguard Worker     static constexpr float kTol[] = {0, 0, 0, 0};
215*c8dee2aaSAndroid Build Coastguard Worker     CheckSolidPixels(expectedColor, pm, kTol, error);
216*c8dee2aaSAndroid Build Coastguard Worker 
217*c8dee2aaSAndroid Build Coastguard Worker     return true;
218*c8dee2aaSAndroid Build Coastguard Worker }
219*c8dee2aaSAndroid Build Coastguard Worker 
220*c8dee2aaSAndroid Build Coastguard Worker using FactoryT = sk_sp<SkImage> (*)(Recorder*);
221*c8dee2aaSAndroid Build Coastguard Worker 
222*c8dee2aaSAndroid Build Coastguard Worker struct TestCase {
223*c8dee2aaSAndroid Build Coastguard Worker     const char* fTestCase;
224*c8dee2aaSAndroid Build Coastguard Worker     FactoryT    fFactory;
225*c8dee2aaSAndroid Build Coastguard Worker     SkColor4f   fExpectedColors[2];   /* [ w/o mipmaps, w/ mipmaps ] */
226*c8dee2aaSAndroid Build Coastguard Worker };
227*c8dee2aaSAndroid Build Coastguard Worker 
run_test(skiatest::Reporter * reporter,Context * context,Recorder * recorder,SkSpan<const TestCase> testcases)228*c8dee2aaSAndroid Build Coastguard Worker void run_test(skiatest::Reporter* reporter,
229*c8dee2aaSAndroid Build Coastguard Worker               Context* context,
230*c8dee2aaSAndroid Build Coastguard Worker               Recorder* recorder,
231*c8dee2aaSAndroid Build Coastguard Worker               SkSpan<const TestCase> testcases) {
232*c8dee2aaSAndroid Build Coastguard Worker 
233*c8dee2aaSAndroid Build Coastguard Worker     for (auto t : testcases) {
234*c8dee2aaSAndroid Build Coastguard Worker         for (auto mm : { Mipmapped::kNo, Mipmapped::kYes }) {
235*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkImage> image = t.fFactory(recorder);
236*c8dee2aaSAndroid Build Coastguard Worker 
237*c8dee2aaSAndroid Build Coastguard Worker             check_img(reporter, context, recorder, image.get(), mm,
238*c8dee2aaSAndroid Build Coastguard Worker                       t.fTestCase, t.fExpectedColors[static_cast<int>(mm)]);
239*c8dee2aaSAndroid Build Coastguard Worker         }
240*c8dee2aaSAndroid Build Coastguard Worker     }
241*c8dee2aaSAndroid Build Coastguard Worker }
242*c8dee2aaSAndroid Build Coastguard Worker 
243*c8dee2aaSAndroid Build Coastguard Worker } // anonymous namespace
244*c8dee2aaSAndroid Build Coastguard Worker 
245*c8dee2aaSAndroid Build Coastguard Worker // This test creates a bunch of solid yellow images in different ways and then draws them into a
246*c8dee2aaSAndroid Build Coastguard Worker // smaller surface (w/ src mode) that has been initialized to solid blue. When mipmap levels
247*c8dee2aaSAndroid Build Coastguard Worker // are possible to be specified the first mipmap level is made red. Thus, when mipmapping
248*c8dee2aaSAndroid Build Coastguard Worker // is allowed and it is specified as the sample mode, the drawn image will be red.
249*c8dee2aaSAndroid Build Coastguard Worker 
250*c8dee2aaSAndroid Build Coastguard Worker // For the Default ImageProvider (which does _no_ caching and conversion) the expectations are:
251*c8dee2aaSAndroid Build Coastguard Worker //
252*c8dee2aaSAndroid Build Coastguard Worker //    0) raster-backed image w/o mipmaps
253*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> dropped draw (blue)
254*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> dropped draw (blue)
255*c8dee2aaSAndroid Build Coastguard Worker //
256*c8dee2aaSAndroid Build Coastguard Worker //    1) raster-backed image w/ mipmaps
257*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> dropped draw (blue)
258*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> dropped draw (blue)
259*c8dee2aaSAndroid Build Coastguard Worker //
260*c8dee2aaSAndroid Build Coastguard Worker //    2) Graphite-backed w/o mipmaps
261*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> drawn (yellow)
262*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> drawn (yellow) - mipmap filtering is dropped
263*c8dee2aaSAndroid Build Coastguard Worker //
264*c8dee2aaSAndroid Build Coastguard Worker //    3) Graphite-backed w/ mipmaps
265*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> drawn (yellow)
266*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> drawn (red)
267*c8dee2aaSAndroid Build Coastguard Worker //
268*c8dee2aaSAndroid Build Coastguard Worker //    4) picture-backed image
269*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> dropped draw (blue)
270*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> dropped draw (blue)
271*c8dee2aaSAndroid Build Coastguard Worker //
272*c8dee2aaSAndroid Build Coastguard Worker //    5) bitmap-backed-generator based image
273*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> dropped draw (blue)
274*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> dropped draw (blue)
275*c8dee2aaSAndroid Build Coastguard Worker //
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageProviderTest_Graphite_Default,reporter,context,CtsEnforcement::kApiLevel_V)276*c8dee2aaSAndroid Build Coastguard Worker DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageProviderTest_Graphite_Default, reporter, context,
277*c8dee2aaSAndroid Build Coastguard Worker                                          CtsEnforcement::kApiLevel_V) {
278*c8dee2aaSAndroid Build Coastguard Worker     TestCase testcases[] = {
279*c8dee2aaSAndroid Build Coastguard Worker         { "0", create_raster_backed_image_no_mipmaps,   { kBackgroundColor, kBackgroundColor } },
280*c8dee2aaSAndroid Build Coastguard Worker         { "1", create_raster_backed_image_with_mipmaps, { kBackgroundColor, kBackgroundColor } },
281*c8dee2aaSAndroid Build Coastguard Worker         { "2", create_gpu_backed_image_no_mipmaps,      { kBaseImageColor,  kBaseImageColor } },
282*c8dee2aaSAndroid Build Coastguard Worker         { "3", create_gpu_backed_image_with_mipmaps,    { kBaseImageColor,  kFirstMipLevelColor } },
283*c8dee2aaSAndroid Build Coastguard Worker         { "4", create_picture_backed_image,             { kBackgroundColor, kBackgroundColor } },
284*c8dee2aaSAndroid Build Coastguard Worker         { "5", create_bitmap_generator_backed_image,    { kBackgroundColor, kBackgroundColor }  },
285*c8dee2aaSAndroid Build Coastguard Worker     };
286*c8dee2aaSAndroid Build Coastguard Worker 
287*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Recorder> recorder = context->makeRecorder();
288*c8dee2aaSAndroid Build Coastguard Worker 
289*c8dee2aaSAndroid Build Coastguard Worker     run_test(reporter, context, recorder.get(), testcases);
290*c8dee2aaSAndroid Build Coastguard Worker }
291*c8dee2aaSAndroid Build Coastguard Worker 
292*c8dee2aaSAndroid Build Coastguard Worker // For the Testing ImageProvider (which does some caching and conversion) the expectations are:
293*c8dee2aaSAndroid Build Coastguard Worker //
294*c8dee2aaSAndroid Build Coastguard Worker //    0) raster-backed image w/o mipmaps
295*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> drawn (yellow) - auto-converted
296*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> drawn (yellow) - auto-converted
297*c8dee2aaSAndroid Build Coastguard Worker //
298*c8dee2aaSAndroid Build Coastguard Worker //    1) raster-backed image w/ mipmaps
299*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> drawn (yellow) - auto-converted
300*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> drawn (red) - auto-converted
301*c8dee2aaSAndroid Build Coastguard Worker //
302*c8dee2aaSAndroid Build Coastguard Worker //    2) Graphite-backed w/o mipmaps
303*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> drawn (yellow)
304*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> drawn (yellow) - mipmap filtering is dropped
305*c8dee2aaSAndroid Build Coastguard Worker //
306*c8dee2aaSAndroid Build Coastguard Worker //    3) Graphite-backed w/ mipmaps
307*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> drawn (yellow)
308*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> drawn (red)
309*c8dee2aaSAndroid Build Coastguard Worker //
310*c8dee2aaSAndroid Build Coastguard Worker //    4) picture-backed image
311*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> drawn (yellow) - auto-converted
312*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> drawn (yellow) - mipmaps auto generated
313*c8dee2aaSAndroid Build Coastguard Worker //
314*c8dee2aaSAndroid Build Coastguard Worker //    5) bitmap-backed-generator based image
315*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/o mipmapping    --> drawn (yellow) - auto-converted
316*c8dee2aaSAndroid Build Coastguard Worker //                    drawn w/ mipmapping     --> drawn (yellow) - auto-converted
317*c8dee2aaSAndroid Build Coastguard Worker //
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageProviderTest_Graphite_Testing,reporter,context,CtsEnforcement::kApiLevel_V)318*c8dee2aaSAndroid Build Coastguard Worker DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageProviderTest_Graphite_Testing, reporter, context,
319*c8dee2aaSAndroid Build Coastguard Worker                                          CtsEnforcement::kApiLevel_V) {
320*c8dee2aaSAndroid Build Coastguard Worker     static const TestCase testcases[] = {
321*c8dee2aaSAndroid Build Coastguard Worker         { "0", create_raster_backed_image_no_mipmaps,   { kBaseImageColor, kBaseImageColor } },
322*c8dee2aaSAndroid Build Coastguard Worker         { "1", create_raster_backed_image_with_mipmaps, { kBaseImageColor, kFirstMipLevelColor } },
323*c8dee2aaSAndroid Build Coastguard Worker         { "2", create_gpu_backed_image_no_mipmaps,      { kBaseImageColor, kBaseImageColor } },
324*c8dee2aaSAndroid Build Coastguard Worker         { "3", create_gpu_backed_image_with_mipmaps,    { kBaseImageColor, kFirstMipLevelColor } },
325*c8dee2aaSAndroid Build Coastguard Worker         { "4", create_picture_backed_image,             { kBaseImageColor, kBaseImageColor } },
326*c8dee2aaSAndroid Build Coastguard Worker         { "5", create_bitmap_generator_backed_image,    { kBaseImageColor, kBaseImageColor } },
327*c8dee2aaSAndroid Build Coastguard Worker     };
328*c8dee2aaSAndroid Build Coastguard Worker 
329*c8dee2aaSAndroid Build Coastguard Worker     RecorderOptions options = ToolUtils::CreateTestingRecorderOptions();
330*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<skgpu::graphite::Recorder> recorder = context->makeRecorder(options);
331*c8dee2aaSAndroid Build Coastguard Worker 
332*c8dee2aaSAndroid Build Coastguard Worker     run_test(reporter, context, recorder.get(), testcases);
333*c8dee2aaSAndroid Build Coastguard Worker }
334*c8dee2aaSAndroid Build Coastguard Worker 
335*c8dee2aaSAndroid Build Coastguard Worker // Here we're testing that the RequiredProperties parameter to makeTextureImage and makeSubset
336*c8dee2aaSAndroid Build Coastguard Worker // works as expected.
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(Make_TextureImage_Subset_Test,reporter,context,CtsEnforcement::kApiLevel_V)337*c8dee2aaSAndroid Build Coastguard Worker DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(Make_TextureImage_Subset_Test, reporter, context,
338*c8dee2aaSAndroid Build Coastguard Worker                                          CtsEnforcement::kApiLevel_V) {
339*c8dee2aaSAndroid Build Coastguard Worker     static const struct {
340*c8dee2aaSAndroid Build Coastguard Worker         std::string name;
341*c8dee2aaSAndroid Build Coastguard Worker         FactoryT fFactory;
342*c8dee2aaSAndroid Build Coastguard Worker     } testcases[] = {
343*c8dee2aaSAndroid Build Coastguard Worker         { "raster_no_mips",    create_raster_backed_image_no_mipmaps   },
344*c8dee2aaSAndroid Build Coastguard Worker         { "raster_with_mips",  create_raster_backed_image_with_mipmaps },
345*c8dee2aaSAndroid Build Coastguard Worker         { "texture_no_mips",   create_gpu_backed_image_no_mipmaps      },
346*c8dee2aaSAndroid Build Coastguard Worker         { "texture_with_mips", create_gpu_backed_image_with_mipmaps    },
347*c8dee2aaSAndroid Build Coastguard Worker         { "picture_backed",    create_picture_backed_image             },
348*c8dee2aaSAndroid Build Coastguard Worker         { "image_generator",   create_bitmap_generator_backed_image    },
349*c8dee2aaSAndroid Build Coastguard Worker     };
350*c8dee2aaSAndroid Build Coastguard Worker 
351*c8dee2aaSAndroid Build Coastguard Worker     const SkIRect kFakeSubset = SkIRect::MakeWH(kImageSize.width(), kImageSize.height());
352*c8dee2aaSAndroid Build Coastguard Worker     const SkIRect kTrueSubset = kFakeSubset.makeInset(4, 4);
353*c8dee2aaSAndroid Build Coastguard Worker 
354*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Recorder> recorderUP = context->makeRecorder();
355*c8dee2aaSAndroid Build Coastguard Worker     auto recorder = recorderUP.get();
356*c8dee2aaSAndroid Build Coastguard Worker 
357*c8dee2aaSAndroid Build Coastguard Worker     for (const auto& test : testcases) {
358*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkImage> orig = test.fFactory(recorder);
359*c8dee2aaSAndroid Build Coastguard Worker         skiatest::ReporterContext subtest(reporter, test.name);
360*c8dee2aaSAndroid Build Coastguard Worker         for (bool mipmapped : {false, true}) {
361*c8dee2aaSAndroid Build Coastguard Worker             skiatest::ReporterContext subtest2(reporter,
362*c8dee2aaSAndroid Build Coastguard Worker                                                SkStringPrintf("mipmaps: %d", (int)mipmapped));
363*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkImage> i = SkImages::TextureFromImage(recorder, orig, {mipmapped});
364*c8dee2aaSAndroid Build Coastguard Worker 
365*c8dee2aaSAndroid Build Coastguard Worker             // makeTextureImage has an optimization which allows Mipmaps on an Image if it
366*c8dee2aaSAndroid Build Coastguard Worker             // would take extra work to remove them.
367*c8dee2aaSAndroid Build Coastguard Worker             bool mipmapOptAllowed = orig->hasMipmaps() && !mipmapped;
368*c8dee2aaSAndroid Build Coastguard Worker 
369*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i->isTextureBacked());
370*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(
371*c8dee2aaSAndroid Build Coastguard Worker                     reporter,
372*c8dee2aaSAndroid Build Coastguard Worker                     (i->hasMipmaps() == mipmapped) || (i->hasMipmaps() && mipmapOptAllowed));
373*c8dee2aaSAndroid Build Coastguard Worker 
374*c8dee2aaSAndroid Build Coastguard Worker             // SkImage::makeSubset should "leave an image where it is", that is, return a
375*c8dee2aaSAndroid Build Coastguard Worker             // texture backed image iff the original image was texture backed. Otherwise,
376*c8dee2aaSAndroid Build Coastguard Worker             // it will return a raster image.
377*c8dee2aaSAndroid Build Coastguard Worker             i = orig->makeSubset(recorder, kTrueSubset, {mipmapped});
378*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, orig->isTextureBacked() == i->isTextureBacked(),
379*c8dee2aaSAndroid Build Coastguard Worker                             "orig texture status %d != subset texture status %d",
380*c8dee2aaSAndroid Build Coastguard Worker                             orig->isTextureBacked(), i->isTextureBacked());
381*c8dee2aaSAndroid Build Coastguard Worker             if (i->isTextureBacked()) {
382*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, i->dimensions() == kTrueSubset.size());
383*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
384*c8dee2aaSAndroid Build Coastguard Worker             }
385*c8dee2aaSAndroid Build Coastguard Worker 
386*c8dee2aaSAndroid Build Coastguard Worker             i = orig->makeSubset(recorder, kFakeSubset, {mipmapped});
387*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, orig->isTextureBacked() == i->isTextureBacked(),
388*c8dee2aaSAndroid Build Coastguard Worker                             "orig texture status %d != subset texture status %d",
389*c8dee2aaSAndroid Build Coastguard Worker                             orig->isTextureBacked(), i->isTextureBacked());
390*c8dee2aaSAndroid Build Coastguard Worker             if (i->isTextureBacked()) {
391*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, i->dimensions() == kFakeSubset.size());
392*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(
393*c8dee2aaSAndroid Build Coastguard Worker                         reporter,
394*c8dee2aaSAndroid Build Coastguard Worker                         i->hasMipmaps() == mipmapped || (i->hasMipmaps() && mipmapOptAllowed));
395*c8dee2aaSAndroid Build Coastguard Worker             }
396*c8dee2aaSAndroid Build Coastguard Worker 
397*c8dee2aaSAndroid Build Coastguard Worker             // SubsetTextureFrom should always return a texture-backed image
398*c8dee2aaSAndroid Build Coastguard Worker             i = SkImages::SubsetTextureFrom(recorder, orig.get(), kTrueSubset, {mipmapped});
399*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i->isTextureBacked());
400*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i->dimensions() == kTrueSubset.size());
401*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
402*c8dee2aaSAndroid Build Coastguard Worker 
403*c8dee2aaSAndroid Build Coastguard Worker             if (!orig->isTextureBacked()) {
404*c8dee2aaSAndroid Build Coastguard Worker                 i = SkImages::TextureFromImage(nullptr, orig, {mipmapped});
405*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, !i);
406*c8dee2aaSAndroid Build Coastguard Worker 
407*c8dee2aaSAndroid Build Coastguard Worker                 // Make sure makeSubset w/o a recorder works as expected
408*c8dee2aaSAndroid Build Coastguard Worker                 i = orig->makeSubset(nullptr, kTrueSubset, {mipmapped});
409*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, !i->isTextureBacked());
410*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, i->dimensions() == kTrueSubset.size());
411*c8dee2aaSAndroid Build Coastguard Worker                 // Picture-backed images don't support mipmaps but check the other types.
412*c8dee2aaSAndroid Build Coastguard Worker                 if (as_IB(i)->type() != SkImage_Base::Type::kLazyPicture) {
413*c8dee2aaSAndroid Build Coastguard Worker                     REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
414*c8dee2aaSAndroid Build Coastguard Worker                 }
415*c8dee2aaSAndroid Build Coastguard Worker 
416*c8dee2aaSAndroid Build Coastguard Worker                 i = orig->makeSubset(nullptr, kFakeSubset, {mipmapped});
417*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, !i->isTextureBacked());
418*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, i->dimensions() == kFakeSubset.size());
419*c8dee2aaSAndroid Build Coastguard Worker                 // Picture-backed images don't support mipmaps but check the other types.
420*c8dee2aaSAndroid Build Coastguard Worker                 if (as_IB(i)->type() != SkImage_Base::Type::kLazyPicture) {
421*c8dee2aaSAndroid Build Coastguard Worker                     REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
422*c8dee2aaSAndroid Build Coastguard Worker                 }
423*c8dee2aaSAndroid Build Coastguard Worker             }
424*c8dee2aaSAndroid Build Coastguard Worker         }
425*c8dee2aaSAndroid Build Coastguard Worker     }
426*c8dee2aaSAndroid Build Coastguard Worker }
427*c8dee2aaSAndroid Build Coastguard Worker 
428*c8dee2aaSAndroid Build Coastguard Worker namespace {
429*c8dee2aaSAndroid Build Coastguard Worker 
pick_colortype(const Caps * caps,bool mipmapped)430*c8dee2aaSAndroid Build Coastguard Worker SkColorType pick_colortype(const Caps* caps, bool mipmapped) {
431*c8dee2aaSAndroid Build Coastguard Worker     auto mm = mipmapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
432*c8dee2aaSAndroid Build Coastguard Worker     TextureInfo info = caps->getDefaultSampledTextureInfo(
433*c8dee2aaSAndroid Build Coastguard Worker             kRGB_565_SkColorType, mm, skgpu::Protected::kNo, skgpu::Renderable::kYes);
434*c8dee2aaSAndroid Build Coastguard Worker     if (info.isValid()) {
435*c8dee2aaSAndroid Build Coastguard Worker         return kRGB_565_SkColorType;
436*c8dee2aaSAndroid Build Coastguard Worker     }
437*c8dee2aaSAndroid Build Coastguard Worker 
438*c8dee2aaSAndroid Build Coastguard Worker     info = caps->getDefaultSampledTextureInfo(
439*c8dee2aaSAndroid Build Coastguard Worker             kRGBA_F16_SkColorType, mm, skgpu::Protected::kNo, skgpu::Renderable::kYes);
440*c8dee2aaSAndroid Build Coastguard Worker     if (info.isValid()) {
441*c8dee2aaSAndroid Build Coastguard Worker         return kRGBA_F16_SkColorType;
442*c8dee2aaSAndroid Build Coastguard Worker     }
443*c8dee2aaSAndroid Build Coastguard Worker 
444*c8dee2aaSAndroid Build Coastguard Worker     return kUnknown_SkColorType;
445*c8dee2aaSAndroid Build Coastguard Worker }
446*c8dee2aaSAndroid Build Coastguard Worker 
447*c8dee2aaSAndroid Build Coastguard Worker } // anonymous namespace
448*c8dee2aaSAndroid Build Coastguard Worker 
449*c8dee2aaSAndroid Build Coastguard Worker // Here we're testing that the RequiredProperties parameter of:
450*c8dee2aaSAndroid Build Coastguard Worker //    SkImage::makeColorSpace and
451*c8dee2aaSAndroid Build Coastguard Worker //    SkImage::makeColorTypeAndColorSpace
452*c8dee2aaSAndroid Build Coastguard Worker // works as expected.
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(MakeColorSpace_Test,reporter,context,CtsEnforcement::kApiLevel_V)453*c8dee2aaSAndroid Build Coastguard Worker DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(MakeColorSpace_Test, reporter, context,
454*c8dee2aaSAndroid Build Coastguard Worker                                          CtsEnforcement::kApiLevel_V) {
455*c8dee2aaSAndroid Build Coastguard Worker     static const struct {
456*c8dee2aaSAndroid Build Coastguard Worker         std::string name;
457*c8dee2aaSAndroid Build Coastguard Worker         FactoryT fFactory;
458*c8dee2aaSAndroid Build Coastguard Worker         bool     fTextureBacked;
459*c8dee2aaSAndroid Build Coastguard Worker     } testcases[] = {
460*c8dee2aaSAndroid Build Coastguard Worker             { "raster_no_mips",    create_raster_backed_image_no_mipmaps,   false },
461*c8dee2aaSAndroid Build Coastguard Worker             { "raster_with_mips",  create_raster_backed_image_with_mipmaps, false },
462*c8dee2aaSAndroid Build Coastguard Worker             { "texture_no_mips",   create_gpu_backed_image_no_mipmaps,      true  },
463*c8dee2aaSAndroid Build Coastguard Worker             { "texture_with_mips", create_gpu_backed_image_with_mipmaps,    true  },
464*c8dee2aaSAndroid Build Coastguard Worker             { "picture_backed",    create_picture_backed_image,             false },
465*c8dee2aaSAndroid Build Coastguard Worker             { "image_generator",   create_bitmap_generator_backed_image,    false },
466*c8dee2aaSAndroid Build Coastguard Worker     };
467*c8dee2aaSAndroid Build Coastguard Worker 
468*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorSpace> spin = SkColorSpace::MakeSRGB()->makeColorSpin();
469*c8dee2aaSAndroid Build Coastguard Worker 
470*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Recorder> recorder = context->makeRecorder();
471*c8dee2aaSAndroid Build Coastguard Worker 
472*c8dee2aaSAndroid Build Coastguard Worker     const Caps* caps = recorder->priv().caps();
473*c8dee2aaSAndroid Build Coastguard Worker 
474*c8dee2aaSAndroid Build Coastguard Worker     for (const auto& testcase : testcases) {
475*c8dee2aaSAndroid Build Coastguard Worker         skiatest::ReporterContext subtest(reporter, testcase.name);
476*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkImage> orig = testcase.fFactory(recorder.get());
477*c8dee2aaSAndroid Build Coastguard Worker 
478*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(orig->colorType() == kRGBA_8888_SkColorType ||
479*c8dee2aaSAndroid Build Coastguard Worker                  orig->colorType() == kBGRA_8888_SkColorType);
480*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!orig->colorSpace() || orig->colorSpace() == SkColorSpace::MakeSRGB().get());
481*c8dee2aaSAndroid Build Coastguard Worker 
482*c8dee2aaSAndroid Build Coastguard Worker         for (bool mipmapped : {false, true}) {
483*c8dee2aaSAndroid Build Coastguard Worker             skiatest::ReporterContext subtest2(reporter,
484*c8dee2aaSAndroid Build Coastguard Worker                                                SkStringPrintf("mipmaps: %d", (int)mipmapped));
485*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkImage> i = orig->makeColorSpace(recorder.get(), spin, {mipmapped});
486*c8dee2aaSAndroid Build Coastguard Worker 
487*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i != nullptr);
488*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i->isTextureBacked() == testcase.fTextureBacked);
489*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i->colorSpace() == spin.get());
490*c8dee2aaSAndroid Build Coastguard Worker             if (testcase.fTextureBacked) {
491*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
492*c8dee2aaSAndroid Build Coastguard Worker             } else {
493*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, !i->hasMipmaps());
494*c8dee2aaSAndroid Build Coastguard Worker             }
495*c8dee2aaSAndroid Build Coastguard Worker 
496*c8dee2aaSAndroid Build Coastguard Worker             SkColorType altCT = pick_colortype(caps, mipmapped);
497*c8dee2aaSAndroid Build Coastguard Worker             i = orig->makeColorTypeAndColorSpace(recorder.get(), altCT, spin, {mipmapped});
498*c8dee2aaSAndroid Build Coastguard Worker 
499*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i != nullptr);
500*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i->isTextureBacked() == testcase.fTextureBacked);
501*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i->colorType() == altCT);
502*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, i->colorSpace() == spin.get());
503*c8dee2aaSAndroid Build Coastguard Worker             if (testcase.fTextureBacked) {
504*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
505*c8dee2aaSAndroid Build Coastguard Worker             } else {
506*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, !i->hasMipmaps());
507*c8dee2aaSAndroid Build Coastguard Worker             }
508*c8dee2aaSAndroid Build Coastguard Worker         }
509*c8dee2aaSAndroid Build Coastguard Worker     }
510*c8dee2aaSAndroid Build Coastguard Worker }
511