xref: /aosp_15_r20/external/skia/tests/graphite/ImageOriginTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2023 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/SkBitmap.h"
11 #include "include/core/SkColorSpace.h"
12 #include "include/core/SkRect.h"
13 #include "include/core/SkTileMode.h"
14 #include "include/gpu/graphite/Context.h"
15 #include "include/gpu/graphite/Image.h"
16 #include "include/gpu/graphite/Surface.h"
17 #include "src/gpu/graphite/Caps.h"
18 #include "src/gpu/graphite/ContextPriv.h"
19 #include "src/gpu/graphite/Surface_Graphite.h"
20 #include "src/shaders/SkImageShader.h"
21 #include "tools/ToolUtils.h"
22 #include "tools/gpu/ManagedBackendTexture.h"
23 
24 namespace skgpu::graphite {
25 
26 namespace {
27 
28 using DrawFn = void (*)(sk_sp<SkImage>, SkCanvas*, SkRect /*srcRect*/, SkRect /*dstRect*/);
29 
30 constexpr SkColor4f kTopColor = SkColors::kRed;
31 constexpr SkColor4f kBottomColor = SkColors::kBlue;
32 constexpr int32_t kHalfSize = 4;
33 constexpr SkISize kImageSize = {2*kHalfSize, 2*kHalfSize};
34 
test_draw(skiatest::Reporter * reporter,Context * context,skgpu::Origin origin,SkRect srcRect,SkRect dstRect,DrawFn drawImageFn)35 void test_draw(skiatest::Reporter* reporter,
36                Context* context,
37                skgpu::Origin origin,
38                SkRect srcRect,
39                SkRect dstRect,
40                DrawFn drawImageFn) {
41     std::unique_ptr<Recorder> recorder = context->makeRecorder();
42 
43     skgpu::Protected isProtected = skgpu::Protected(context->priv().caps()->protectedSupport());
44 
45     SkBitmap bitmap;
46     bitmap.allocPixels(SkImageInfo::Make(kImageSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType),
47                        0);
48     bitmap.eraseColor(kTopColor);
49     bitmap.erase(kBottomColor,
50                  SkIRect::MakeLTRB(0, kHalfSize, kImageSize.width(), kImageSize.height()));
51 
52     auto managedTexture =
53             sk_gpu_test::ManagedGraphiteTexture::MakeFromPixmap(recorder.get(),
54                                                                 bitmap.pixmap(),
55                                                                 skgpu::Mipmapped::kNo,
56                                                                 skgpu::Renderable::kNo,
57                                                                 isProtected);
58 
59     REPORTER_ASSERT(reporter, managedTexture);
60     if (!managedTexture) {
61         return;
62     }
63 
64     sk_sp<SkImage> image = SkImages::WrapTexture(recorder.get(),
65                                                  managedTexture->texture(),
66                                                  kRGBA_8888_SkColorType,
67                                                  kPremul_SkAlphaType,
68                                                  /*colorSpace=*/nullptr,
69                                                  origin);
70 
71     REPORTER_ASSERT(reporter, image);
72     if (!image) {
73         return;
74     }
75 
76     sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(
77             recorder.get(),
78             SkImageInfo::Make(kImageSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
79 
80     REPORTER_ASSERT(reporter, surface);
81     if (!surface) {
82         return;
83     }
84 
85     SkCanvas* canvas = surface->getCanvas();
86 
87     drawImageFn(image, canvas, srcRect, dstRect);
88 
89     SkPixmap pm;
90 
91     SkBitmap result;
92     result.allocPixels(SkImageInfo::Make(kImageSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
93     bool peekPixelsSuccess = result.peekPixels(&pm);
94     REPORTER_ASSERT(reporter, peekPixelsSuccess);
95 
96     bool readPixelsSuccess = surface->readPixels(pm, 0, 0);
97     REPORTER_ASSERT(reporter, readPixelsSuccess);
98 
99     bool resultTopColorOnTop = origin == skgpu::Origin::kTopLeft;
100 
101     for (int32_t y = 0; y < kImageSize.height(); ++y) {
102         for (int32_t x = 0; x < kImageSize.width(); ++x) {
103             SkColor4f color = pm.getColor4f(x, y);
104 
105             SkColor4f expectedColor = ((y < kHalfSize) == resultTopColorOnTop) ? kTopColor
106                                                                                : kBottomColor;
107             REPORTER_ASSERT(reporter,
108                             color == expectedColor,
109                             "At position {%d, %d}, "
110                             "expected {%.1f, %.1f, %.1f, %.1f}, "
111                             "found {%.1f, %.1f, %.1f, %.1f}",
112                             x, y,
113                             expectedColor.fR, expectedColor.fG, expectedColor.fB, expectedColor.fA,
114                             color.fR, color.fG, color.fB, color.fA);
115         }
116     }
117 }
118 
119 const SkRect kTestSrcRects[] = {
120     // entire thing
121     SkRect::MakeWH(kImageSize.width(), kImageSize.height()),
122     // half rect still splitting top and bottom colors
123     SkRect::MakeXYWH(2, 2, kHalfSize, kHalfSize),
124 };
125 
test_draw_fn(skiatest::Reporter * reporter,Context * context,DrawFn drawImageFn)126 void test_draw_fn(skiatest::Reporter* reporter,
127                   Context* context,
128                   DrawFn drawImageFn) {
129     for (auto origin : {skgpu::Origin::kTopLeft, skgpu::Origin::kBottomLeft}) {
130         for (auto srcRect: kTestSrcRects) {
131             test_draw(reporter,
132                       context,
133                       origin,
134                       srcRect,
135                       SkRect::MakeWH(kImageSize.width(), kImageSize.height()),
136                       drawImageFn);
137         }
138     }
139 }
140 
draw_image(sk_sp<SkImage> image,SkCanvas * canvas,SkRect srcRect,SkRect dstRect)141 void draw_image(sk_sp<SkImage> image,
142                 SkCanvas* canvas,
143                 SkRect srcRect,
144                 SkRect dstRect) {
145     canvas->drawImageRect(image,
146                           srcRect,
147                           dstRect,
148                           SkSamplingOptions(),
149                           /*paint=*/nullptr,
150                           SkCanvas::kStrict_SrcRectConstraint);
151 }
152 
draw_image_with_shader(sk_sp<SkImage> image,SkCanvas * canvas,SkRect srcRect,SkRect dstRect)153 void draw_image_with_shader(sk_sp<SkImage> image,
154                             SkCanvas* canvas,
155                             SkRect srcRect,
156                             SkRect dstRect) {
157     SkPaint p;
158     SkMatrix srcToDst = SkMatrix::RectToRect(srcRect, dstRect);
159     p.setShader(SkImageShader::MakeSubset(
160                 std::move(image),
161                 srcRect,
162                 SkTileMode::kClamp,
163                 SkTileMode::kClamp,
164                 SkSamplingOptions(),
165                 &srcToDst));
166     canvas->drawRect(dstRect, p);
167 }
168 
169 }  // anonymous namespace
170 
171 
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageOriginTest_drawImage_Graphite,reporter,context,CtsEnforcement::kApiLevel_V)172 DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageOriginTest_drawImage_Graphite, reporter, context,
173                                          CtsEnforcement::kApiLevel_V) {
174     test_draw_fn(reporter, context, draw_image);
175 }
176 
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageOriginTest_imageShader_Graphite,reporter,context,CtsEnforcement::kApiLevel_V)177 DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageOriginTest_imageShader_Graphite, reporter, context,
178                                          CtsEnforcement::kApiLevel_V) {
179     test_draw_fn(reporter, context, draw_image_with_shader);
180 }
181 
182 }  // namespace skgpu::graphite
183