1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h" 9cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 10cb93a386Sopenharmony_ci#include "include/core/SkColor.h" 11cb93a386Sopenharmony_ci#include "include/core/SkColorSpace.h" 12cb93a386Sopenharmony_ci#include "include/core/SkImageInfo.h" 13cb93a386Sopenharmony_ci#include "include/core/SkPaint.h" 14cb93a386Sopenharmony_ci#include "include/core/SkRect.h" 15cb93a386Sopenharmony_ci#include "include/core/SkRefCnt.h" 16cb93a386Sopenharmony_ci#include "include/core/SkSurface.h" 17cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 18cb93a386Sopenharmony_ci#include "include/gpu/GrContextOptions.h" 19cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 20cb93a386Sopenharmony_ci#include "include/private/GrTypesPriv.h" 21cb93a386Sopenharmony_ci#include "include/private/SkColorData.h" 22cb93a386Sopenharmony_ci#include "src/core/SkAutoPixmapStorage.h" 23cb93a386Sopenharmony_ci#include "src/gpu/GrColor.h" 24cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 25cb93a386Sopenharmony_ci#include "src/gpu/GrImageInfo.h" 26cb93a386Sopenharmony_ci#include "src/gpu/ops/ClearOp.h" 27cb93a386Sopenharmony_ci#include "src/gpu/v1/SurfaceDrawContext_v1.h" 28cb93a386Sopenharmony_ci#include "tests/Test.h" 29cb93a386Sopenharmony_ci#include "tools/gpu/GrContextFactory.h" 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ci#include <cstdint> 32cb93a386Sopenharmony_ci#include <memory> 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ciusing SurfaceDrawContext = skgpu::v1::SurfaceDrawContext; 35cb93a386Sopenharmony_ciusing ClearOp = skgpu::v1::ClearOp; 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_cistatic bool check_rect(GrDirectContext* dContext, 38cb93a386Sopenharmony_ci SurfaceDrawContext* sdc, 39cb93a386Sopenharmony_ci const SkIRect& rect, 40cb93a386Sopenharmony_ci uint32_t expectedValue, 41cb93a386Sopenharmony_ci uint32_t* actualValue, 42cb93a386Sopenharmony_ci int* failX, 43cb93a386Sopenharmony_ci int* failY) { 44cb93a386Sopenharmony_ci int w = rect.width(); 45cb93a386Sopenharmony_ci int h = rect.height(); 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci SkImageInfo dstInfo = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType); 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci SkAutoPixmapStorage readback; 50cb93a386Sopenharmony_ci readback.alloc(dstInfo); 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci readback.erase(~expectedValue); 53cb93a386Sopenharmony_ci if (!sdc->readPixels(dContext, readback, {rect.fLeft, rect.fTop})) { 54cb93a386Sopenharmony_ci return false; 55cb93a386Sopenharmony_ci } 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci for (int y = 0; y < h; ++y) { 58cb93a386Sopenharmony_ci for (int x = 0; x < w; ++x) { 59cb93a386Sopenharmony_ci uint32_t pixel = readback.addr32()[y * w + x]; 60cb93a386Sopenharmony_ci if (pixel != expectedValue) { 61cb93a386Sopenharmony_ci *actualValue = pixel; 62cb93a386Sopenharmony_ci *failX = x + rect.fLeft; 63cb93a386Sopenharmony_ci *failY = y + rect.fTop; 64cb93a386Sopenharmony_ci return false; 65cb93a386Sopenharmony_ci } 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci return true; 69cb93a386Sopenharmony_ci} 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_cistd::unique_ptr<SurfaceDrawContext> newSDC(GrRecordingContext* rContext, int w, int h) { 72cb93a386Sopenharmony_ci return SurfaceDrawContext::Make(rContext, GrColorType::kRGBA_8888, nullptr, 73cb93a386Sopenharmony_ci SkBackingFit::kExact, {w, h}, SkSurfaceProps()); 74cb93a386Sopenharmony_ci} 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_cistatic void clear_op_test(skiatest::Reporter* reporter, GrDirectContext* dContext) { 77cb93a386Sopenharmony_ci static const int kW = 10; 78cb93a386Sopenharmony_ci static const int kH = 10; 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci SkIRect fullRect = SkIRect::MakeWH(kW, kH); 81cb93a386Sopenharmony_ci std::unique_ptr<SurfaceDrawContext> sdc; 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci // A rectangle that is inset by one on all sides and the 1-pixel wide rectangles that surround 84cb93a386Sopenharmony_ci // it. 85cb93a386Sopenharmony_ci SkIRect mid1Rect = SkIRect::MakeXYWH(1, 1, kW-2, kH-2); 86cb93a386Sopenharmony_ci SkIRect outerLeftEdge = SkIRect::MakeXYWH(0, 0, 1, kH); 87cb93a386Sopenharmony_ci SkIRect outerTopEdge = SkIRect::MakeXYWH(0, 0, kW, 1); 88cb93a386Sopenharmony_ci SkIRect outerRightEdge = SkIRect::MakeXYWH(kW-1, 0, 1, kH); 89cb93a386Sopenharmony_ci SkIRect outerBottomEdge = SkIRect::MakeXYWH(0, kH-1, kW, 1); 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci // A rectangle that is inset by two on all sides and the 1-pixel wide rectangles that surround 92cb93a386Sopenharmony_ci // it. 93cb93a386Sopenharmony_ci SkIRect mid2Rect = SkIRect::MakeXYWH(2, 2, kW-4, kH-4); 94cb93a386Sopenharmony_ci SkIRect innerLeftEdge = SkIRect::MakeXYWH(1, 1, 1, kH-2); 95cb93a386Sopenharmony_ci SkIRect innerTopEdge = SkIRect::MakeXYWH(1, 1, kW-2, 1); 96cb93a386Sopenharmony_ci SkIRect innerRightEdge = SkIRect::MakeXYWH(kW-2, 1, 1, kH-2); 97cb93a386Sopenharmony_ci SkIRect innerBottomEdge = SkIRect::MakeXYWH(1, kH-2, kW-2, 1); 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci uint32_t actualValue; 100cb93a386Sopenharmony_ci int failX, failY; 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_ci static const GrColor kColor1 = 0xABCDEF01; 103cb93a386Sopenharmony_ci static const GrColor kColor2 = ~kColor1; 104cb93a386Sopenharmony_ci static const SkPMColor4f kColor1f = SkPMColor4f::FromBytes_RGBA(kColor1); 105cb93a386Sopenharmony_ci static const SkPMColor4f kColor2f = SkPMColor4f::FromBytes_RGBA(kColor2); 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 108cb93a386Sopenharmony_ci SkASSERT(sdc); 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ci // Check a full clear 111cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor1f); 112cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), fullRect, kColor1, &actualValue, &failX, &failY)) { 113cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue, 114cb93a386Sopenharmony_ci failX, failY); 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 118cb93a386Sopenharmony_ci SkASSERT(sdc); 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci // Check two full clears, same color 121cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor1f); 122cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor1f); 123cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), fullRect, kColor1, &actualValue, &failX, &failY)) { 124cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue, 125cb93a386Sopenharmony_ci failX, failY); 126cb93a386Sopenharmony_ci } 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 129cb93a386Sopenharmony_ci SkASSERT(sdc); 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_ci // Check two full clears, different colors 132cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor1f); 133cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor2f); 134cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), fullRect, kColor2, &actualValue, &failX, &failY)) { 135cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue, 136cb93a386Sopenharmony_ci failX, failY); 137cb93a386Sopenharmony_ci } 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 140cb93a386Sopenharmony_ci SkASSERT(sdc); 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci // Test a full clear followed by a same color inset clear 143cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor1f); 144cb93a386Sopenharmony_ci sdc->clear(mid1Rect, kColor1f); 145cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), fullRect, kColor1, &actualValue, &failX, &failY)) { 146cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue, 147cb93a386Sopenharmony_ci failX, failY); 148cb93a386Sopenharmony_ci } 149cb93a386Sopenharmony_ci 150cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 151cb93a386Sopenharmony_ci SkASSERT(sdc); 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_ci // Test a inset clear followed by same color full clear 154cb93a386Sopenharmony_ci sdc->clear(mid1Rect, kColor1f); 155cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor1f); 156cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), fullRect, kColor1, &actualValue, &failX, &failY)) { 157cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue, 158cb93a386Sopenharmony_ci failX, failY); 159cb93a386Sopenharmony_ci } 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 162cb93a386Sopenharmony_ci SkASSERT(sdc); 163cb93a386Sopenharmony_ci 164cb93a386Sopenharmony_ci // Test a full clear followed by a different color inset clear 165cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor1f); 166cb93a386Sopenharmony_ci sdc->clear(mid1Rect, kColor2f); 167cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), mid1Rect, kColor2, &actualValue, &failX, &failY)) { 168cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue, 169cb93a386Sopenharmony_ci failX, failY); 170cb93a386Sopenharmony_ci } 171cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) || 172cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) || 173cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) || 174cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) { 175cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue, 176cb93a386Sopenharmony_ci failX, failY); 177cb93a386Sopenharmony_ci } 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 180cb93a386Sopenharmony_ci SkASSERT(sdc); 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_ci // Test a inset clear followed by a different full clear 183cb93a386Sopenharmony_ci sdc->clear(mid1Rect, kColor2f); 184cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor1f); 185cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), fullRect, kColor1, &actualValue, &failX, &failY)) { 186cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue, 187cb93a386Sopenharmony_ci failX, failY); 188cb93a386Sopenharmony_ci } 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 191cb93a386Sopenharmony_ci SkASSERT(sdc); 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci // Check three nested clears from largest to smallest where outermost and innermost are same 194cb93a386Sopenharmony_ci // color. 195cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor1f); 196cb93a386Sopenharmony_ci sdc->clear(mid1Rect, kColor2f); 197cb93a386Sopenharmony_ci sdc->clear(mid2Rect, kColor1f); 198cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), mid2Rect, kColor1, &actualValue, &failX, &failY)) { 199cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue, 200cb93a386Sopenharmony_ci failX, failY); 201cb93a386Sopenharmony_ci } 202cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), innerLeftEdge, kColor2, &actualValue, &failX, &failY) || 203cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), innerTopEdge, kColor2, &actualValue, &failX, &failY) || 204cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), innerRightEdge, kColor2, &actualValue, &failX, &failY) || 205cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), innerBottomEdge, kColor2, &actualValue, &failX, &failY)) { 206cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue, 207cb93a386Sopenharmony_ci failX, failY); 208cb93a386Sopenharmony_ci } 209cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) || 210cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) || 211cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) || 212cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) { 213cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue, 214cb93a386Sopenharmony_ci failX, failY); 215cb93a386Sopenharmony_ci } 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 218cb93a386Sopenharmony_ci SkASSERT(sdc); 219cb93a386Sopenharmony_ci 220cb93a386Sopenharmony_ci // Swap the order of the second two clears in the above test. 221cb93a386Sopenharmony_ci sdc->clear(fullRect, kColor1f); 222cb93a386Sopenharmony_ci sdc->clear(mid2Rect, kColor1f); 223cb93a386Sopenharmony_ci sdc->clear(mid1Rect, kColor2f); 224cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), mid1Rect, kColor2, &actualValue, &failX, &failY)) { 225cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue, 226cb93a386Sopenharmony_ci failX, failY); 227cb93a386Sopenharmony_ci } 228cb93a386Sopenharmony_ci if (!check_rect(dContext, sdc.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) || 229cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) || 230cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) || 231cb93a386Sopenharmony_ci !check_rect(dContext, sdc.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) { 232cb93a386Sopenharmony_ci ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue, 233cb93a386Sopenharmony_ci failX, failY); 234cb93a386Sopenharmony_ci } 235cb93a386Sopenharmony_ci 236cb93a386Sopenharmony_ci // Clear calls need to remain ClearOps for the following combining-tests to work as expected 237cb93a386Sopenharmony_ci if (!dContext->priv().caps()->performColorClearsAsDraws() && 238cb93a386Sopenharmony_ci !dContext->priv().caps()->performStencilClearsAsDraws() && 239cb93a386Sopenharmony_ci !dContext->priv().caps()->performPartialClearsAsDraws()) { 240cb93a386Sopenharmony_ci static constexpr SkIRect kScissorRect = SkIRect::MakeXYWH(1, 1, kW-1, kH-1); 241cb93a386Sopenharmony_ci 242cb93a386Sopenharmony_ci // Try combining a pure-color clear w/ a combined stencil & color clear 243cb93a386Sopenharmony_ci // (re skbug.com/10963) 244cb93a386Sopenharmony_ci { 245cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 246cb93a386Sopenharmony_ci SkASSERT(sdc); 247cb93a386Sopenharmony_ci 248cb93a386Sopenharmony_ci sdc->clearStencilClip(kScissorRect, true); 249cb93a386Sopenharmony_ci // This color clear can combine w/ the preceding stencil clear 250cb93a386Sopenharmony_ci sdc->clear(kScissorRect, SK_PMColor4fWHITE); 251cb93a386Sopenharmony_ci 252cb93a386Sopenharmony_ci // This should combine w/ the prior combined clear and overwrite the color 253cb93a386Sopenharmony_ci sdc->clear(kScissorRect, SK_PMColor4fBLACK); 254cb93a386Sopenharmony_ci 255cb93a386Sopenharmony_ci auto opsTask = sdc->getOpsTask(); 256cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, opsTask->numOpChains() == 1); 257cb93a386Sopenharmony_ci 258cb93a386Sopenharmony_ci const ClearOp& clearOp = opsTask->getChain(0)->cast<ClearOp>(); 259cb93a386Sopenharmony_ci 260cb93a386Sopenharmony_ci constexpr std::array<float, 4> kExpected { 0, 0, 0, 1 }; 261cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, clearOp.color() == kExpected); 262cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, clearOp.stencilInsideMask()); 263cb93a386Sopenharmony_ci 264cb93a386Sopenharmony_ci dContext->flushAndSubmit(); 265cb93a386Sopenharmony_ci } 266cb93a386Sopenharmony_ci 267cb93a386Sopenharmony_ci // Try combining a pure-stencil clear w/ a combined stencil & color clear 268cb93a386Sopenharmony_ci // (re skbug.com/10963) 269cb93a386Sopenharmony_ci { 270cb93a386Sopenharmony_ci sdc = newSDC(dContext, kW, kH); 271cb93a386Sopenharmony_ci SkASSERT(sdc); 272cb93a386Sopenharmony_ci 273cb93a386Sopenharmony_ci sdc->clearStencilClip(kScissorRect, true); 274cb93a386Sopenharmony_ci // This color clear can combine w/ the preceding stencil clear 275cb93a386Sopenharmony_ci sdc->clear(kScissorRect, SK_PMColor4fWHITE); 276cb93a386Sopenharmony_ci 277cb93a386Sopenharmony_ci // This should combine w/ the prior combined clear and overwrite the 'insideStencilMask' 278cb93a386Sopenharmony_ci // field 279cb93a386Sopenharmony_ci sdc->clearStencilClip(kScissorRect, false); 280cb93a386Sopenharmony_ci 281cb93a386Sopenharmony_ci auto opsTask = sdc->getOpsTask(); 282cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, opsTask->numOpChains() == 1); 283cb93a386Sopenharmony_ci 284cb93a386Sopenharmony_ci const ClearOp& clearOp = opsTask->getChain(0)->cast<ClearOp>(); 285cb93a386Sopenharmony_ci 286cb93a386Sopenharmony_ci constexpr std::array<float, 4> kExpected { 1, 1, 1, 1 }; 287cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, clearOp.color() == kExpected); 288cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !clearOp.stencilInsideMask()); 289cb93a386Sopenharmony_ci 290cb93a386Sopenharmony_ci dContext->flushAndSubmit(); 291cb93a386Sopenharmony_ci } 292cb93a386Sopenharmony_ci } 293cb93a386Sopenharmony_ci} 294cb93a386Sopenharmony_ci 295cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ClearOp, reporter, ctxInfo) { 296cb93a386Sopenharmony_ci // Regular clear 297cb93a386Sopenharmony_ci clear_op_test(reporter, ctxInfo.directContext()); 298cb93a386Sopenharmony_ci 299cb93a386Sopenharmony_ci // Force drawing for clears 300cb93a386Sopenharmony_ci GrContextOptions options(ctxInfo.options()); 301cb93a386Sopenharmony_ci options.fUseDrawInsteadOfClear = GrContextOptions::Enable::kYes; 302cb93a386Sopenharmony_ci sk_gpu_test::GrContextFactory workaroundFactory(options); 303cb93a386Sopenharmony_ci clear_op_test(reporter, workaroundFactory.get(ctxInfo.type())); 304cb93a386Sopenharmony_ci} 305cb93a386Sopenharmony_ci 306cb93a386Sopenharmony_civoid fullscreen_clear_with_layer_test(skiatest::Reporter* reporter, GrRecordingContext* rContext) { 307cb93a386Sopenharmony_ci const SkImageInfo ii = SkImageInfo::Make(400, 77, kRGBA_8888_SkColorType, kPremul_SkAlphaType); 308cb93a386Sopenharmony_ci 309cb93a386Sopenharmony_ci sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(rContext, SkBudgeted::kYes, ii); 310cb93a386Sopenharmony_ci SkCanvas* canvas = surf->getCanvas(); 311cb93a386Sopenharmony_ci 312cb93a386Sopenharmony_ci SkPaint paints[2]; 313cb93a386Sopenharmony_ci paints[0].setColor(SK_ColorGREEN); 314cb93a386Sopenharmony_ci paints[1].setColor(SK_ColorGRAY); 315cb93a386Sopenharmony_ci 316cb93a386Sopenharmony_ci static const int kLeftX = 158; 317cb93a386Sopenharmony_ci static const int kMidX = 258; 318cb93a386Sopenharmony_ci static const int kRightX = 383; 319cb93a386Sopenharmony_ci static const int kTopY = 26; 320cb93a386Sopenharmony_ci static const int kBotY = 51; 321cb93a386Sopenharmony_ci 322cb93a386Sopenharmony_ci const SkRect rects[2] = { 323cb93a386Sopenharmony_ci { kLeftX, kTopY, kMidX, kBotY }, 324cb93a386Sopenharmony_ci { kMidX, kTopY, kRightX, kBotY }, 325cb93a386Sopenharmony_ci }; 326cb93a386Sopenharmony_ci 327cb93a386Sopenharmony_ci for (int i = 0; i < 2; ++i) { 328cb93a386Sopenharmony_ci // the bounds parameter is required to cause a full screen clear 329cb93a386Sopenharmony_ci canvas->saveLayer(&rects[i], nullptr); 330cb93a386Sopenharmony_ci canvas->drawRect(rects[i], paints[i]); 331cb93a386Sopenharmony_ci canvas->restore(); 332cb93a386Sopenharmony_ci } 333cb93a386Sopenharmony_ci 334cb93a386Sopenharmony_ci SkBitmap bm; 335cb93a386Sopenharmony_ci bm.allocPixels(ii, 0); 336cb93a386Sopenharmony_ci 337cb93a386Sopenharmony_ci SkAssertResult(surf->readPixels(bm, 0, 0)); 338cb93a386Sopenharmony_ci 339cb93a386Sopenharmony_ci bool isCorrect = true; 340cb93a386Sopenharmony_ci for (int y = kTopY; isCorrect && y < kBotY; ++y) { 341cb93a386Sopenharmony_ci const uint32_t* sl = bm.getAddr32(0, y); 342cb93a386Sopenharmony_ci 343cb93a386Sopenharmony_ci for (int x = kLeftX; x < kMidX; ++x) { 344cb93a386Sopenharmony_ci if (SK_ColorGREEN != sl[x]) { 345cb93a386Sopenharmony_ci isCorrect = false; 346cb93a386Sopenharmony_ci break; 347cb93a386Sopenharmony_ci } 348cb93a386Sopenharmony_ci } 349cb93a386Sopenharmony_ci 350cb93a386Sopenharmony_ci for (int x = kMidX; x < kRightX; ++x) { 351cb93a386Sopenharmony_ci if (SK_ColorGRAY != sl[x]) { 352cb93a386Sopenharmony_ci isCorrect = false; 353cb93a386Sopenharmony_ci break; 354cb93a386Sopenharmony_ci } 355cb93a386Sopenharmony_ci } 356cb93a386Sopenharmony_ci } 357cb93a386Sopenharmony_ci 358cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, isCorrect); 359cb93a386Sopenharmony_ci} 360cb93a386Sopenharmony_ci// From crbug.com/768134 361cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(FullScreenClearWithLayers, reporter, ctxInfo) { 362cb93a386Sopenharmony_ci // Regular clear 363cb93a386Sopenharmony_ci fullscreen_clear_with_layer_test(reporter, ctxInfo.directContext()); 364cb93a386Sopenharmony_ci 365cb93a386Sopenharmony_ci // Use draws for clears 366cb93a386Sopenharmony_ci GrContextOptions options(ctxInfo.options()); 367cb93a386Sopenharmony_ci options.fUseDrawInsteadOfClear = GrContextOptions::Enable::kYes; 368cb93a386Sopenharmony_ci sk_gpu_test::GrContextFactory workaroundFactory(options); 369cb93a386Sopenharmony_ci fullscreen_clear_with_layer_test(reporter, workaroundFactory.get(ctxInfo.type())); 370cb93a386Sopenharmony_ci} 371