blob: c1c39dc4eab9c3875fc62c3267a24b7da67eaf90 [file] [log] [blame]
bsalomone63ffef2016-02-05 07:17:34 -08001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Test.h"
9
10#if SK_SUPPORT_GPU
11#include "GrContext.h"
Brian Osman11052242016-10-27 14:47:55 -040012#include "GrRenderTargetContext.h"
bsalomone63ffef2016-02-05 07:17:34 -080013
Brian Osman11052242016-10-27 14:47:55 -040014static bool check_rect(GrRenderTargetContext* rtc, const SkIRect& rect, uint32_t expectedValue,
bsalomone63ffef2016-02-05 07:17:34 -080015 uint32_t* actualValue, int* failX, int* failY) {
bsalomone63ffef2016-02-05 07:17:34 -080016 int w = rect.width();
17 int h = rect.height();
Ben Wagner7ecc5962016-11-02 17:07:33 -040018 std::unique_ptr<uint32_t[]> pixels(new uint32_t[w * h]);
bsalomone63ffef2016-02-05 07:17:34 -080019 memset(pixels.get(), ~expectedValue, sizeof(uint32_t) * w * h);
Robert Phillips301431d2017-03-29 12:08:49 -040020
21 SkImageInfo dstInfo = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
22
23 if (!rtc->readPixels(dstInfo, pixels.get(), 0, rect.fLeft, rect.fTop)) {
24 return false;
25 }
26
bsalomone63ffef2016-02-05 07:17:34 -080027 for (int y = 0; y < h; ++y) {
28 for (int x = 0; x < w; ++x) {
29 uint32_t pixel = pixels.get()[y * w + x];
30 if (pixel != expectedValue) {
31 *actualValue = pixel;
32 *failX = x + rect.fLeft;
33 *failY = y + rect.fTop;
34 return false;
35 }
36 }
37 }
38 return true;
39}
40
Robert Phillipse4d45bf2017-06-02 14:53:40 -040041sk_sp<GrRenderTargetContext> newRTC(GrContext* context, int w, int h) {
42 return context->makeDeferredRenderTargetContext(SkBackingFit::kExact, w, h,
Robert Phillipsdd3b3f42017-04-24 10:57:28 -040043 kRGBA_8888_GrPixelConfig, nullptr);
bsalomone63ffef2016-02-05 07:17:34 -080044}
45
Brian Salomon43f8bf02017-10-18 08:33:29 -040046static void clear_op_test(skiatest::Reporter* reporter, GrContext* context) {
bsalomone63ffef2016-02-05 07:17:34 -080047 static const int kW = 10;
48 static const int kH = 10;
49
50 SkIRect fullRect = SkIRect::MakeWH(kW, kH);
Brian Osman11052242016-10-27 14:47:55 -040051 sk_sp<GrRenderTargetContext> rtContext;
bsalomone63ffef2016-02-05 07:17:34 -080052
53 // A rectangle that is inset by one on all sides and the 1-pixel wide rectangles that surround
54 // it.
55 SkIRect mid1Rect = SkIRect::MakeXYWH(1, 1, kW-2, kH-2);
56 SkIRect outerLeftEdge = SkIRect::MakeXYWH(0, 0, 1, kH);
57 SkIRect outerTopEdge = SkIRect::MakeXYWH(0, 0, kW, 1);
58 SkIRect outerRightEdge = SkIRect::MakeXYWH(kW-1, 0, 1, kH);
59 SkIRect outerBottomEdge = SkIRect::MakeXYWH(0, kH-1, kW, 1);
60
61 // A rectangle that is inset by two on all sides and the 1-pixel wide rectangles that surround
62 // it.
63 SkIRect mid2Rect = SkIRect::MakeXYWH(2, 2, kW-4, kH-4);
64 SkIRect innerLeftEdge = SkIRect::MakeXYWH(1, 1, 1, kH-2);
65 SkIRect innerTopEdge = SkIRect::MakeXYWH(1, 1, kW-2, 1);
66 SkIRect innerRightEdge = SkIRect::MakeXYWH(kW-2, 1, 1, kH-2);
67 SkIRect innerBottomEdge = SkIRect::MakeXYWH(1, kH-2, kW-2, 1);
68
69 uint32_t actualValue;
70 int failX, failY;
71
72 static const GrColor kColor1 = 0xABCDEF01;
73 static const GrColor kColor2 = ~kColor1;
74
Robert Phillipse4d45bf2017-06-02 14:53:40 -040075 rtContext = newRTC(context, kW, kH);
76 SkASSERT(rtContext);
77
bsalomone63ffef2016-02-05 07:17:34 -080078 // Check a full clear
Brian Osman11052242016-10-27 14:47:55 -040079 rtContext->clear(&fullRect, kColor1, false);
80 if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -080081 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
82 failX, failY);
83 }
84
Robert Phillipse4d45bf2017-06-02 14:53:40 -040085 rtContext = newRTC(context, kW, kH);
86 SkASSERT(rtContext);
87
bsalomone63ffef2016-02-05 07:17:34 -080088 // Check two full clears, same color
Brian Osman11052242016-10-27 14:47:55 -040089 rtContext->clear(&fullRect, kColor1, false);
90 rtContext->clear(&fullRect, kColor1, false);
91 if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -080092 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
93 failX, failY);
94 }
95
Robert Phillipse4d45bf2017-06-02 14:53:40 -040096 rtContext = newRTC(context, kW, kH);
97 SkASSERT(rtContext);
98
bsalomone63ffef2016-02-05 07:17:34 -080099 // Check two full clears, different colors
Brian Osman11052242016-10-27 14:47:55 -0400100 rtContext->clear(&fullRect, kColor1, false);
101 rtContext->clear(&fullRect, kColor2, false);
102 if (!check_rect(rtContext.get(), fullRect, kColor2, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800103 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
104 failX, failY);
105 }
106
Robert Phillipse4d45bf2017-06-02 14:53:40 -0400107 rtContext = newRTC(context, kW, kH);
108 SkASSERT(rtContext);
109
bsalomone63ffef2016-02-05 07:17:34 -0800110 // Test a full clear followed by a same color inset clear
Brian Osman11052242016-10-27 14:47:55 -0400111 rtContext->clear(&fullRect, kColor1, false);
112 rtContext->clear(&mid1Rect, kColor1, false);
113 if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800114 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
115 failX, failY);
116 }
117
Robert Phillipse4d45bf2017-06-02 14:53:40 -0400118 rtContext = newRTC(context, kW, kH);
119 SkASSERT(rtContext);
120
bsalomone63ffef2016-02-05 07:17:34 -0800121 // Test a inset clear followed by same color full clear
Brian Osman11052242016-10-27 14:47:55 -0400122 rtContext->clear(&mid1Rect, kColor1, false);
123 rtContext->clear(&fullRect, kColor1, false);
124 if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800125 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
126 failX, failY);
127 }
128
Robert Phillipse4d45bf2017-06-02 14:53:40 -0400129 rtContext = newRTC(context, kW, kH);
130 SkASSERT(rtContext);
131
bsalomone63ffef2016-02-05 07:17:34 -0800132 // Test a full clear followed by a different color inset clear
Brian Osman11052242016-10-27 14:47:55 -0400133 rtContext->clear(&fullRect, kColor1, false);
134 rtContext->clear(&mid1Rect, kColor2, false);
135 if (!check_rect(rtContext.get(), mid1Rect, kColor2, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800136 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
137 failX, failY);
138 }
Brian Osman11052242016-10-27 14:47:55 -0400139 if (!check_rect(rtContext.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) ||
140 !check_rect(rtContext.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) ||
141 !check_rect(rtContext.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) ||
142 !check_rect(rtContext.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800143 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
144 failX, failY);
145 }
146
Robert Phillipse4d45bf2017-06-02 14:53:40 -0400147 rtContext = newRTC(context, kW, kH);
148 SkASSERT(rtContext);
149
bsalomone63ffef2016-02-05 07:17:34 -0800150 // Test a inset clear followed by a different full clear
Brian Osman11052242016-10-27 14:47:55 -0400151 rtContext->clear(&mid1Rect, kColor2, false);
152 rtContext->clear(&fullRect, kColor1, false);
153 if (!check_rect(rtContext.get(), fullRect, kColor1, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800154 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
155 failX, failY);
156 }
157
Robert Phillipse4d45bf2017-06-02 14:53:40 -0400158 rtContext = newRTC(context, kW, kH);
159 SkASSERT(rtContext);
160
bsalomone63ffef2016-02-05 07:17:34 -0800161 // Check three nested clears from largest to smallest where outermost and innermost are same
162 // color.
Brian Osman11052242016-10-27 14:47:55 -0400163 rtContext->clear(&fullRect, kColor1, false);
164 rtContext->clear(&mid1Rect, kColor2, false);
165 rtContext->clear(&mid2Rect, kColor1, false);
166 if (!check_rect(rtContext.get(), mid2Rect, kColor1, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800167 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
168 failX, failY);
169 }
Brian Osman11052242016-10-27 14:47:55 -0400170 if (!check_rect(rtContext.get(), innerLeftEdge, kColor2, &actualValue, &failX, &failY) ||
171 !check_rect(rtContext.get(), innerTopEdge, kColor2, &actualValue, &failX, &failY) ||
172 !check_rect(rtContext.get(), innerRightEdge, kColor2, &actualValue, &failX, &failY) ||
173 !check_rect(rtContext.get(), innerBottomEdge, kColor2, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800174 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
175 failX, failY);
176 }
Brian Osman11052242016-10-27 14:47:55 -0400177 if (!check_rect(rtContext.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) ||
178 !check_rect(rtContext.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) ||
179 !check_rect(rtContext.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) ||
180 !check_rect(rtContext.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800181 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
182 failX, failY);
183 }
184
Robert Phillipse4d45bf2017-06-02 14:53:40 -0400185 rtContext = newRTC(context, kW, kH);
186 SkASSERT(rtContext);
187
bsalomone63ffef2016-02-05 07:17:34 -0800188 // Swap the order of the second two clears in the above test.
Brian Osman11052242016-10-27 14:47:55 -0400189 rtContext->clear(&fullRect, kColor1, false);
190 rtContext->clear(&mid2Rect, kColor1, false);
191 rtContext->clear(&mid1Rect, kColor2, false);
192 if (!check_rect(rtContext.get(), mid1Rect, kColor2, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800193 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor2, actualValue,
194 failX, failY);
195 }
Brian Osman11052242016-10-27 14:47:55 -0400196 if (!check_rect(rtContext.get(), outerLeftEdge, kColor1, &actualValue, &failX, &failY) ||
197 !check_rect(rtContext.get(), outerTopEdge, kColor1, &actualValue, &failX, &failY) ||
198 !check_rect(rtContext.get(), outerRightEdge, kColor1, &actualValue, &failX, &failY) ||
199 !check_rect(rtContext.get(), outerBottomEdge, kColor1, &actualValue, &failX, &failY)) {
bsalomone63ffef2016-02-05 07:17:34 -0800200 ERRORF(reporter, "Expected 0x%08x but got 0x%08x at (%d, %d).", kColor1, actualValue,
201 failX, failY);
202 }
203}
Brian Salomon43f8bf02017-10-18 08:33:29 -0400204
205DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ClearOp, reporter, ctxInfo) {
206 clear_op_test(reporter, ctxInfo.grContext());
207 if (ctxInfo.backend() == kOpenGL_GrBackend) {
208 GrContextOptions options(ctxInfo.options());
209 options.fUseDrawInsteadOfGLClear = GrContextOptions::Enable::kYes;
210 sk_gpu_test::GrContextFactory workaroundFactory(options);
211 clear_op_test(reporter, workaroundFactory.get(ctxInfo.type()));
212 }
213}
214
215#if 0
216
217void fullscreen_clear_with_layer_test(skiatest::Reporter* reporter, GrContext* context) {
218 const SkImageInfo ii = SkImageInfo::Make(400, 77, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
219
220 sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii);
221 SkCanvas* canvas = surf->getCanvas();
222
223 SkPaint paints[2];
224 paints[0].setColor(SK_ColorGREEN);
225 paints[1].setColor(SK_ColorGRAY);
226
227 static const int kLeftX = 158;
228 static const int kMidX = 258;
229 static const int kRightX = 383;
230 static const int kTopY = 26;
231 static const int kBotY = 51;
232
233 const SkRect rects[2] = {
234 { kLeftX, kTopY, kMidX, kBotY },
235 { kMidX, kTopY, kRightX, kBotY },
236 };
237
238 for (int i = 0; i < 2; ++i) {
239 // the bounds parameter is required to cause a full screen clear
240 canvas->saveLayer(&rects[i], nullptr);
241 canvas->drawRect(rects[i], paints[i]);
242 canvas->restore();
243 }
244
245 SkBitmap bm;
246 bm.allocPixels(ii, 0);
247
248 SkAssertResult(surf->readPixels(bm, 0, 0));
249
250 bool isCorrect = true;
251 for (int y = kTopY; isCorrect && y < kBotY; ++y) {
252 const uint32_t* sl = bm.getAddr32(0, y);
253
254 for (int x = kLeftX; x < kMidX; ++x) {
255 if (SK_ColorGREEN != sl[x]) {
256 isCorrect = false;
257 break;
258 }
259 }
260
261 for (int x = kMidX; x < kRightX; ++x) {
262 if (SK_ColorGRAY != sl[x]) {
263 isCorrect = false;
264 break;
265 }
266 }
267 }
268
269 REPORTER_ASSERT(reporter, isCorrect);
270}
271// From crbug.com/768134
272DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FullScreenClearWithLayers, reporter, ctxInfo) {
273 fullscreen_clear_with_layer_test(reporter, ctxInfo.grContext());
274 if (ctxInfo.backend() == kOpenGL_GrBackend) {
275 GrContextOptions options(ctxInfo.options());
276 options.fUseDrawInsteadOfGLClear = GrContextOptions::Enable::kYes;
277 sk_gpu_test::GrContextFactory workaroundFactory(options);
278 fullscreen_clear_with_layer_test(reporter, workaroundFactory.get(ctxInfo.type()));
279 }
280}
281
282#endif
283
bsalomone63ffef2016-02-05 07:17:34 -0800284#endif