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