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/SkTileMode.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Context.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Surface.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Image.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Recorder.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Surface_Graphite.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/shaders/SkImageShader.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h"
19*c8dee2aaSAndroid Build Coastguard Worker
20*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
21*c8dee2aaSAndroid Build Coastguard Worker
22*c8dee2aaSAndroid Build Coastguard Worker namespace {
23*c8dee2aaSAndroid Build Coastguard Worker
24*c8dee2aaSAndroid Build Coastguard Worker constexpr SkColor4f kRectColor = SkColors::kRed;
25*c8dee2aaSAndroid Build Coastguard Worker constexpr SkColor4f kBgColor = SkColors::kTransparent;
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Worker struct Expectation {
28*c8dee2aaSAndroid Build Coastguard Worker SkPoint pos;
29*c8dee2aaSAndroid Build Coastguard Worker SkColor4f color;
30*c8dee2aaSAndroid Build Coastguard Worker };
31*c8dee2aaSAndroid Build Coastguard Worker
test_draw(skiatest::Reporter * reporter,Context * context,SkISize canvasSize,SkISize imageSize,SkRect srcRect,SkRect dstRect,SkTileMode tileMode,SkSamplingOptions samplingOptions,std::vector<Expectation> expectations)32*c8dee2aaSAndroid Build Coastguard Worker void test_draw(skiatest::Reporter* reporter,
33*c8dee2aaSAndroid Build Coastguard Worker Context* context,
34*c8dee2aaSAndroid Build Coastguard Worker SkISize canvasSize,
35*c8dee2aaSAndroid Build Coastguard Worker SkISize imageSize,
36*c8dee2aaSAndroid Build Coastguard Worker SkRect srcRect,
37*c8dee2aaSAndroid Build Coastguard Worker SkRect dstRect,
38*c8dee2aaSAndroid Build Coastguard Worker SkTileMode tileMode,
39*c8dee2aaSAndroid Build Coastguard Worker SkSamplingOptions samplingOptions,
40*c8dee2aaSAndroid Build Coastguard Worker std::vector<Expectation> expectations) {
41*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Recorder> recorder = context->makeRecorder();
42*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, recorder);
43*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(
44*c8dee2aaSAndroid Build Coastguard Worker recorder.get(),
45*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo::Make(canvasSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
46*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* canvas = surface->getCanvas();
47*c8dee2aaSAndroid Build Coastguard Worker
48*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
49*c8dee2aaSAndroid Build Coastguard Worker bitmap.allocPixels(SkImageInfo::Make(imageSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType),
50*c8dee2aaSAndroid Build Coastguard Worker 0);
51*c8dee2aaSAndroid Build Coastguard Worker bitmap.eraseColor(kRectColor);
52*c8dee2aaSAndroid Build Coastguard Worker bitmap.setImmutable();
53*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> image = SkImages::TextureFromImage(recorder.get(), bitmap.asImage(),
54*c8dee2aaSAndroid Build Coastguard Worker {/*fMipmapped=*/false});
55*c8dee2aaSAndroid Build Coastguard Worker
56*c8dee2aaSAndroid Build Coastguard Worker SkPaint p;
57*c8dee2aaSAndroid Build Coastguard Worker SkMatrix srcToDst = SkMatrix::RectToRect(srcRect, dstRect);
58*c8dee2aaSAndroid Build Coastguard Worker p.setShader(SkImageShader::MakeSubset(
59*c8dee2aaSAndroid Build Coastguard Worker std::move(image), srcRect, tileMode, tileMode, samplingOptions, &srcToDst));
60*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(dstRect, p);
61*c8dee2aaSAndroid Build Coastguard Worker
62*c8dee2aaSAndroid Build Coastguard Worker SkPixmap pm;
63*c8dee2aaSAndroid Build Coastguard Worker
64*c8dee2aaSAndroid Build Coastguard Worker SkBitmap result;
65*c8dee2aaSAndroid Build Coastguard Worker result.allocPixels(SkImageInfo::Make(canvasSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
66*c8dee2aaSAndroid Build Coastguard Worker bool peekPixelsSuccess = result.peekPixels(&pm);
67*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, peekPixelsSuccess);
68*c8dee2aaSAndroid Build Coastguard Worker
69*c8dee2aaSAndroid Build Coastguard Worker bool readPixelsSuccess = surface->readPixels(pm, 0, 0);
70*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, readPixelsSuccess);
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker for (const Expectation& e : expectations) {
73*c8dee2aaSAndroid Build Coastguard Worker SkColor4f a = e.color;
74*c8dee2aaSAndroid Build Coastguard Worker SkColor4f b = pm.getColor4f(e.pos.fX, e.pos.fY);
75*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
76*c8dee2aaSAndroid Build Coastguard Worker a == b,
77*c8dee2aaSAndroid Build Coastguard Worker "At position {%.1f, %.1f}, "
78*c8dee2aaSAndroid Build Coastguard Worker "expected {%.1f, %.1f, %.1f, %.1f}, "
79*c8dee2aaSAndroid Build Coastguard Worker "found {%.1f, %.1f, %.1f, %.1f}",
80*c8dee2aaSAndroid Build Coastguard Worker e.pos.fX, e.pos.fY,
81*c8dee2aaSAndroid Build Coastguard Worker a.fR, a.fG, a.fB, a.fA,
82*c8dee2aaSAndroid Build Coastguard Worker b.fR, b.fG, b.fB, b.fA);
83*c8dee2aaSAndroid Build Coastguard Worker }
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker
86*c8dee2aaSAndroid Build Coastguard Worker } // anonymous namespace
87*c8dee2aaSAndroid Build Coastguard Worker
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageShaderTest,reporter,context,CtsEnforcement::kApiLevel_V)88*c8dee2aaSAndroid Build Coastguard Worker DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageShaderTest, reporter, context,
89*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_V) {
90*c8dee2aaSAndroid Build Coastguard Worker // Test that a subset bound covering less than half of a pixel causes that pixel not to be
91*c8dee2aaSAndroid Build Coastguard Worker // drawn when using decal tiling and nearest-neighbor filtering. In this case we have a subset
92*c8dee2aaSAndroid Build Coastguard Worker // that covers 3/4 the pixel column at y=1, all of the y=2 column, and 1/4 the y=3 column.
93*c8dee2aaSAndroid Build Coastguard Worker test_draw(reporter,
94*c8dee2aaSAndroid Build Coastguard Worker context,
95*c8dee2aaSAndroid Build Coastguard Worker /*canvasSize=*/SkISize::Make(100, 100),
96*c8dee2aaSAndroid Build Coastguard Worker /*imageSize=*/SkISize::Make(4, 4),
97*c8dee2aaSAndroid Build Coastguard Worker /*srcRect=*/SkRect::MakeLTRB(1.25, 0.0f, 3.25f, 2.0f),
98*c8dee2aaSAndroid Build Coastguard Worker /*dstRect=*/SkRect::MakeLTRB(0, 0, 80, 80),
99*c8dee2aaSAndroid Build Coastguard Worker SkTileMode::kDecal,
100*c8dee2aaSAndroid Build Coastguard Worker SkSamplingOptions(),
101*c8dee2aaSAndroid Build Coastguard Worker
102*c8dee2aaSAndroid Build Coastguard Worker // Pixel that should sample the image at y=1, since that's where the subset starts.
103*c8dee2aaSAndroid Build Coastguard Worker {{{0, 40}, kRectColor},
104*c8dee2aaSAndroid Build Coastguard Worker // Pixel that would sample the image at y=3, but the subset bound at y=3.25 prevents
105*c8dee2aaSAndroid Build Coastguard Worker // us from sampling the image.
106*c8dee2aaSAndroid Build Coastguard Worker {{75, 40}, kBgColor}});
107*c8dee2aaSAndroid Build Coastguard Worker }
108*c8dee2aaSAndroid Build Coastguard Worker
109*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
110