Flutter Engine
The Flutter Engine
Typedefs | Functions
ClearTest.cpp File Reference
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurface.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrContextOptions.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/private/SkColorData.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrColor.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/ops/ClearOp.h"
#include "src/gpu/ganesh/ops/GrOp.h"
#include "src/gpu/ganesh/ops/OpsTask.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include <array>
#include <cstdint>
#include <memory>

Go to the source code of this file.

Typedefs

using SurfaceDrawContext = skgpu::ganesh::SurfaceDrawContext
 
using ClearOp = skgpu::ganesh::ClearOp
 

Functions

static bool pixel_matches (const SkPixmap &pm, int x, int y, uint32_t expectedValue, uint32_t *actualValue, int *failX, int *failY)
 
static bool check_rect (GrDirectContext *dContext, SurfaceDrawContext *sdc, const SkIRect &rect, uint32_t expectedValue, uint32_t *actualValue, int *failX, int *failY)
 
static bool check_ring (GrDirectContext *dContext, SurfaceDrawContext *sdc, int inset, uint32_t expectedValue, uint32_t *actualValue, int *failX, int *failY)
 
std::unique_ptr< SurfaceDrawContextnewSDC (GrRecordingContext *rContext, int w, int h)
 
static void clear_op_test (skiatest::Reporter *reporter, GrDirectContext *dContext)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (ClearOp, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
void fullscreen_clear_with_layer_test (skiatest::Reporter *reporter, GrRecordingContext *rContext)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (FullScreenClearWithLayers, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 

Typedef Documentation

◆ ClearOp

Definition at line 47 of file ClearTest.cpp.

◆ SurfaceDrawContext

Definition at line 46 of file ClearTest.cpp.

Function Documentation

◆ check_rect()

static bool check_rect ( GrDirectContext dContext,
SurfaceDrawContext sdc,
const SkIRect rect,
uint32_t  expectedValue,
uint32_t *  actualValue,
int failX,
int failY 
)
static

Definition at line 62 of file ClearTest.cpp.

68 {
69 int w = sdc->width();
70 int h = sdc->height();
71
73
75 readback.alloc(dstInfo);
76
77 readback.erase(~expectedValue);
78 if (!sdc->readPixels(dContext, readback, {0, 0})) {
79 return false;
80 }
81
82 SkASSERT(rect.fTop < rect.fBottom && rect.fLeft < rect.fRight);
83 for (int y = rect.fTop; y < rect.fBottom; ++y) {
84 for (int x = rect.fLeft; x < rect.fRight; ++x) {
85 if (!pixel_matches(readback, x, y, expectedValue, actualValue, failX, failY)) {
86 return false;
87 }
88 }
89 }
90 return true;
91}
static void readback(const SkBitmap &src, int *result, int resultCount)
Definition: BlurTest.cpp:264
static bool pixel_matches(const SkPixmap &pm, int x, int y, uint32_t expectedValue, uint32_t *actualValue, int *failX, int *failY)
Definition: ClearTest.cpp:49
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
bool readPixels(GrDirectContext *dContext, GrPixmap dst, SkIPoint srcPt)
double y
double x
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
SkScalar w
SkScalar h
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)

◆ check_ring()

static bool check_ring ( GrDirectContext dContext,
SurfaceDrawContext sdc,
int  inset,
uint32_t  expectedValue,
uint32_t *  actualValue,
int failX,
int failY 
)
static

Definition at line 94 of file ClearTest.cpp.

100 {
101 int w = sdc->width();
102 int h = sdc->height();
103
105
107 readback.alloc(dstInfo);
108
109 readback.erase(~expectedValue);
110 if (!sdc->readPixels(dContext, readback, {0, 0})) {
111 return false;
112 }
113
114 for (int y = inset; y < h-inset; ++y) {
115 if (!pixel_matches(readback, inset, y, expectedValue, actualValue, failX, failY) ||
116 !pixel_matches(readback, w-1-inset, y, expectedValue, actualValue, failX, failY)) {
117 return false;
118 }
119 }
120 for (int x = inset+1; x < w-inset-1; ++x) {
121 if (!pixel_matches(readback, x, inset, expectedValue, actualValue, failX, failY) ||
122 !pixel_matches(readback, x, h-1-inset, expectedValue, actualValue, failX, failY)) {
123 return false;
124 }
125 }
126
127 return true;
128}
static SkRect inset(const SkRect &r)

◆ clear_op_test()

static void clear_op_test ( skiatest::Reporter reporter,
GrDirectContext dContext 
)
static

Definition at line 136 of file ClearTest.cpp.

136 {
137 static const int kW = 10;
138 static const int kH = 10;
139
140 SkIRect fullRect = SkIRect::MakeWH(kW, kH);
141 std::unique_ptr<SurfaceDrawContext> sdc;
142
143 // A rectangle that is inset by one on all sides and the 1-pixel wide rectangles that surround
144 // it.
145 SkIRect mid1Rect = SkIRect::MakeXYWH(1, 1, kW-2, kH-2);
146
147 // A rectangle that is inset by two on all sides and the 1-pixel wide rectangles that surround
148 // it.
149 SkIRect mid2Rect = SkIRect::MakeXYWH(2, 2, kW-4, kH-4);
150
151 uint32_t actualValue;
152 int failX, failY;
153
154 static const GrColor kColor1 = 0xABCDEF01;
155 static const GrColor kColor2 = ~kColor1;
156 static const SkPMColor4f kColor1f = SkPMColor4f::FromBytes_RGBA(kColor1);
157 static const SkPMColor4f kColor2f = SkPMColor4f::FromBytes_RGBA(kColor2);
158
159 sdc = newSDC(dContext, kW, kH);
160 SkASSERT(sdc);
161
162 // Check a full clear
163 sdc->clear(fullRect, kColor1f);
164 if (!check_rect(dContext, sdc.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
165 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
166 failX, failY);
167 }
168
169 sdc = newSDC(dContext, kW, kH);
170 SkASSERT(sdc);
171
172 // Check two full clears, same color
173 sdc->clear(fullRect, kColor1f);
174 sdc->clear(fullRect, kColor1f);
175 if (!check_rect(dContext, sdc.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
176 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
177 failX, failY);
178 }
179
180 sdc = newSDC(dContext, kW, kH);
181 SkASSERT(sdc);
182
183 // Check two full clears, different colors
184 sdc->clear(fullRect, kColor1f);
185 sdc->clear(fullRect, kColor2f);
186 if (!check_rect(dContext, sdc.get(), fullRect, kColor2, &actualValue, &failX, &failY)) {
187 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
188 failX, failY);
189 }
190
191 sdc = newSDC(dContext, kW, kH);
192 SkASSERT(sdc);
193
194 // Test a full clear followed by a same color inset clear
195 sdc->clear(fullRect, kColor1f);
196 sdc->clear(mid1Rect, kColor1f);
197 if (!check_rect(dContext, sdc.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
198 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
199 failX, failY);
200 }
201
202 sdc = newSDC(dContext, kW, kH);
203 SkASSERT(sdc);
204
205 // Test a inset clear followed by same color full clear
206 sdc->clear(mid1Rect, kColor1f);
207 sdc->clear(fullRect, kColor1f);
208 if (!check_rect(dContext, sdc.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
209 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
210 failX, failY);
211 }
212
213 sdc = newSDC(dContext, kW, kH);
214 SkASSERT(sdc);
215
216 // Test a full clear followed by a different color inset clear
217 sdc->clear(fullRect, kColor1f);
218 sdc->clear(mid1Rect, kColor2f);
219 if (!check_rect(dContext, sdc.get(), mid1Rect, kColor2, &actualValue, &failX, &failY)) {
220 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
221 failX, failY);
222 }
223
224 if (!check_ring(dContext, sdc.get(), /*inset=*/ 0, kColor1, &actualValue, &failX, &failY)) {
225 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
226 failX, failY);
227 }
228
229 sdc = newSDC(dContext, kW, kH);
230 SkASSERT(sdc);
231
232 // Test a inset clear followed by a different full clear
233 sdc->clear(mid1Rect, kColor2f);
234 sdc->clear(fullRect, kColor1f);
235 if (!check_rect(dContext, sdc.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
236 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
237 failX, failY);
238 }
239
240 sdc = newSDC(dContext, kW, kH);
241 SkASSERT(sdc);
242
243 // Check three nested clears from largest to smallest where outermost and innermost are same
244 // color.
245 sdc->clear(fullRect, kColor1f);
246 sdc->clear(mid1Rect, kColor2f);
247 sdc->clear(mid2Rect, kColor1f);
248 if (!check_rect(dContext, sdc.get(), mid2Rect, kColor1, &actualValue, &failX, &failY)) {
249 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
250 failX, failY);
251 }
252
253 if (!check_ring(dContext, sdc.get(), /*inset=*/ 1, kColor2, &actualValue, &failX, &failY)) {
254 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
255 failX, failY);
256 }
257
258 if (!check_ring(dContext, sdc.get(), /*inset=*/ 0, kColor1, &actualValue, &failX, &failY)) {
259 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
260 failX, failY);
261 }
262
263 sdc = newSDC(dContext, kW, kH);
264 SkASSERT(sdc);
265
266 // Swap the order of the second two clears in the above test.
267 sdc->clear(fullRect, kColor1f);
268 sdc->clear(mid2Rect, kColor1f);
269 sdc->clear(mid1Rect, kColor2f);
270 if (!check_rect(dContext, sdc.get(), mid1Rect, kColor2, &actualValue, &failX, &failY)) {
271 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
272 failX, failY);
273 }
274 if (!check_ring(dContext, sdc.get(), /*inset=*/ 0, kColor1, &actualValue, &failX, &failY)) {
275 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
276 failX, failY);
277 }
278
279 // Clear calls need to remain ClearOps for the following combining-tests to work as expected
280 if (!dContext->priv().caps()->performColorClearsAsDraws() &&
281 !dContext->priv().caps()->performStencilClearsAsDraws() &&
282 !dContext->priv().caps()->performPartialClearsAsDraws()) {
283 static constexpr SkIRect kScissorRect = SkIRect::MakeXYWH(1, 1, kW-1, kH-1);
284
285 // Try combining a pure-color clear w/ a combined stencil & color clear
286 // (re skbug.com/10963)
287 {
288 sdc = newSDC(dContext, kW, kH);
289 SkASSERT(sdc);
290
291 sdc->clearStencilClip(kScissorRect, true);
292 // This color clear can combine w/ the preceding stencil clear
293 sdc->clear(kScissorRect, SK_PMColor4fWHITE);
294
295 // This should combine w/ the prior combined clear and overwrite the color
296 sdc->clear(kScissorRect, SK_PMColor4fBLACK);
297
298 auto opsTask = sdc->getOpsTask();
299 REPORTER_ASSERT(reporter, opsTask->numOpChains() == 1);
300
301 const ClearOp& clearOp = opsTask->getChain(0)->cast<ClearOp>();
302
303 constexpr std::array<float, 4> kExpected { 0, 0, 0, 1 };
304 REPORTER_ASSERT(reporter, clearOp.color() == kExpected);
306
307 dContext->flushAndSubmit();
308 }
309
310 // Try combining a pure-stencil clear w/ a combined stencil & color clear
311 // (re skbug.com/10963)
312 {
313 sdc = newSDC(dContext, kW, kH);
314 SkASSERT(sdc);
315
316 sdc->clearStencilClip(kScissorRect, true);
317 // This color clear can combine w/ the preceding stencil clear
318 sdc->clear(kScissorRect, SK_PMColor4fWHITE);
319
320 // This should combine w/ the prior combined clear and overwrite the 'insideStencilMask'
321 // field
322 sdc->clearStencilClip(kScissorRect, false);
323
324 auto opsTask = sdc->getOpsTask();
325 REPORTER_ASSERT(reporter, opsTask->numOpChains() == 1);
326
327 const ClearOp& clearOp = opsTask->getChain(0)->cast<ClearOp>();
328
329 constexpr std::array<float, 4> kExpected { 1, 1, 1, 1 };
330 REPORTER_ASSERT(reporter, clearOp.color() == kExpected);
332
333 dContext->flushAndSubmit();
334 }
335 }
336}
static bool check_ring(GrDirectContext *dContext, SurfaceDrawContext *sdc, int inset, uint32_t expectedValue, uint32_t *actualValue, int *failX, int *failY)
Definition: ClearTest.cpp:94
std::unique_ptr< SurfaceDrawContext > newSDC(GrRecordingContext *rContext, int w, int h)
Definition: ClearTest.cpp:130
static bool check_rect(GrDirectContext *dContext, SurfaceDrawContext *sdc, const SkIRect &rect, uint32_t expectedValue, uint32_t *actualValue, int *failX, int *failY)
Definition: ClearTest.cpp:62
reporter
Definition: FontMgrTest.cpp:39
uint32_t GrColor
Definition: GrColor.h:25
constexpr SkPMColor4f SK_PMColor4fWHITE
Definition: SkColorData.h:380
constexpr SkPMColor4f SK_PMColor4fBLACK
Definition: SkColorData.h:379
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define ERRORF(r,...)
Definition: Test.h:293
constexpr int kH
constexpr int kW
const GrCaps * caps() const
bool performPartialClearsAsDraws() const
Definition: GrCaps.h:426
bool performColorClearsAsDraws() const
Definition: GrCaps.h:431
bool performStencilClearsAsDraws() const
Definition: GrCaps.h:438
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
GrDirectContextPriv priv()
const T & cast() const
Definition: GrOp.h:148
bool stencilInsideMask() const
Definition: ClearOp.h:36
const std::array< float, 4 > & color() const
Definition: ClearOp.h:35
static SkColor kColor1
static SkColor kColor2
Definition: SkRect.h:32
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104
static SkRGBA4f FromBytes_RGBA(uint32_t color)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [1/2]

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

Definition at line 338 of file ClearTest.cpp.

338 {
339 // Regular clear
340 clear_op_test(reporter, ctxInfo.directContext());
341
342 // Force drawing for clears
343 GrContextOptions options(ctxInfo.options());
344 options.fUseDrawInsteadOfClear = GrContextOptions::Enable::kYes;
345 sk_gpu_test::GrContextFactory workaroundFactory(options);
346 clear_op_test(reporter, workaroundFactory.get(ctxInfo.type()));
347}
static void clear_op_test(skiatest::Reporter *reporter, GrDirectContext *dContext)
Definition: ClearTest.cpp:136
const char * options

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [2/2]

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

Definition at line 404 of file ClearTest.cpp.

407 {
408 // Regular clear
409 fullscreen_clear_with_layer_test(reporter, ctxInfo.directContext());
410
411 // Use draws for clears
412 GrContextOptions options(ctxInfo.options());
413 options.fUseDrawInsteadOfClear = GrContextOptions::Enable::kYes;
414 sk_gpu_test::GrContextFactory workaroundFactory(options);
415 fullscreen_clear_with_layer_test(reporter, workaroundFactory.get(ctxInfo.type()));
416}
void fullscreen_clear_with_layer_test(skiatest::Reporter *reporter, GrRecordingContext *rContext)
Definition: ClearTest.cpp:349

◆ fullscreen_clear_with_layer_test()

void fullscreen_clear_with_layer_test ( skiatest::Reporter reporter,
GrRecordingContext rContext 
)

Definition at line 349 of file ClearTest.cpp.

349 {
351
353 SkCanvas* canvas = surf->getCanvas();
354
355 SkPaint paints[2];
356 paints[0].setColor(SK_ColorGREEN);
357 paints[1].setColor(SK_ColorGRAY);
358
359 static const int kLeftX = 158;
360 static const int kMidX = 258;
361 static const int kRightX = 383;
362 static const int kTopY = 26;
363 static const int kBotY = 51;
364
365 const SkRect rects[2] = {
366 { kLeftX, kTopY, kMidX, kBotY },
367 { kMidX, kTopY, kRightX, kBotY },
368 };
369
370 for (int i = 0; i < 2; ++i) {
371 // the bounds parameter is required to cause a full screen clear
372 canvas->saveLayer(&rects[i], nullptr);
373 canvas->drawRect(rects[i], paints[i]);
374 canvas->restore();
375 }
376
377 SkBitmap bm;
378 bm.allocPixels(ii, 0);
379
380 SkAssertResult(surf->readPixels(bm, 0, 0));
381
382 bool isCorrect = true;
383 for (int y = kTopY; isCorrect && y < kBotY; ++y) {
384 const uint32_t* sl = bm.getAddr32(0, y);
385
386 for (int x = kLeftX; x < kMidX; ++x) {
387 if (SK_ColorGREEN != sl[x]) {
388 isCorrect = false;
389 break;
390 }
391 }
392
393 for (int x = kMidX; x < kRightX; ++x) {
394 if (SK_ColorGRAY != sl[x]) {
395 isCorrect = false;
396 break;
397 }
398 }
399 }
400
401 REPORTER_ASSERT(reporter, isCorrect);
402}
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
constexpr SkColor SK_ColorGRAY
Definition: SkColor.h:113
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition: SkBitmap.cpp:258
uint32_t * getAddr32(int x, int y) const
Definition: SkBitmap.h:1260
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition: SkCanvas.cpp:496
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void restore()
Definition: SkCanvas.cpp:461
void setColor(SkColor color)
Definition: SkPaint.cpp:119
SkCanvas * getCanvas()
Definition: SkSurface.cpp:82
bool readPixels(const SkPixmap &dst, int srcX, int srcY)
Definition: SkSurface.cpp:125
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)

◆ newSDC()

std::unique_ptr< SurfaceDrawContext > newSDC ( GrRecordingContext rContext,
int  w,
int  h 
)

Definition at line 130 of file ClearTest.cpp.

130 {
131 return SurfaceDrawContext::Make(rContext, GrColorType::kRGBA_8888, nullptr,
133 /*label=*/{});
134}
static std::unique_ptr< SurfaceDrawContext > Make(GrRecordingContext *, GrColorType, sk_sp< GrSurfaceProxy >, sk_sp< SkColorSpace >, GrSurfaceOrigin, const SkSurfaceProps &)

◆ pixel_matches()

static bool pixel_matches ( const SkPixmap pm,
int  x,
int  y,
uint32_t  expectedValue,
uint32_t *  actualValue,
int failX,
int failY 
)
static

Definition at line 49 of file ClearTest.cpp.

50 {
51 uint32_t pixel = pm.addr32()[y * pm.width() + x];
52 if (pixel != expectedValue) {
53 *actualValue = pixel;
54 *failX = x;
55 *failY = y;
56 return false;
57 }
58
59 return true;
60}
const uint32_t * addr32() const
Definition: SkPixmap.h:352
int width() const
Definition: SkPixmap.h:160