Flutter Engine
The Flutter Engine
Functions
DMSAATest.cpp File Reference
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkSurface.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypes.h"
#include "include/core/SkVertices.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrContextOptions.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrTypes.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/private/SkColorData.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkBlendModePriv.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/GrPixmap.h"
#include "src/gpu/ganesh/GrXferProcessor.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/gpu/ContextType.h"
#include <cstdint>
#include <cstring>
#include <memory>
#include <utility>

Go to the source code of this file.

Functions

static void draw_paint_with_aa (skgpu::ganesh::SurfaceDrawContext *sdc, const SkPMColor4f &color, SkBlendMode blendMode)
 
static void draw_paint_with_dmsaa (skgpu::ganesh::SurfaceDrawContext *sdc, const SkPMColor4f &color, SkBlendMode blendMode)
 
static bool fuzzy_equals (const float a[4], const SkPMColor4f &b)
 
static void check_sdc_color (skiatest::Reporter *reporter, skgpu::ganesh::SurfaceDrawContext *sdc, GrDirectContext *ctx, const SkPMColor4f &color)
 
 DEF_GANESH_TEST_FOR_CONTEXTS (DMSAA_preserve_contents, &skgpu::IsRenderingContext, reporter, ctxInfo, nullptr, CtsEnforcement::kApiLevel_T)
 
static void require_dst_reads (GrContextOptions *options)
 
 DEF_GANESH_TEST_FOR_CONTEXTS (DMSAA_dst_read, &skgpu::IsRenderingContext, reporter, ctxInfo, require_dst_reads, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_CONTEXTS (DMSAA_aa_dst_read_after_dmsaa, &skgpu::IsRenderingContext, reporter, ctxInfo, require_dst_reads, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_CONTEXTS (DMSAA_dst_read_with_existing_barrier, &skgpu::IsRenderingContext, reporter, ctxInfo, require_dst_reads, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (DMSAA_dual_source_blend_disable, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 

Function Documentation

◆ check_sdc_color()

static void check_sdc_color ( skiatest::Reporter reporter,
skgpu::ganesh::SurfaceDrawContext sdc,
GrDirectContext ctx,
const SkPMColor4f color 
)
static

Definition at line 99 of file DMSAATest.cpp.

102 {
105 sdc->readPixels(ctx, pixmap, {0, 0});
106 auto pix = static_cast<const float*>(pixmap.addr());
107 for (int y = 0; y < kHeight; ++y) {
108 for (int x = 0; x < kWidth; ++x) {
109 if (!fuzzy_equals(pix, color)) {
110 ERRORF(reporter, "SDC color mismatch.\n"
111 "Got [%0.3f, %0.3f, %0.3f, %0.3f]\n"
112 "Expected [%0.3f, %0.3f, %0.3f, %0.3f]",
113 pix[0], pix[1], pix[2], pix[3], color.fR, color.fG, color.fB, color.fA);
114 return;
115 }
116 pix += 4;
117 }
118 }
119}
static bool fuzzy_equals(const float a[4], const SkPMColor4f &b)
Definition: DMSAATest.cpp:89
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
reporter
Definition: FontMgrTest.cpp:39
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
Definition: SkColorType.h:40
#define ERRORF(r,...)
Definition: Test.h:293
T * addr() const
Definition: GrPixmap.h:20
static GrPixmap Allocate(const GrImageInfo &info)
Definition: GrPixmap.h:101
bool readPixels(GrDirectContext *dContext, GrPixmap dst, SkIPoint srcPt)
DlColor color
double y
double x
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
constexpr size_t kHeight
constexpr size_t kWidth

◆ DEF_GANESH_TEST_FOR_CONTEXTS() [1/4]

DEF_GANESH_TEST_FOR_CONTEXTS ( DMSAA_aa_dst_read_after_dmsaa  ,
&skgpu::IsRenderingContext  ,
reporter  ,
ctxInfo  ,
require_dst_reads  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 191 of file DMSAATest.cpp.

196 {
197 auto dContext = ctxInfo.directContext();
198 auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext,
200 nullptr,
202 {kWidth, kHeight},
203 kDMSAAProps,
204 /*label=*/{});
205
206 // Initialize the texture and dmsaa attachment with transparent.
208 check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
209
210 sdc->clear(SK_PMColor4fWHITE);
212
213 draw_paint_with_dmsaa(sdc.get(), kTransYellow, SkBlendMode::kDarken);
214 dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransYellow, dstColor);
215
216 // Draw with aa after dmsaa. This should break up the render pass and issue a texture barrier.
217 draw_paint_with_aa(sdc.get(), kTransCyan, SkBlendMode::kDarken);
218 dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransCyan, dstColor);
219
220 check_sdc_color(reporter, sdc.get(), dContext, dstColor);
221}
static void draw_paint_with_aa(skgpu::ganesh::SurfaceDrawContext *sdc, const SkPMColor4f &color, SkBlendMode blendMode)
Definition: DMSAATest.cpp:63
static void check_sdc_color(skiatest::Reporter *reporter, skgpu::ganesh::SurfaceDrawContext *sdc, GrDirectContext *ctx, const SkPMColor4f &color)
Definition: DMSAATest.cpp:99
static void draw_paint_with_dmsaa(skgpu::ganesh::SurfaceDrawContext *sdc, const SkPMColor4f &color, SkBlendMode blendMode)
Definition: DMSAATest.cpp:73
SkPMColor4f SkBlendMode_Apply(SkBlendMode mode, const SkPMColor4f &src, const SkPMColor4f &dst)
@ kDarken
rc = s + d - max(s*da, d*sa), ra = kSrcOver
constexpr SkPMColor4f SK_PMColor4fWHITE
Definition: SkColorData.h:380
constexpr SkPMColor4f SK_PMColor4fTRANSPARENT
Definition: SkColorData.h:378
static std::unique_ptr< SurfaceDrawContext > Make(GrRecordingContext *, GrColorType, sk_sp< GrSurfaceProxy >, sk_sp< SkColorSpace >, GrSurfaceOrigin, const SkSurfaceProps &)

◆ DEF_GANESH_TEST_FOR_CONTEXTS() [2/4]

DEF_GANESH_TEST_FOR_CONTEXTS ( DMSAA_dst_read  ,
&skgpu::IsRenderingContext  ,
reporter  ,
ctxInfo  ,
require_dst_reads  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 160 of file DMSAATest.cpp.

165 {
166 auto dContext = ctxInfo.directContext();
167 auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext,
169 nullptr,
171 {kWidth, kHeight},
172 kDMSAAProps,
173 /*label=*/{});
174
175 // Initialize the texture and dmsaa attachment with transparent.
177 check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
178
179 sdc->clear(SK_PMColor4fWHITE);
181
182 draw_paint_with_dmsaa(sdc.get(), kTransYellow, SkBlendMode::kDarken);
183 dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransYellow, dstColor);
184
185 draw_paint_with_dmsaa(sdc.get(), kTransCyan, SkBlendMode::kDarken);
186 dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransCyan, dstColor);
187
188 check_sdc_color(reporter, sdc.get(), dContext, dstColor);
189}

◆ DEF_GANESH_TEST_FOR_CONTEXTS() [3/4]

DEF_GANESH_TEST_FOR_CONTEXTS ( DMSAA_dst_read_with_existing_barrier  ,
&skgpu::IsRenderingContext  ,
reporter  ,
ctxInfo  ,
require_dst_reads  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 223 of file DMSAATest.cpp.

228 {
229 auto dContext = ctxInfo.directContext();
230 auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext,
232 nullptr,
234 {kWidth, kHeight},
235 kDMSAAProps,
236 /*label=*/{});
237
238 // Initialize the texture and dmsaa attachment with transparent.
240 check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
241
242 sdc->clear(SK_PMColor4fWHITE);
244
245 // Blend to the texture (not the dmsaa attachment) with a dst read. This creates a texture
246 // barrier.
247 draw_paint_with_aa(sdc.get(), kTransYellow, SkBlendMode::kDarken);
248 dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransYellow, dstColor);
249
250 // Blend to the msaa attachment _without_ a dst read. This ensures we respect the prior texture
251 // barrier by splitting the opsTask.
252 draw_paint_with_dmsaa(sdc.get(), kTransCyan, SkBlendMode::kSrcOver);
253 dstColor = SkBlendMode_Apply(SkBlendMode::kSrcOver, kTransCyan, dstColor);
254
255 check_sdc_color(reporter, sdc.get(), dContext, dstColor);
256}
@ kSrcOver
r = s + (1-sa)*d

◆ DEF_GANESH_TEST_FOR_CONTEXTS() [4/4]

DEF_GANESH_TEST_FOR_CONTEXTS ( DMSAA_preserve_contents  ,
&skgpu::IsRenderingContext  ,
reporter  ,
ctxInfo  ,
nullptr  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 121 of file DMSAATest.cpp.

126 {
127 auto dContext = ctxInfo.directContext();
128 auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext,
130 nullptr,
132 {kWidth, kHeight},
133 kDMSAAProps,
134 /*label=*/{});
135
136 // Initialize the texture and dmsaa attachment with transparent.
138 check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
139
140 // Clear the main texture to yellow.
141 sdc->clear(kTransYellow);
142
143 // Close the opsTask by doing a readback.
144 check_sdc_color(reporter, sdc.get(), dContext, kTransYellow);
145
146 // Now the DMSAA attachment is clear and the texture is yellow. Blend cyan into the DMSAA
147 // attachment. This will fail if the yellow from the main texture doesn't get copied into the
148 // DMSAA attachment before the renderPass.
149 draw_paint_with_dmsaa(sdc.get(), kTransCyan, SkBlendMode::kSrcOver);
150 SkPMColor4f dstColor = SkBlendMode_Apply(SkBlendMode::kSrcOver, kTransCyan, kTransYellow);
151
152 check_sdc_color(reporter, sdc.get(), dContext, dstColor);
153}

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS()

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( DMSAA_dual_source_blend_disable  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 261 of file DMSAATest.cpp.

264 {
265 SkISize surfaceDims = {100, 100};
266 SkISize texDims = {50, 50};
267 auto context = ctxInfo.directContext();
268
269 auto sourceTexture = context->createBackendTexture(texDims.width(),
270 texDims.height(),
276
277 auto sourceImage = SkImages::BorrowTextureFrom(context,
278 sourceTexture,
282 nullptr);
283
284 auto texture1 = context->createBackendTexture(surfaceDims.width(),
285 surfaceDims.height(),
291
292 auto texture2 = context->createBackendTexture(surfaceDims.width(),
293 surfaceDims.height(),
299
301 paint.setBlendMode(SkBlendMode::kSrc);
302
303 SkRect srcRect = SkRect::MakeIWH(texDims.width(), texDims.height());
304 SkRect dstRect = SkRect::MakeXYWH(texDims.width()/2, texDims.height()/2,
305 texDims.width(), texDims.height());
306
307 // First we do an image draw to a DMSAA surface with kSrc blend mode. This will trigger us to
308 // use dual source blending if supported.
309 // Note: The draw here doesn't actually use the dmsaa multisampled buffer. However, by using
310 // a dmsaa surface it forces us to use the FillRRectOp instead of the normal FillQuad path. It
311 // is unclear why, but using the FillRRectOp is required to repro the bug.
312 {
314 texture1,
316 1,
318 nullptr,
319 &kDMSAAProps);
320
321 surface->getCanvas()->drawImageRect(sourceImage,
322 srcRect,
323 dstRect,
325 &paint,
327 // Make sure there isn't any batching
328 context->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
329 }
330
331 // Next we do an image draw to a different surface that doesn't have the dmsaa flag. This will
332 // trigger use to disable blending. However, when the bug is present the driver still seems to
333 // try and use a "src2" blend value and ends up just writing the original dst color of yellow.
334 {
336 texture2,
338 1,
340 nullptr,
341 &kBasicProps);
342
343 surface->getCanvas()->drawImageRect(sourceImage,
344 srcRect,
345 dstRect,
347 &paint,
349 context->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
350 }
351
352 {
353 auto readImage = SkImages::BorrowTextureFrom(context,
354 texture2,
358 nullptr);
359 SkImageInfo dstIInfo = SkImageInfo::Make(texDims.width(),
360 texDims.height(),
363 nullptr);
364
366 bitmap.allocPixels(dstIInfo);
367
368 bool success = readImage->readPixels(context, bitmap.pixmap(), dstRect.fLeft, dstRect.fTop);
369 if (!success) {
370 ERRORF(reporter, "Failed to read pixels");
371 return;
372 }
373 auto pix = static_cast<const uint32_t*>(bitmap.getAddr(0, 0));
374 for (int x = 0; x < 50; ++x) {
375 for (int y = 0; y < 50; ++y) {
376 uint32_t pixColor = pix[x + y * 50];
377 if (pixColor != 0xFFFF0000) {
378 ERRORF(reporter, "Didn't get a blue pixel at %d, %d. Got 0x%8X",
379 x, y, pixColor);
380 continue;
381 }
382 }
383 }
384 }
385 sourceImage.reset();
386 // Need to make sure the gpu is fully finished before deleting the textures
387 context->flushAndSubmit(GrSyncCpu::kYes);
388 context->deleteBackendTexture(sourceTexture);
389 context->deleteBackendTexture(texture1);
390 context->deleteBackendTexture(texture2);
391}
@ kTopLeft_GrSurfaceOrigin
Definition: GrTypes.h:148
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition: SkCanvas.h:1542
const Paint & paint
Definition: color_source.cc:38
VkSurfaceKHR surface
Definition: main.cc:49
constexpr SkColor4f kRed
Definition: SkColor.h:440
constexpr SkColor4f kBlue
Definition: SkColor.h:442
constexpr SkColor4f kYellow
Definition: SkColor.h:443
SK_API sk_sp< SkImage > BorrowTextureFrom(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
SK_API sk_sp< SkSurface > WrapBackendTexture(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, int sampleCnt, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
Definition: bitmap.py:1
SkSamplingOptions(SkFilterMode::kLinear))
Definition: SkSize.h:16
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
static SkRect MakeIWH(int w, int h)
Definition: SkRect.h:623
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15

◆ draw_paint_with_aa()

static void draw_paint_with_aa ( skgpu::ganesh::SurfaceDrawContext sdc,
const SkPMColor4f color,
SkBlendMode  blendMode 
)
static

Definition at line 63 of file DMSAATest.cpp.

65 {
67 paint.setColor4f(color);
68 paint.setXPFactory(GrXPFactory::FromBlendMode(blendMode));
69 sdc->drawRect(nullptr, std::move(paint), GrAA::kYes, SkMatrix::I(),
70 SkRect::MakeIWH(kWidth, kHeight), nullptr);
71}
static const GrXPFactory * FromBlendMode(SkBlendMode)
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
void drawRect(const GrClip *, GrPaint &&paint, GrAA, const SkMatrix &viewMatrix, const SkRect &, const GrStyle *style=nullptr)

◆ draw_paint_with_dmsaa()

static void draw_paint_with_dmsaa ( skgpu::ganesh::SurfaceDrawContext sdc,
const SkPMColor4f color,
SkBlendMode  blendMode 
)
static

Definition at line 73 of file DMSAATest.cpp.

75 {
76 // drawVertices should always trigger dmsaa, but draw something non-rectangular just to be 100%
77 // certain.
78 static const SkPoint kVertices[3] = {{-.5f,-.5f}, {kWidth * 2.1f, 0}, {0, kHeight * 2.1f}};
80 memcpy(builder.positions(), kVertices, sizeof(kVertices));
81 auto vertices = builder.detach();
82
84 paint.setColor4f(color);
85 paint.setXPFactory(GrXPFactory::FromBlendMode(blendMode));
86 sdc->drawVertices(nullptr, std::move(paint), SkMatrix::I(), vertices);
87}
@ kTriangles_VertexMode
Definition: SkVertices.h:31
void drawVertices(const GrClip *, GrPaint &&paint, const SkMatrix &viewMatrix, sk_sp< SkVertices > vertices, GrPrimitiveType *overridePrimType=nullptr, bool skipColorXform=false)

◆ fuzzy_equals()

static bool fuzzy_equals ( const float  a[4],
const SkPMColor4f b 
)
static

Definition at line 89 of file DMSAATest.cpp.

89 {
90 constexpr static float kTolerance = 2.5f / 256;
91 for (int i = 0; i < 4; ++i) {
92 if (!SkScalarNearlyEqual(a[i], b.vec()[i], kTolerance)) {
93 return false;
94 }
95 }
96 return true;
97}
static constexpr float kTolerance
Definition: GrQuadUtils.cpp:29
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
static bool b
struct MyStruct a[10]

◆ require_dst_reads()

static void require_dst_reads ( GrContextOptions options)
static

Definition at line 155 of file DMSAATest.cpp.

155 {
156 options->fSuppressAdvancedBlendEquations = true;
157 options->fSuppressFramebufferFetch = true;
158}
const char * options