1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2016 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Test.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContext.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetContext.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool check_rect(GrRenderTargetContext* rtc, const SkIRect& rect, uint32_t expectedValue,
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                       uint32_t* actualValue, int* failX, int* failY) {
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int w = rect.width();
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int h = rect.height();
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    std::unique_ptr<uint32_t[]> pixels(new uint32_t[w * h]);
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    memset(pixels.get(), ~expectedValue, sizeof(uint32_t) * w * h);
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkImageInfo dstInfo = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!rtc->readPixels(dstInfo, pixels.get(), 0, rect.fLeft, rect.fTop)) {
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return false;
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int y = 0; y < h; ++y) {
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int x = 0; x < w; ++x) {
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            uint32_t pixel = pixels.get()[y * w + x];
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (pixel != expectedValue) {
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                *actualValue = pixel;
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                *failX = x + rect.fLeft;
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                *failY = y + rect.fTop;
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return false;
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return true;
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<GrRenderTargetContext> newRTC(GrContext* context, int w, int h) {
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return context->makeDeferredRenderTargetContext(SkBackingFit::kExact, w, h,
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                    kRGBA_8888_GrPixelConfig, nullptr);
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void clear_op_test(skiatest::Reporter* reporter, GrContext* context) {
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kW = 10;
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kH = 10;
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect fullRect = SkIRect::MakeWH(kW, kH);
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrRenderTargetContext> rtContext;
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // A rectangle that is inset by one on all sides and the 1-pixel wide rectangles that surround
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // it.
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect mid1Rect = SkIRect::MakeXYWH(1, 1, kW-2, kH-2);
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect outerLeftEdge = SkIRect::MakeXYWH(0, 0, 1, kH);
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect outerTopEdge = SkIRect::MakeXYWH(0, 0, kW, 1);
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect outerRightEdge = SkIRect::MakeXYWH(kW-1, 0, 1, kH);
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect outerBottomEdge = SkIRect::MakeXYWH(0, kH-1, kW, 1);
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // A rectangle that is inset by two on all sides and the 1-pixel wide rectangles that surround
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // it.
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect mid2Rect = SkIRect::MakeXYWH(2, 2, kW-4, kH-4);
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect innerLeftEdge = SkIRect::MakeXYWH(1, 1, 1, kH-2);
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect innerTopEdge = SkIRect::MakeXYWH(1, 1, kW-2, 1);
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect innerRightEdge = SkIRect::MakeXYWH(kW-2, 1, 1, kH-2);
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect innerBottomEdge = SkIRect::MakeXYWH(1, kH-2, kW-2, 1);
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    uint32_t actualValue;
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int failX, failY;
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const GrColor kColor1 = 0xABCDEF01;
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const GrColor kColor2 = ~kColor1;
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext = newRTC(context, kW, kH);
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(rtContext);
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Check a full clear
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext = newRTC(context, kW, kH);
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(rtContext);
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Check two full clears, same color
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext = newRTC(context, kW, kH);
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(rtContext);
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Check two full clears, different colors
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor2, GrRenderTargetContext::CanClearFullscreen::kNo);
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), fullRect, kColor2, &actualValue, &failX, &failY)) {
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext = newRTC(context, kW, kH);
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(rtContext);
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Test a full clear followed by a same color inset clear
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&mid1Rect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext = newRTC(context, kW, kH);
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(rtContext);
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Test a inset clear followed by same color full clear
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&mid1Rect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext = newRTC(context, kW, kH);
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(rtContext);
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Test a full clear followed by a different color inset clear
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&mid1Rect, kColor2, GrRenderTargetContext::CanClearFullscreen::kNo);
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), mid1Rect, kColor2, &actualValue, &failX, &failY)) {
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) ||
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) ||
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) ||
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) {
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext = newRTC(context, kW, kH);
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(rtContext);
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Test a inset clear followed by a different full clear
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&mid1Rect, kColor2, GrRenderTargetContext::CanClearFullscreen::kNo);
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext = newRTC(context, kW, kH);
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(rtContext);
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Check three nested clears from largest to smallest where outermost and innermost are same
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // color.
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&mid1Rect, kColor2, GrRenderTargetContext::CanClearFullscreen::kNo);
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&mid2Rect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), mid2Rect, kColor1, &actualValue, &failX, &failY)) {
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), innerLeftEdge, kColor2, &actualValue, &failX, &failY) ||
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), innerTopEdge, kColor2, &actualValue, &failX, &failY) ||
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), innerRightEdge, kColor2, &actualValue, &failX, &failY) ||
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), innerBottomEdge, kColor2, &actualValue, &failX, &failY)) {
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) ||
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) ||
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) ||
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) {
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext = newRTC(context, kW, kH);
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(rtContext);
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Swap the order of the second two clears in the above test.
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&fullRect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&mid2Rect, kColor1, GrRenderTargetContext::CanClearFullscreen::kNo);
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rtContext->clear(&mid1Rect, kColor2, GrRenderTargetContext::CanClearFullscreen::kNo);
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), mid1Rect, kColor2, &actualValue, &failX, &failY)) {
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!check_rect(rtContext.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) ||
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) ||
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) ||
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        !check_rect(rtContext.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) {
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               failX, failY);
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ClearOp, reporter, ctxInfo) {
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    clear_op_test(reporter, ctxInfo.grContext());
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (ctxInfo.backend() == kOpenGL_GrBackend) {
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrContextOptions options(ctxInfo.options());
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        options.fUseDrawInsteadOfGLClear = GrContextOptions::Enable::kYes;
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_gpu_test::GrContextFactory workaroundFactory(options);
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        clear_op_test(reporter, workaroundFactory.get(ctxInfo.type()));
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid fullscreen_clear_with_layer_test(skiatest::Reporter* reporter, GrContext* context) {
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkImageInfo ii = SkImageInfo::Make(400, 77, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii);
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkCanvas* canvas = surf->getCanvas();
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paints[2];
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paints[0].setColor(SK_ColorGREEN);
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paints[1].setColor(SK_ColorGRAY);
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kLeftX = 158;
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kMidX = 258;
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kRightX = 383;
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kTopY = 26;
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kBotY = 51;
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkRect rects[2] = {
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        { kLeftX, kTopY, kMidX, kBotY },
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        { kMidX, kTopY, kRightX, kBotY },
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 2; ++i) {
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // the bounds parameter is required to cause a full screen clear
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->saveLayer(&rects[i], nullptr);
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->drawRect(rects[i], paints[i]);
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->restore();
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkBitmap bm;
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bm.allocPixels(ii, 0);
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkAssertResult(surf->readPixels(bm, 0, 0));
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool isCorrect = true;
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int y = kTopY; isCorrect && y < kBotY; ++y) {
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const uint32_t* sl = bm.getAddr32(0, y);
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int x = kLeftX; x < kMidX; ++x) {
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (SK_ColorGREEN != sl[x]) {
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                isCorrect = false;
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int x = kMidX; x < kRightX; ++x) {
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (SK_ColorGRAY != sl[x]) {
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                isCorrect = false;
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, isCorrect);
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// From crbug.com/768134
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST_FOR_RENDERING_CONTEXTS(FullScreenClearWithLayers, reporter, ctxInfo) {
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fullscreen_clear_with_layer_test(reporter, ctxInfo.grContext());
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (ctxInfo.backend() == kOpenGL_GrBackend) {
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrContextOptions options(ctxInfo.options());
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        options.fUseDrawInsteadOfGLClear = GrContextOptions::Enable::kYes;
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_gpu_test::GrContextFactory workaroundFactory(options);
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fullscreen_clear_with_layer_test(reporter, workaroundFactory.get(ctxInfo.type()));
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
284