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