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