xref: /aosp_15_r20/external/skia/tests/graphite/ImageWrapTextureMipmapsTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2024 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 "tests/Test.h"
9 
10 #include "include/core/SkCanvas.h"
11 #include "include/gpu/graphite/BackendTexture.h"
12 #include "include/gpu/graphite/Context.h"
13 #include "include/gpu/graphite/Image.h"
14 #include "include/gpu/graphite/Recorder.h"
15 #include "include/gpu/graphite/Surface.h"
16 #include "src/core/SkAutoPixmapStorage.h"
17 #include "src/gpu/graphite/Caps.h"
18 #include "src/gpu/graphite/ContextPriv.h"
19 #include "tools/gpu/ManagedBackendTexture.h"
20 #include "tools/graphite/GraphiteTestContext.h"
21 
22 using namespace skgpu;
23 using namespace skgpu::graphite;
24 
DEF_CONDITIONAL_GRAPHITE_TEST_FOR_ALL_CONTEXTS(ImageWrapTextureMipmapsTest,reporter,context,testContext,true,CtsEnforcement::kApiLevel_V)25 DEF_CONDITIONAL_GRAPHITE_TEST_FOR_ALL_CONTEXTS(ImageWrapTextureMipmapsTest,
26                                                reporter,
27                                                context,
28                                                testContext,
29                                                true,
30                                                CtsEnforcement::kApiLevel_V) {
31     auto recorder = context->makeRecorder();
32     if (!recorder) {
33         ERRORF(reporter, "Could not make recorder");
34         return;
35     }
36 
37     skgpu::Protected isProtected = skgpu::Protected(context->priv().caps()->protectedSupport());
38 
39     auto info = SkImageInfo::Make({2, 1}, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
40     SkAutoPixmapStorage basePM, topPM;
41     basePM.alloc(info);
42     basePM.erase(SK_ColorGREEN);
43     topPM.alloc(info.makeDimensions({1, 1}));
44     topPM.erase(SK_ColorBLUE);
45 
46     SkPixmap levelPMs[]{basePM, topPM};
47     auto mbet = sk_gpu_test::ManagedGraphiteTexture::MakeMipmappedFromPixmaps(recorder.get(),
48                                                                               levelPMs,
49                                                                               Renderable::kNo,
50                                                                               isProtected);
51 
52     if (!mbet) {
53         ERRORF(reporter, "Could not make backend texture");
54         return;
55     }
56 
57     std::unique_ptr<Recording> recording = recorder->snap();
58 
59     auto recordingFinishProc = [](void* context, CallbackResult) {
60         std::unique_ptr<Recording>(static_cast<Recording*>(context));
61     };
62 
63     skgpu::graphite::InsertRecordingInfo recordingInfo;
64     recordingInfo.fFinishedProc = recordingFinishProc;
65     recordingInfo.fRecording = recording.get();
66     recordingInfo.fFinishedContext = recording.release();
67     if (!context->insertRecording(recordingInfo)) {
68         ERRORF(reporter, "Could not insert recording");
69         return;
70     }
71 
72     static constexpr struct TestCase {
73         SkImages::GenerateMipmapsFromBase genMipmaps;
74         SkColor expectedColor;
75     } kTestCases[]{{SkImages::GenerateMipmapsFromBase::kNo , 0xFFFF0000},
76                    {SkImages::GenerateMipmapsFromBase::kYes, 0XFF00FF00}};
77 
78     for (const auto& testCase : kTestCases) {
79         recorder = context->makeRecorder();
80         if (!recorder) {
81             ERRORF(reporter, "Could not make recorder");
82             return;
83         }
84 
85         auto image = SkImages::WrapTexture(recorder.get(),
86                                            mbet->texture(),
87                                            info.colorType(),
88                                            info.alphaType(),
89                                            info.refColorSpace(),
90                                            Origin::kTopLeft,
91                                            testCase.genMipmaps,
92                                            sk_gpu_test::ManagedGraphiteTexture::ImageReleaseProc,
93                                            mbet->releaseContext());
94         if (!recorder) {
95             ERRORF(reporter, "Could not make image");
96             return;
97         }
98 
99         // We determe the contents of the image's top level by doing a downsampling draw to a
100         // surface and then reading the surface's contents.
101         auto surface = SkSurfaces::RenderTarget(recorder.get(), info.makeDimensions({1, 1}));
102         if (!recorder) {
103             ERRORF(reporter, "Could not make surface");
104             return;
105         }
106 
107         auto shader = image->makeShader(
108                 SkTileMode::kRepeat,
109                 SkTileMode::kRepeat,
110                 SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNearest));
111 
112         surface->getCanvas()->scale(0.05f, 0.05f);
113         SkPaint paint;
114         paint.setShader(std::move(shader));
115         surface->getCanvas()->drawPaint(paint);
116 
117         recording = recorder->snap();
118         recordingInfo.fRecording = recording.get();
119         recordingInfo.fFinishedContext = recording.release();
120         if (!context->insertRecording(recordingInfo)) {
121             ERRORF(reporter, "Could not insert recording");
122             return;
123         }
124 
125         struct ReadContext {
126             bool called = false;
127             bool success = false;
128             uint32_t color;
129         };
130         auto readPixelsCallback = [](SkImage::ReadPixelsContext context,
131                                      std::unique_ptr<const SkImage::AsyncReadResult> result) {
132             auto& readContext = *static_cast<ReadContext*>(context);
133             readContext.called = true;
134             if (result) {
135                 readContext.success = true;
136                 readContext.color = *static_cast<const uint32_t*>(result->data(0));
137             }
138         };
139         ReadContext readContext;
140         context->asyncRescaleAndReadPixels(surface.get(),
141                                            surface->imageInfo(),
142                                            SkIRect::MakeSize(surface->imageInfo().dimensions()),
143                                            SkImage::RescaleGamma::kSrc,
144                                            SkImage::RescaleMode::kNearest,
145                                            readPixelsCallback,
146                                            &readContext);
147         context->submit();
148         while (!readContext.called) {
149             testContext->tick();
150             context->checkAsyncWorkCompletion();
151         }
152 
153         if (!readContext.success) {
154             ERRORF(reporter, "Read pixels failed");
155             return;
156         }
157 
158         REPORTER_ASSERT(reporter, readContext.color == testCase.expectedColor);
159     }
160 }
161