1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2021 Google Inc.
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 "include/core/SkAlphaType.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlendMode.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSamplingOptions.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurfaceProps.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkVertices.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrContextOptions.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkImageGanesh.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkBlendModePriv.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/SkBackingFit.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPaint.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPixmap.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrXferProcessor.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SurfaceDrawContext.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ContextType.h"
47*c8dee2aaSAndroid Build Coastguard Worker
48*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
49*c8dee2aaSAndroid Build Coastguard Worker #include <cstring>
50*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
51*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
52*c8dee2aaSAndroid Build Coastguard Worker
53*c8dee2aaSAndroid Build Coastguard Worker namespace {
54*c8dee2aaSAndroid Build Coastguard Worker
55*c8dee2aaSAndroid Build Coastguard Worker static SkSurfaceProps kDMSAAProps(SkSurfaceProps::kDynamicMSAA_Flag, kUnknown_SkPixelGeometry);
56*c8dee2aaSAndroid Build Coastguard Worker static SkSurfaceProps kBasicProps(0, kUnknown_SkPixelGeometry);
57*c8dee2aaSAndroid Build Coastguard Worker constexpr static SkPMColor4f kTransYellow = {.5f,.5f,.0f,.5f};
58*c8dee2aaSAndroid Build Coastguard Worker constexpr static SkPMColor4f kTransCyan = {.0f,.5f,.5f,.5f};
59*c8dee2aaSAndroid Build Coastguard Worker constexpr static int kWidth=10, kHeight=10;
60*c8dee2aaSAndroid Build Coastguard Worker
61*c8dee2aaSAndroid Build Coastguard Worker }
62*c8dee2aaSAndroid Build Coastguard Worker
draw_paint_with_aa(skgpu::ganesh::SurfaceDrawContext * sdc,const SkPMColor4f & color,SkBlendMode blendMode)63*c8dee2aaSAndroid Build Coastguard Worker static void draw_paint_with_aa(skgpu::ganesh::SurfaceDrawContext* sdc,
64*c8dee2aaSAndroid Build Coastguard Worker const SkPMColor4f& color,
65*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode blendMode) {
66*c8dee2aaSAndroid Build Coastguard Worker GrPaint paint;
67*c8dee2aaSAndroid Build Coastguard Worker paint.setColor4f(color);
68*c8dee2aaSAndroid Build Coastguard Worker paint.setXPFactory(GrXPFactory::FromBlendMode(blendMode));
69*c8dee2aaSAndroid Build Coastguard Worker sdc->drawRect(nullptr, std::move(paint), GrAA::kYes, SkMatrix::I(),
70*c8dee2aaSAndroid Build Coastguard Worker SkRect::MakeIWH(kWidth, kHeight), nullptr);
71*c8dee2aaSAndroid Build Coastguard Worker }
72*c8dee2aaSAndroid Build Coastguard Worker
draw_paint_with_dmsaa(skgpu::ganesh::SurfaceDrawContext * sdc,const SkPMColor4f & color,SkBlendMode blendMode)73*c8dee2aaSAndroid Build Coastguard Worker static void draw_paint_with_dmsaa(skgpu::ganesh::SurfaceDrawContext* sdc,
74*c8dee2aaSAndroid Build Coastguard Worker const SkPMColor4f& color,
75*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode blendMode) {
76*c8dee2aaSAndroid Build Coastguard Worker // drawVertices should always trigger dmsaa, but draw something non-rectangular just to be 100%
77*c8dee2aaSAndroid Build Coastguard Worker // certain.
78*c8dee2aaSAndroid Build Coastguard Worker static const SkPoint kVertices[3] = {{-.5f,-.5f}, {kWidth * 2.1f, 0}, {0, kHeight * 2.1f}};
79*c8dee2aaSAndroid Build Coastguard Worker SkVertices::Builder builder(SkVertices::kTriangles_VertexMode, 3, 0, 0);
80*c8dee2aaSAndroid Build Coastguard Worker memcpy(builder.positions(), kVertices, sizeof(kVertices));
81*c8dee2aaSAndroid Build Coastguard Worker auto vertices = builder.detach();
82*c8dee2aaSAndroid Build Coastguard Worker
83*c8dee2aaSAndroid Build Coastguard Worker GrPaint paint;
84*c8dee2aaSAndroid Build Coastguard Worker paint.setColor4f(color);
85*c8dee2aaSAndroid Build Coastguard Worker paint.setXPFactory(GrXPFactory::FromBlendMode(blendMode));
86*c8dee2aaSAndroid Build Coastguard Worker sdc->drawVertices(nullptr, std::move(paint), SkMatrix::I(), vertices);
87*c8dee2aaSAndroid Build Coastguard Worker }
88*c8dee2aaSAndroid Build Coastguard Worker
fuzzy_equals(const float a[4],const SkPMColor4f & b)89*c8dee2aaSAndroid Build Coastguard Worker static bool fuzzy_equals(const float a[4], const SkPMColor4f& b) {
90*c8dee2aaSAndroid Build Coastguard Worker constexpr static float kTolerance = 2.5f / 256;
91*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < 4; ++i) {
92*c8dee2aaSAndroid Build Coastguard Worker if (!SkScalarNearlyEqual(a[i], b.vec()[i], kTolerance)) {
93*c8dee2aaSAndroid Build Coastguard Worker return false;
94*c8dee2aaSAndroid Build Coastguard Worker }
95*c8dee2aaSAndroid Build Coastguard Worker }
96*c8dee2aaSAndroid Build Coastguard Worker return true;
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker
check_sdc_color(skiatest::Reporter * reporter,skgpu::ganesh::SurfaceDrawContext * sdc,GrDirectContext * ctx,const SkPMColor4f & color)99*c8dee2aaSAndroid Build Coastguard Worker static void check_sdc_color(skiatest::Reporter* reporter,
100*c8dee2aaSAndroid Build Coastguard Worker skgpu::ganesh::SurfaceDrawContext* sdc,
101*c8dee2aaSAndroid Build Coastguard Worker GrDirectContext* ctx,
102*c8dee2aaSAndroid Build Coastguard Worker const SkPMColor4f& color) {
103*c8dee2aaSAndroid Build Coastguard Worker auto info = SkImageInfo::Make(kWidth, kHeight, kRGBA_F32_SkColorType, kPremul_SkAlphaType);
104*c8dee2aaSAndroid Build Coastguard Worker GrPixmap pixmap = GrPixmap::Allocate(info);
105*c8dee2aaSAndroid Build Coastguard Worker sdc->readPixels(ctx, pixmap, {0, 0});
106*c8dee2aaSAndroid Build Coastguard Worker auto pix = static_cast<const float*>(pixmap.addr());
107*c8dee2aaSAndroid Build Coastguard Worker for (int y = 0; y < kHeight; ++y) {
108*c8dee2aaSAndroid Build Coastguard Worker for (int x = 0; x < kWidth; ++x) {
109*c8dee2aaSAndroid Build Coastguard Worker if (!fuzzy_equals(pix, color)) {
110*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "SDC color mismatch.\n"
111*c8dee2aaSAndroid Build Coastguard Worker "Got [%0.3f, %0.3f, %0.3f, %0.3f]\n"
112*c8dee2aaSAndroid Build Coastguard Worker "Expected [%0.3f, %0.3f, %0.3f, %0.3f]",
113*c8dee2aaSAndroid Build Coastguard Worker pix[0], pix[1], pix[2], pix[3], color.fR, color.fG, color.fB, color.fA);
114*c8dee2aaSAndroid Build Coastguard Worker return;
115*c8dee2aaSAndroid Build Coastguard Worker }
116*c8dee2aaSAndroid Build Coastguard Worker pix += 4;
117*c8dee2aaSAndroid Build Coastguard Worker }
118*c8dee2aaSAndroid Build Coastguard Worker }
119*c8dee2aaSAndroid Build Coastguard Worker }
120*c8dee2aaSAndroid Build Coastguard Worker
121*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_CONTEXTS(DMSAA_preserve_contents,
122*c8dee2aaSAndroid Build Coastguard Worker &skgpu::IsRenderingContext,
123*c8dee2aaSAndroid Build Coastguard Worker reporter,
124*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
125*c8dee2aaSAndroid Build Coastguard Worker nullptr,
126*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
127*c8dee2aaSAndroid Build Coastguard Worker auto dContext = ctxInfo.directContext();
128*c8dee2aaSAndroid Build Coastguard Worker auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext,
129*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kRGBA_8888,
130*c8dee2aaSAndroid Build Coastguard Worker nullptr,
131*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kApprox,
132*c8dee2aaSAndroid Build Coastguard Worker {kWidth, kHeight},
133*c8dee2aaSAndroid Build Coastguard Worker kDMSAAProps,
134*c8dee2aaSAndroid Build Coastguard Worker /*label=*/{});
135*c8dee2aaSAndroid Build Coastguard Worker
136*c8dee2aaSAndroid Build Coastguard Worker // Initialize the texture and dmsaa attachment with transparent.
137*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_dmsaa(sdc.get(), SK_PMColor4fTRANSPARENT, SkBlendMode::kSrc);
138*c8dee2aaSAndroid Build Coastguard Worker check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
139*c8dee2aaSAndroid Build Coastguard Worker
140*c8dee2aaSAndroid Build Coastguard Worker // Clear the main texture to yellow.
141*c8dee2aaSAndroid Build Coastguard Worker sdc->clear(kTransYellow);
142*c8dee2aaSAndroid Build Coastguard Worker
143*c8dee2aaSAndroid Build Coastguard Worker // Close the opsTask by doing a readback.
144*c8dee2aaSAndroid Build Coastguard Worker check_sdc_color(reporter, sdc.get(), dContext, kTransYellow);
145*c8dee2aaSAndroid Build Coastguard Worker
146*c8dee2aaSAndroid Build Coastguard Worker // Now the DMSAA attachment is clear and the texture is yellow. Blend cyan into the DMSAA
147*c8dee2aaSAndroid Build Coastguard Worker // attachment. This will fail if the yellow from the main texture doesn't get copied into the
148*c8dee2aaSAndroid Build Coastguard Worker // DMSAA attachment before the renderPass.
149*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_dmsaa(sdc.get(), kTransCyan, SkBlendMode::kSrcOver);
150*c8dee2aaSAndroid Build Coastguard Worker SkPMColor4f dstColor = SkBlendMode_Apply(SkBlendMode::kSrcOver, kTransCyan, kTransYellow);
151*c8dee2aaSAndroid Build Coastguard Worker
152*c8dee2aaSAndroid Build Coastguard Worker check_sdc_color(reporter, sdc.get(), dContext, dstColor);
153*c8dee2aaSAndroid Build Coastguard Worker }
154*c8dee2aaSAndroid Build Coastguard Worker
require_dst_reads(GrContextOptions * options)155*c8dee2aaSAndroid Build Coastguard Worker static void require_dst_reads(GrContextOptions* options) {
156*c8dee2aaSAndroid Build Coastguard Worker options->fSuppressAdvancedBlendEquations = true;
157*c8dee2aaSAndroid Build Coastguard Worker options->fSuppressFramebufferFetch = true;
158*c8dee2aaSAndroid Build Coastguard Worker }
159*c8dee2aaSAndroid Build Coastguard Worker
160*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_CONTEXTS(DMSAA_dst_read,
161*c8dee2aaSAndroid Build Coastguard Worker &skgpu::IsRenderingContext,
162*c8dee2aaSAndroid Build Coastguard Worker reporter,
163*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
164*c8dee2aaSAndroid Build Coastguard Worker require_dst_reads,
165*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
166*c8dee2aaSAndroid Build Coastguard Worker auto dContext = ctxInfo.directContext();
167*c8dee2aaSAndroid Build Coastguard Worker auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext,
168*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kRGBA_8888,
169*c8dee2aaSAndroid Build Coastguard Worker nullptr,
170*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kApprox,
171*c8dee2aaSAndroid Build Coastguard Worker {kWidth, kHeight},
172*c8dee2aaSAndroid Build Coastguard Worker kDMSAAProps,
173*c8dee2aaSAndroid Build Coastguard Worker /*label=*/{});
174*c8dee2aaSAndroid Build Coastguard Worker
175*c8dee2aaSAndroid Build Coastguard Worker // Initialize the texture and dmsaa attachment with transparent.
176*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_dmsaa(sdc.get(), SK_PMColor4fTRANSPARENT, SkBlendMode::kSrc);
177*c8dee2aaSAndroid Build Coastguard Worker check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
178*c8dee2aaSAndroid Build Coastguard Worker
179*c8dee2aaSAndroid Build Coastguard Worker sdc->clear(SK_PMColor4fWHITE);
180*c8dee2aaSAndroid Build Coastguard Worker SkPMColor4f dstColor = SK_PMColor4fWHITE;
181*c8dee2aaSAndroid Build Coastguard Worker
182*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_dmsaa(sdc.get(), kTransYellow, SkBlendMode::kDarken);
183*c8dee2aaSAndroid Build Coastguard Worker dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransYellow, dstColor);
184*c8dee2aaSAndroid Build Coastguard Worker
185*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_dmsaa(sdc.get(), kTransCyan, SkBlendMode::kDarken);
186*c8dee2aaSAndroid Build Coastguard Worker dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransCyan, dstColor);
187*c8dee2aaSAndroid Build Coastguard Worker
188*c8dee2aaSAndroid Build Coastguard Worker check_sdc_color(reporter, sdc.get(), dContext, dstColor);
189*c8dee2aaSAndroid Build Coastguard Worker }
190*c8dee2aaSAndroid Build Coastguard Worker
191*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_CONTEXTS(DMSAA_aa_dst_read_after_dmsaa,
192*c8dee2aaSAndroid Build Coastguard Worker &skgpu::IsRenderingContext,
193*c8dee2aaSAndroid Build Coastguard Worker reporter,
194*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
195*c8dee2aaSAndroid Build Coastguard Worker require_dst_reads,
196*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
197*c8dee2aaSAndroid Build Coastguard Worker auto dContext = ctxInfo.directContext();
198*c8dee2aaSAndroid Build Coastguard Worker auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext,
199*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kRGBA_8888,
200*c8dee2aaSAndroid Build Coastguard Worker nullptr,
201*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kApprox,
202*c8dee2aaSAndroid Build Coastguard Worker {kWidth, kHeight},
203*c8dee2aaSAndroid Build Coastguard Worker kDMSAAProps,
204*c8dee2aaSAndroid Build Coastguard Worker /*label=*/{});
205*c8dee2aaSAndroid Build Coastguard Worker
206*c8dee2aaSAndroid Build Coastguard Worker // Initialize the texture and dmsaa attachment with transparent.
207*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_dmsaa(sdc.get(), SK_PMColor4fTRANSPARENT, SkBlendMode::kSrc);
208*c8dee2aaSAndroid Build Coastguard Worker check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
209*c8dee2aaSAndroid Build Coastguard Worker
210*c8dee2aaSAndroid Build Coastguard Worker sdc->clear(SK_PMColor4fWHITE);
211*c8dee2aaSAndroid Build Coastguard Worker SkPMColor4f dstColor = SK_PMColor4fWHITE;
212*c8dee2aaSAndroid Build Coastguard Worker
213*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_dmsaa(sdc.get(), kTransYellow, SkBlendMode::kDarken);
214*c8dee2aaSAndroid Build Coastguard Worker dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransYellow, dstColor);
215*c8dee2aaSAndroid Build Coastguard Worker
216*c8dee2aaSAndroid Build Coastguard Worker // Draw with aa after dmsaa. This should break up the render pass and issue a texture barrier.
217*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_aa(sdc.get(), kTransCyan, SkBlendMode::kDarken);
218*c8dee2aaSAndroid Build Coastguard Worker dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransCyan, dstColor);
219*c8dee2aaSAndroid Build Coastguard Worker
220*c8dee2aaSAndroid Build Coastguard Worker check_sdc_color(reporter, sdc.get(), dContext, dstColor);
221*c8dee2aaSAndroid Build Coastguard Worker }
222*c8dee2aaSAndroid Build Coastguard Worker
223*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_CONTEXTS(DMSAA_dst_read_with_existing_barrier,
224*c8dee2aaSAndroid Build Coastguard Worker &skgpu::IsRenderingContext,
225*c8dee2aaSAndroid Build Coastguard Worker reporter,
226*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
227*c8dee2aaSAndroid Build Coastguard Worker require_dst_reads,
228*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
229*c8dee2aaSAndroid Build Coastguard Worker auto dContext = ctxInfo.directContext();
230*c8dee2aaSAndroid Build Coastguard Worker auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext,
231*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kRGBA_8888,
232*c8dee2aaSAndroid Build Coastguard Worker nullptr,
233*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kApprox,
234*c8dee2aaSAndroid Build Coastguard Worker {kWidth, kHeight},
235*c8dee2aaSAndroid Build Coastguard Worker kDMSAAProps,
236*c8dee2aaSAndroid Build Coastguard Worker /*label=*/{});
237*c8dee2aaSAndroid Build Coastguard Worker
238*c8dee2aaSAndroid Build Coastguard Worker // Initialize the texture and dmsaa attachment with transparent.
239*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_dmsaa(sdc.get(), SK_PMColor4fTRANSPARENT, SkBlendMode::kSrc);
240*c8dee2aaSAndroid Build Coastguard Worker check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
241*c8dee2aaSAndroid Build Coastguard Worker
242*c8dee2aaSAndroid Build Coastguard Worker sdc->clear(SK_PMColor4fWHITE);
243*c8dee2aaSAndroid Build Coastguard Worker SkPMColor4f dstColor = SK_PMColor4fWHITE;
244*c8dee2aaSAndroid Build Coastguard Worker
245*c8dee2aaSAndroid Build Coastguard Worker // Blend to the texture (not the dmsaa attachment) with a dst read. This creates a texture
246*c8dee2aaSAndroid Build Coastguard Worker // barrier.
247*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_aa(sdc.get(), kTransYellow, SkBlendMode::kDarken);
248*c8dee2aaSAndroid Build Coastguard Worker dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransYellow, dstColor);
249*c8dee2aaSAndroid Build Coastguard Worker
250*c8dee2aaSAndroid Build Coastguard Worker // Blend to the msaa attachment _without_ a dst read. This ensures we respect the prior texture
251*c8dee2aaSAndroid Build Coastguard Worker // barrier by splitting the opsTask.
252*c8dee2aaSAndroid Build Coastguard Worker draw_paint_with_dmsaa(sdc.get(), kTransCyan, SkBlendMode::kSrcOver);
253*c8dee2aaSAndroid Build Coastguard Worker dstColor = SkBlendMode_Apply(SkBlendMode::kSrcOver, kTransCyan, dstColor);
254*c8dee2aaSAndroid Build Coastguard Worker
255*c8dee2aaSAndroid Build Coastguard Worker check_sdc_color(reporter, sdc.get(), dContext, dstColor);
256*c8dee2aaSAndroid Build Coastguard Worker }
257*c8dee2aaSAndroid Build Coastguard Worker
258*c8dee2aaSAndroid Build Coastguard Worker // This test is used to test for crbug.com/1241134. The bug appears on Adreno5xx devices with OS
259*c8dee2aaSAndroid Build Coastguard Worker // PQ3A. It does not repro on the earlier PPR1 version since the extend blend func extension was not
260*c8dee2aaSAndroid Build Coastguard Worker // present on the older driver.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DMSAA_dual_source_blend_disable,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)261*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DMSAA_dual_source_blend_disable,
262*c8dee2aaSAndroid Build Coastguard Worker reporter,
263*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
264*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
265*c8dee2aaSAndroid Build Coastguard Worker SkISize surfaceDims = {100, 100};
266*c8dee2aaSAndroid Build Coastguard Worker SkISize texDims = {50, 50};
267*c8dee2aaSAndroid Build Coastguard Worker auto context = ctxInfo.directContext();
268*c8dee2aaSAndroid Build Coastguard Worker
269*c8dee2aaSAndroid Build Coastguard Worker auto sourceTexture = context->createBackendTexture(texDims.width(),
270*c8dee2aaSAndroid Build Coastguard Worker texDims.height(),
271*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
272*c8dee2aaSAndroid Build Coastguard Worker SkColors::kBlue,
273*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped::kNo,
274*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kYes,
275*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo);
276*c8dee2aaSAndroid Build Coastguard Worker
277*c8dee2aaSAndroid Build Coastguard Worker auto sourceImage = SkImages::BorrowTextureFrom(context,
278*c8dee2aaSAndroid Build Coastguard Worker sourceTexture,
279*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
280*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
281*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType,
282*c8dee2aaSAndroid Build Coastguard Worker nullptr);
283*c8dee2aaSAndroid Build Coastguard Worker
284*c8dee2aaSAndroid Build Coastguard Worker auto texture1 = context->createBackendTexture(surfaceDims.width(),
285*c8dee2aaSAndroid Build Coastguard Worker surfaceDims.height(),
286*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
287*c8dee2aaSAndroid Build Coastguard Worker SkColors::kRed,
288*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped::kNo,
289*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kYes,
290*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo);
291*c8dee2aaSAndroid Build Coastguard Worker
292*c8dee2aaSAndroid Build Coastguard Worker auto texture2 = context->createBackendTexture(surfaceDims.width(),
293*c8dee2aaSAndroid Build Coastguard Worker surfaceDims.height(),
294*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
295*c8dee2aaSAndroid Build Coastguard Worker SkColors::kYellow,
296*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped::kNo,
297*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kYes,
298*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo);
299*c8dee2aaSAndroid Build Coastguard Worker
300*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
301*c8dee2aaSAndroid Build Coastguard Worker paint.setBlendMode(SkBlendMode::kSrc);
302*c8dee2aaSAndroid Build Coastguard Worker
303*c8dee2aaSAndroid Build Coastguard Worker SkRect srcRect = SkRect::MakeIWH(texDims.width(), texDims.height());
304*c8dee2aaSAndroid Build Coastguard Worker SkRect dstRect = SkRect::MakeXYWH(texDims.width()/2, texDims.height()/2,
305*c8dee2aaSAndroid Build Coastguard Worker texDims.width(), texDims.height());
306*c8dee2aaSAndroid Build Coastguard Worker
307*c8dee2aaSAndroid Build Coastguard Worker // First we do an image draw to a DMSAA surface with kSrc blend mode. This will trigger us to
308*c8dee2aaSAndroid Build Coastguard Worker // use dual source blending if supported.
309*c8dee2aaSAndroid Build Coastguard Worker // Note: The draw here doesn't actually use the dmsaa multisampled buffer. However, by using
310*c8dee2aaSAndroid Build Coastguard Worker // a dmsaa surface it forces us to use the FillRRectOp instead of the normal FillQuad path. It
311*c8dee2aaSAndroid Build Coastguard Worker // is unclear why, but using the FillRRectOp is required to repro the bug.
312*c8dee2aaSAndroid Build Coastguard Worker {
313*c8dee2aaSAndroid Build Coastguard Worker auto surface = SkSurfaces::WrapBackendTexture(context,
314*c8dee2aaSAndroid Build Coastguard Worker texture1,
315*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
316*c8dee2aaSAndroid Build Coastguard Worker 1,
317*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
318*c8dee2aaSAndroid Build Coastguard Worker nullptr,
319*c8dee2aaSAndroid Build Coastguard Worker &kDMSAAProps);
320*c8dee2aaSAndroid Build Coastguard Worker
321*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->drawImageRect(sourceImage,
322*c8dee2aaSAndroid Build Coastguard Worker srcRect,
323*c8dee2aaSAndroid Build Coastguard Worker dstRect,
324*c8dee2aaSAndroid Build Coastguard Worker SkSamplingOptions(),
325*c8dee2aaSAndroid Build Coastguard Worker &paint,
326*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::kStrict_SrcRectConstraint);
327*c8dee2aaSAndroid Build Coastguard Worker // Make sure there isn't any batching
328*c8dee2aaSAndroid Build Coastguard Worker context->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
329*c8dee2aaSAndroid Build Coastguard Worker }
330*c8dee2aaSAndroid Build Coastguard Worker
331*c8dee2aaSAndroid Build Coastguard Worker // Next we do an image draw to a different surface that doesn't have the dmsaa flag. This will
332*c8dee2aaSAndroid Build Coastguard Worker // trigger use to disable blending. However, when the bug is present the driver still seems to
333*c8dee2aaSAndroid Build Coastguard Worker // try and use a "src2" blend value and ends up just writing the original dst color of yellow.
334*c8dee2aaSAndroid Build Coastguard Worker {
335*c8dee2aaSAndroid Build Coastguard Worker auto surface = SkSurfaces::WrapBackendTexture(context,
336*c8dee2aaSAndroid Build Coastguard Worker texture2,
337*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
338*c8dee2aaSAndroid Build Coastguard Worker 1,
339*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
340*c8dee2aaSAndroid Build Coastguard Worker nullptr,
341*c8dee2aaSAndroid Build Coastguard Worker &kBasicProps);
342*c8dee2aaSAndroid Build Coastguard Worker
343*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->drawImageRect(sourceImage,
344*c8dee2aaSAndroid Build Coastguard Worker srcRect,
345*c8dee2aaSAndroid Build Coastguard Worker dstRect,
346*c8dee2aaSAndroid Build Coastguard Worker SkSamplingOptions(),
347*c8dee2aaSAndroid Build Coastguard Worker &paint,
348*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::kStrict_SrcRectConstraint);
349*c8dee2aaSAndroid Build Coastguard Worker context->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
350*c8dee2aaSAndroid Build Coastguard Worker }
351*c8dee2aaSAndroid Build Coastguard Worker
352*c8dee2aaSAndroid Build Coastguard Worker {
353*c8dee2aaSAndroid Build Coastguard Worker auto readImage = SkImages::BorrowTextureFrom(context,
354*c8dee2aaSAndroid Build Coastguard Worker texture2,
355*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
356*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
357*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType,
358*c8dee2aaSAndroid Build Coastguard Worker nullptr);
359*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo dstIInfo = SkImageInfo::Make(texDims.width(),
360*c8dee2aaSAndroid Build Coastguard Worker texDims.height(),
361*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
362*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType,
363*c8dee2aaSAndroid Build Coastguard Worker nullptr);
364*c8dee2aaSAndroid Build Coastguard Worker
365*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
366*c8dee2aaSAndroid Build Coastguard Worker bitmap.allocPixels(dstIInfo);
367*c8dee2aaSAndroid Build Coastguard Worker
368*c8dee2aaSAndroid Build Coastguard Worker bool success = readImage->readPixels(context, bitmap.pixmap(), dstRect.fLeft, dstRect.fTop);
369*c8dee2aaSAndroid Build Coastguard Worker if (!success) {
370*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to read pixels");
371*c8dee2aaSAndroid Build Coastguard Worker return;
372*c8dee2aaSAndroid Build Coastguard Worker }
373*c8dee2aaSAndroid Build Coastguard Worker auto pix = static_cast<const uint32_t*>(bitmap.getAddr(0, 0));
374*c8dee2aaSAndroid Build Coastguard Worker for (int x = 0; x < 50; ++x) {
375*c8dee2aaSAndroid Build Coastguard Worker for (int y = 0; y < 50; ++y) {
376*c8dee2aaSAndroid Build Coastguard Worker uint32_t pixColor = pix[x + y * 50];
377*c8dee2aaSAndroid Build Coastguard Worker if (pixColor != 0xFFFF0000) {
378*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Didn't get a blue pixel at %d, %d. Got 0x%8X",
379*c8dee2aaSAndroid Build Coastguard Worker x, y, pixColor);
380*c8dee2aaSAndroid Build Coastguard Worker continue;
381*c8dee2aaSAndroid Build Coastguard Worker }
382*c8dee2aaSAndroid Build Coastguard Worker }
383*c8dee2aaSAndroid Build Coastguard Worker }
384*c8dee2aaSAndroid Build Coastguard Worker }
385*c8dee2aaSAndroid Build Coastguard Worker sourceImage.reset();
386*c8dee2aaSAndroid Build Coastguard Worker // Need to make sure the gpu is fully finished before deleting the textures
387*c8dee2aaSAndroid Build Coastguard Worker context->flushAndSubmit(GrSyncCpu::kYes);
388*c8dee2aaSAndroid Build Coastguard Worker context->deleteBackendTexture(sourceTexture);
389*c8dee2aaSAndroid Build Coastguard Worker context->deleteBackendTexture(texture1);
390*c8dee2aaSAndroid Build Coastguard Worker context->deleteBackendTexture(texture2);
391*c8dee2aaSAndroid Build Coastguard Worker }
392