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 
does_full_buffer_contain_correct_color(GrColor * buffer,GrColor clearColor,GrPixelConfig config,int width,int height)20 bool 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 
basic_clear_test(skiatest::Reporter * reporter,GrContext * context,GrPixelConfig config)49 void 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 
sub_clear_test(skiatest::Reporter * reporter,GrContext * context,GrPixelConfig config)99 void 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 
DEF_GPUTEST(VkClearTests,reporter,factory)198 DEF_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