1e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon/*
2e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon * Copyright 2016 Google Inc.
3e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon *
4e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon * Use of this source code is governed by a BSD-style license that can be
5e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon * found in the LICENSE file.
6e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon */
7e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
8e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon#include "Test.h"
9e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
10e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon#if SK_SUPPORT_GPU
11e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon#include "GrContext.h"
121105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman#include "GrRenderTargetContext.h"
13e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
14dbfecd06adeb03e9365f3539e113412c0b18785eRobert Phillips#include "SkCanvas.h"
15dbfecd06adeb03e9365f3539e113412c0b18785eRobert Phillips#include "SkSurface.h"
16dbfecd06adeb03e9365f3539e113412c0b18785eRobert Phillips
171105224f9701e57ec5ce0354d6a380b664f5c638Brian Osmanstatic bool check_rect(GrRenderTargetContext* rtc, const SkIRect& rect, uint32_t expectedValue,
18e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon                       uint32_t* actualValue, int* failX, int* failY) {
19e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    int w = rect.width();
20e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    int h = rect.height();
217ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner    std::unique_ptr<uint32_t[]> pixels(new uint32_t[w * h]);
22e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    memset(pixels.get(), ~expectedValue, sizeof(uint32_t) * w * h);
23301431d7516a18e2b4232ccb70d2a79e8192c748Robert Phillips
24301431d7516a18e2b4232ccb70d2a79e8192c748Robert Phillips    SkImageInfo dstInfo = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
25301431d7516a18e2b4232ccb70d2a79e8192c748Robert Phillips
26301431d7516a18e2b4232ccb70d2a79e8192c748Robert Phillips    if (!rtc->readPixels(dstInfo, pixels.get(), 0, rect.fLeft, rect.fTop)) {
27301431d7516a18e2b4232ccb70d2a79e8192c748Robert Phillips        return false;
28301431d7516a18e2b4232ccb70d2a79e8192c748Robert Phillips    }
29301431d7516a18e2b4232ccb70d2a79e8192c748Robert Phillips
30e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    for (int y = 0; y < h; ++y) {
31e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        for (int x = 0; x < w; ++x) {
32e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon            uint32_t pixel = pixels.get()[y * w + x];
33e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon            if (pixel != expectedValue) {
34e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon                *actualValue = pixel;
35e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon                *failX = x + rect.fLeft;
36e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon                *failY = y + rect.fTop;
37e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon                return false;
38e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon            }
39e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        }
40e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
41e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    return true;
42e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon}
43e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
44e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillipssk_sp<GrRenderTargetContext> newRTC(GrContext* context, int w, int h) {
45e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    return context->makeDeferredRenderTargetContext(SkBackingFit::kExact, w, h,
46dd3b3f41829d32d7eaf3eb4903570d49c2ba9ff8Robert Phillips                                                    kRGBA_8888_GrPixelConfig, nullptr);
47e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon}
48e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
4943f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomonstatic void clear_op_test(skiatest::Reporter* reporter, GrContext* context) {
50e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    static const int kW = 10;
51e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    static const int kH = 10;
52e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
53e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect fullRect = SkIRect::MakeWH(kW, kH);
541105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    sk_sp<GrRenderTargetContext> rtContext;
55e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
56e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // A rectangle that is inset by one on all sides and the 1-pixel wide rectangles that surround
57e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // it.
58e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect mid1Rect = SkIRect::MakeXYWH(1, 1, kW-2, kH-2);
59e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect outerLeftEdge = SkIRect::MakeXYWH(0, 0, 1, kH);
60e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect outerTopEdge = SkIRect::MakeXYWH(0, 0, kW, 1);
61e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect outerRightEdge = SkIRect::MakeXYWH(kW-1, 0, 1, kH);
62e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect outerBottomEdge = SkIRect::MakeXYWH(0, kH-1, kW, 1);
63e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
64e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // A rectangle that is inset by two on all sides and the 1-pixel wide rectangles that surround
65e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // it.
66e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect mid2Rect = SkIRect::MakeXYWH(2, 2, kW-4, kH-4);
67e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect innerLeftEdge = SkIRect::MakeXYWH(1, 1, 1, kH-2);
68e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect innerTopEdge = SkIRect::MakeXYWH(1, 1, kW-2, 1);
69e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect innerRightEdge = SkIRect::MakeXYWH(kW-2, 1, 1, kH-2);
70e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    SkIRect innerBottomEdge = SkIRect::MakeXYWH(1, kH-2, kW-2, 1);
71e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
72e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    uint32_t actualValue;
73e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    int failX, failY;
74e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
75e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    static const GrColor kColor1 = 0xABCDEF01;
76e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    static const GrColor kColor2 = ~kColor1;
77e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
78e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    rtContext = newRTC(context, kW, kH);
79e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    SkASSERT(rtContext);
80e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips
81e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // Check a full clear
82344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
831105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
84e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
85e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
86e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
87e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
88e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    rtContext = newRTC(context, kW, kH);
89e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    SkASSERT(rtContext);
90e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips
91e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // Check two full clears, same color
92344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
93344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
941105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
95e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
96e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
97e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
98e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
99e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    rtContext = newRTC(context, kW, kH);
100e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    SkASSERT(rtContext);
101e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips
102e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // Check two full clears, different colors
103344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
104344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor2, GrRenderTargetContext::CanClearFullscreen::kNo);
1051105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), fullRect, kColor2, &actualValue, &failX, &failY)) {
106e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
107e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
108e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
109e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
110e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    rtContext = newRTC(context, kW, kH);
111e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    SkASSERT(rtContext);
112e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips
113e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // Test a full clear followed by a same color inset clear
114344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
115344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&mid1Rect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
1161105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
117e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
118e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
119e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
120e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
121e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    rtContext = newRTC(context, kW, kH);
122e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    SkASSERT(rtContext);
123e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips
124e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // Test a inset clear followed by same color full clear
125344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&mid1Rect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
126344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
1271105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
128e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
129e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
130e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
131e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
132e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    rtContext = newRTC(context, kW, kH);
133e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    SkASSERT(rtContext);
134e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips
135e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // Test a full clear followed by a different color inset clear
136344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
137344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&mid1Rect, kColor2, GrRenderTargetContext::CanClearFullscreen::kNo);
1381105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), mid1Rect, kColor2, &actualValue, &failX, &failY)) {
139e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
140e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
141e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
1421105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) ||
1431105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) ||
1441105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) ||
1451105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) {
146e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
147e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
148e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
149e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
150e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    rtContext = newRTC(context, kW, kH);
151e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    SkASSERT(rtContext);
152e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips
153e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // Test a inset clear followed by a different full clear
154344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&mid1Rect, kColor2, GrRenderTargetContext::CanClearFullscreen::kNo);
155344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
1561105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
157e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
158e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
159e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
160e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
161e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    rtContext = newRTC(context, kW, kH);
162e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    SkASSERT(rtContext);
163e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips
164e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // Check three nested clears from largest to smallest where outermost and innermost are same
165e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // color.
166344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
167344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&mid1Rect, kColor2, GrRenderTargetContext::CanClearFullscreen::kNo);
168344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&mid2Rect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
1691105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), mid2Rect, kColor1, &actualValue, &failX, &failY)) {
170e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
171e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
172e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
1731105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), innerLeftEdge, kColor2, &actualValue, &failX, &failY) ||
1741105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), innerTopEdge, kColor2, &actualValue, &failX, &failY) ||
1751105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), innerRightEdge, kColor2, &actualValue, &failX, &failY) ||
1761105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), innerBottomEdge, kColor2, &actualValue, &failX, &failY)) {
177e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
178e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
179e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
1801105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) ||
1811105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) ||
1821105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) ||
1831105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) {
184e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
185e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
186e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
187e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon
188e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    rtContext = newRTC(context, kW, kH);
189e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips    SkASSERT(rtContext);
190e4d45bf5ba413e5a26d4f6c24886bbd104b14885Robert Phillips
191e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    // Swap the order of the second two clears in the above test.
192344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
193344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&mid2Rect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
194344e9037e1befdee76691a1239a47829e6af4ea5Chris Dalton    rtContext->clear(&mid1Rect, kColor2, GrRenderTargetContext::CanClearFullscreen::kNo);
1951105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), mid1Rect, kColor2, &actualValue, &failX, &failY)) {
196e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
197e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
198e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
1991105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!check_rect(rtContext.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) ||
2001105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) ||
2011105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) ||
2021105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        !check_rect(rtContext.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) {
203e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
204e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon               failX, failY);
205e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    }
206e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon}
20743f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
20843f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian SalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ClearOp, reporter, ctxInfo) {
20943f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    clear_op_test(reporter, ctxInfo.grContext());
21043f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    if (ctxInfo.backend() == kOpenGL_GrBackend) {
21143f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        GrContextOptions options(ctxInfo.options());
21243f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        options.fUseDrawInsteadOfGLClear = GrContextOptions::Enable::kYes;
21343f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        sk_gpu_test::GrContextFactory workaroundFactory(options);
21443f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        clear_op_test(reporter, workaroundFactory.get(ctxInfo.type()));
21543f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    }
21643f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon}
21743f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
21843f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomonvoid fullscreen_clear_with_layer_test(skiatest::Reporter* reporter, GrContext* context) {
21943f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    const SkImageInfo ii = SkImageInfo::Make(400, 77, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
22043f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
22143f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii);
22243f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    SkCanvas* canvas = surf->getCanvas();
22343f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
22443f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    SkPaint paints[2];
22543f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    paints[0].setColor(SK_ColorGREEN);
22643f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    paints[1].setColor(SK_ColorGRAY);
22743f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
22843f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    static const int kLeftX = 158;
22943f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    static const int kMidX = 258;
23043f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    static const int kRightX = 383;
23143f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    static const int kTopY = 26;
23243f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    static const int kBotY = 51;
23343f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
23443f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    const SkRect rects[2] = {
23543f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        { kLeftX, kTopY, kMidX, kBotY },
23643f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        { kMidX, kTopY, kRightX, kBotY },
23743f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    };
23843f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
23943f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    for (int i = 0; i < 2; ++i) {
24043f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        // the bounds parameter is required to cause a full screen clear
24143f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        canvas->saveLayer(&rects[i], nullptr);
24243f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon            canvas->drawRect(rects[i], paints[i]);
24343f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        canvas->restore();
24443f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    }
24543f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
24643f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    SkBitmap bm;
24743f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    bm.allocPixels(ii, 0);
24843f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
24943f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    SkAssertResult(surf->readPixels(bm, 0, 0));
25043f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
25143f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    bool isCorrect = true;
25243f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    for (int y = kTopY; isCorrect && y < kBotY; ++y) {
25343f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        const uint32_t* sl = bm.getAddr32(0, y);
25443f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
25543f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        for (int x = kLeftX; x < kMidX; ++x) {
25643f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon            if (SK_ColorGREEN != sl[x]) {
25743f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon                isCorrect = false;
25843f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon                break;
25943f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon            }
26043f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        }
26143f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
26243f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        for (int x = kMidX; x < kRightX; ++x) {
26343f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon            if (SK_ColorGRAY != sl[x]) {
26443f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon                isCorrect = false;
26543f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon                break;
26643f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon            }
26743f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        }
26843f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    }
26943f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
27043f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    REPORTER_ASSERT(reporter, isCorrect);
27143f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon}
27243f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon// From crbug.com/768134
27343f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian SalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(FullScreenClearWithLayers, reporter, ctxInfo) {
27443f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    fullscreen_clear_with_layer_test(reporter, ctxInfo.grContext());
27543f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    if (ctxInfo.backend() == kOpenGL_GrBackend) {
27643f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        GrContextOptions options(ctxInfo.options());
27743f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        options.fUseDrawInsteadOfGLClear = GrContextOptions::Enable::kYes;
27843f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        sk_gpu_test::GrContextFactory workaroundFactory(options);
27943f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon        fullscreen_clear_with_layer_test(reporter, workaroundFactory.get(ctxInfo.type()));
28043f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon    }
28143f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon}
28243f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon
28343f8bf0f784f4182ed0fca9053ecf570caf7ad70Brian Salomon#endif
284