1/*
2 * Copyright 2015 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// This is a GPU-backend specific test. It relies on static intializers to work
9
10#include "SkTypes.h"
11
12#if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_VULKAN)
13
14#include "GrContextFactory.h"
15#include "GrTest.h"
16#include "Test.h"
17#include "vk/GrVkGpu.h"
18
19using sk_gpu_test::GrContextFactory;
20
21bool does_full_buffer_contain_correct_color(GrColor* buffer,
22                                            GrColor clearColor,
23                                            GrPixelConfig config,
24                                            int width,
25                                            int height) {
26    GrColor matchColor;
27    if (kRGBA_8888_GrPixelConfig == config) {
28        matchColor = clearColor;
29    } else if (kBGRA_8888_GrPixelConfig) {
30        // Hack to flip the R, B componets in the GrColor so that the comparrison will work below
31        matchColor = GrColorPackRGBA(GrColorUnpackB(clearColor),
32                                     GrColorUnpackG(clearColor),
33                                     GrColorUnpackR(clearColor),
34                                     GrColorUnpackA(clearColor));
35    } else {
36        // currently only supporting rgba_8888 and bgra_8888
37        return false;
38    }
39
40    for (int j = 0; j < height; ++j) {
41        for (int i = 0; i < width; ++i) {
42            if (buffer[j * width + i] != matchColor) {
43                return false;
44            }
45        }
46    }
47    return true;
48}
49
50void basic_clear_test(skiatest::Reporter* reporter, GrContext* context, GrPixelConfig config) {
51#if 0
52    GrVkGpu* gpu = static_cast<GrVkGpu*>(context->getGpu());
53    SkAutoTMalloc<GrColor> buffer(25);
54
55    GrSurfaceDesc surfDesc;
56    surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
57    surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
58    surfDesc.fWidth = 5;
59    surfDesc.fHeight = 5;
60    surfDesc.fConfig = config;
61    surfDesc.fSampleCnt = 0;
62    GrTexture* tex = gpu->createTexture(surfDesc, SkBudgeted::kNo);
63    SkASSERT(tex);
64    SkASSERT(tex->asRenderTarget());
65    SkIRect rect = SkIRect::MakeWH(5, 5);
66
67    gpu->clear(rect, GrColor_TRANSPARENT_BLACK, tex->asRenderTarget());
68
69    gpu->readPixels(tex, 0, 0, 5, 5, config, (void*)buffer.get(), 0);
70
71    REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(buffer.get(),
72                                                                     GrColor_TRANSPARENT_BLACK,
73                                                                     config,
74                                                                     5,
75                                                                     5));
76
77    gpu->clear(rect, GrColor_WHITE, tex->asRenderTarget());
78
79    gpu->readPixels(tex, 0, 0, 5, 5, config, (void*)buffer.get(), 0);
80
81    REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(buffer.get(),
82                                                                     GrColor_WHITE,
83                                                                     config,
84                                                                     5,
85                                                                     5));
86
87    GrColor myColor = GrColorPackRGBA(0xFF, 0x7F, 0x40, 0x20);
88
89    gpu->clear(rect, myColor, tex->asRenderTarget());
90
91    gpu->readPixels(tex, 0, 0, 5, 5, config, (void*)buffer.get(), 0);
92
93    REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(buffer.get(),
94                                                                     myColor,
95                                                                     config,
96                                                                     5,
97                                                                     5));
98#endif
99}
100
101void sub_clear_test(skiatest::Reporter* reporter, GrContext* context, GrPixelConfig config) {
102#if 0
103    const int width = 10;
104    const int height = 10;
105    const int subWidth = width/2;
106    const int subHeight = height/2;
107    GrVkGpu* gpu = static_cast<GrVkGpu*>(context->getGpu());
108    SkAutoTMalloc<GrColor> buffer(width * height);
109    SkAutoTMalloc<GrColor> subBuffer(subWidth * subHeight);
110
111    GrSurfaceDesc surfDesc;
112    surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
113    surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
114    surfDesc.fWidth = width;
115    surfDesc.fHeight = height;
116    surfDesc.fConfig = config;
117    surfDesc.fSampleCnt = 0;
118    GrTexture* tex = gpu->createTexture(surfDesc, SkBudgeted::kNo);
119    SkASSERT(tex);
120    SkASSERT(tex->asRenderTarget());
121
122    SkIRect fullRect = SkIRect::MakeWH(10, 10);
123    gpu->clear(fullRect, GrColor_TRANSPARENT_BLACK, tex->asRenderTarget());
124
125    gpu->readPixels(tex, 0, 0, width, height, config, (void*)buffer.get(), 0);
126
127    REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(buffer.get(),
128                                                                     GrColor_TRANSPARENT_BLACK,
129                                                                     config,
130                                                                     width,
131                                                                     height));
132    SkIRect rect;
133    rect = SkIRect::MakeXYWH(0, 0, subWidth, subHeight);
134    gpu->clear(rect, GrColor_WHITE, tex->asRenderTarget());
135    rect = SkIRect::MakeXYWH(subWidth, 0, subWidth, subHeight);
136    gpu->clear(rect, GrColor_WHITE, tex->asRenderTarget());
137    rect = SkIRect::MakeXYWH(0, subHeight, subWidth, subHeight);
138    gpu->clear(rect, GrColor_WHITE, tex->asRenderTarget());
139
140    // Should fail since bottom right sub area has not been cleared to white
141    gpu->readPixels(tex, 0, 0, width, height, config, (void*)buffer.get(), 0);
142    REPORTER_ASSERT(reporter, !does_full_buffer_contain_correct_color(buffer.get(),
143                                                                      GrColor_WHITE,
144                                                                      config,
145                                                                      width,
146                                                                      height));
147
148    rect = SkIRect::MakeXYWH(subWidth, subHeight, subWidth, subHeight);
149    gpu->clear(rect, GrColor_WHITE, tex->asRenderTarget());
150
151    gpu->readPixels(tex, 0, 0, width, height, config, (void*)buffer.get(), 0);
152    REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(buffer.get(),
153                                                                     GrColor_WHITE,
154                                                                     config,
155                                                                     width,
156                                                                     height));
157
158    // Try different colors and that each sub area has correct color
159    GrColor subColor1 = GrColorPackRGBA(0xFF, 0x00, 0x00, 0xFF);
160    GrColor subColor2 = GrColorPackRGBA(0x00, 0xFF, 0x00, 0xFF);
161    GrColor subColor3 = GrColorPackRGBA(0x00, 0x00, 0xFF, 0xFF);
162    GrColor subColor4 = GrColorPackRGBA(0xFF, 0xFF, 0x00, 0xFF);
163
164    rect = SkIRect::MakeXYWH(0, 0, subWidth, subHeight);
165    gpu->clear(rect, subColor1, tex->asRenderTarget());
166    rect = SkIRect::MakeXYWH(subWidth, 0, subWidth, subHeight);
167    gpu->clear(rect, subColor2, tex->asRenderTarget());
168    rect = SkIRect::MakeXYWH(0, subHeight, subWidth, subHeight);
169    gpu->clear(rect, subColor3, tex->asRenderTarget());
170    rect = SkIRect::MakeXYWH(subWidth, subHeight, subWidth, subHeight);
171    gpu->clear(rect, subColor4, tex->asRenderTarget());
172
173    gpu->readPixels(tex, 0, 0, subWidth, subHeight, config, (void*)subBuffer.get(), 0);
174    REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(subBuffer.get(),
175                                                                     subColor1,
176                                                                     config,
177                                                                     subWidth,
178                                                                     subHeight));
179    gpu->readPixels(tex, subWidth, 0, subWidth, subHeight, config, (void*)subBuffer.get(), 0);
180    REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(subBuffer.get(),
181                                                                     subColor2,
182                                                                     config,
183                                                                     subWidth,
184                                                                     subHeight));
185    gpu->readPixels(tex, 0, subHeight, subWidth, subHeight, config, (void*)subBuffer.get(), 0);
186    REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(subBuffer.get(),
187                                                                     subColor3,
188                                                                     config,
189                                                                     subWidth,
190                                                                     subHeight));
191    gpu->readPixels(tex, subWidth, subHeight, subWidth, subHeight,
192                    config, (void*)subBuffer.get(), 0);
193    REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(subBuffer.get(),
194                                                                     subColor4,
195                                                                     config,
196                                                                     subWidth,
197                                                                     subHeight));
198#endif
199}
200
201DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkClearTests, reporter, ctxInfo) {
202    basic_clear_test(reporter, ctxInfo.grContext(), kRGBA_8888_GrPixelConfig);
203    basic_clear_test(reporter, ctxInfo.grContext(), kBGRA_8888_GrPixelConfig);
204    sub_clear_test(reporter, ctxInfo.grContext(), kRGBA_8888_GrPixelConfig);
205    sub_clear_test(reporter, ctxInfo.grContext(), kBGRA_8888_GrPixelConfig);
206}
207
208#endif
209