/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// This is a GPU-backend specific test. It relies on static intializers to work
#include "SkTypes.h"
#if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_VULKAN)
#include "GrContextFactory.h"
#include "GrTest.h"
#include "Test.h"
#include "vk/GrVkGpu.h"
bool does_full_buffer_contain_correct_color(GrColor* buffer,
GrColor clearColor,
GrPixelConfig config,
int width,
int height) {
GrColor matchColor;
if (kRGBA_8888_GrPixelConfig == config) {
matchColor = clearColor;
} else if (kBGRA_8888_GrPixelConfig) {
// Hack to flip the R, B componets in the GrColor so that the comparrison will work below
matchColor = GrColorPackRGBA(GrColorUnpackB(clearColor),
GrColorUnpackG(clearColor),
GrColorUnpackR(clearColor),
GrColorUnpackA(clearColor));
} else {
// currently only supporting rgba_8888 and bgra_8888
return false;
}
for (int j = 0; j < height; ++j) {
for (int i = 0; i < width; ++i) {
if (buffer[j * width + i] != matchColor) {
return false;
}
}
}
return true;
}
void basic_clear_test(skiatest::Reporter* reporter, GrContext* context, GrPixelConfig config) {
GrVkGpu* gpu = static_cast<GrVkGpu*>(context->getGpu());
gpu->discard(NULL);
SkAutoTMalloc<GrColor> buffer(25);
GrSurfaceDesc surfDesc;
surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
surfDesc.fWidth = 5;
surfDesc.fHeight = 5;
surfDesc.fConfig = config;
surfDesc.fSampleCnt = 0;
GrTexture* tex = gpu->createTexture(surfDesc, SkBudgeted::kNo, nullptr, 0);
SkASSERT(tex);
SkASSERT(tex->asRenderTarget());
SkIRect rect = SkIRect::MakeWH(5, 5);
gpu->clear(rect, GrColor_TRANSPARENT_BLACK, tex->asRenderTarget());
gpu->readPixels(tex, 0, 0, 5, 5, config, (void*)buffer.get(), 0);
REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(buffer.get(),
GrColor_TRANSPARENT_BLACK,
config,
5,
5));
gpu->clear(rect, GrColor_WHITE, tex->asRenderTarget());
gpu->readPixels(tex, 0, 0, 5, 5, config, (void*)buffer.get(), 0);
REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(buffer.get(),
GrColor_WHITE,
config,
5,
5));
GrColor myColor = GrColorPackRGBA(0xFF, 0x7F, 0x40, 0x20);
gpu->clear(rect, myColor, tex->asRenderTarget());
gpu->readPixels(tex, 0, 0, 5, 5, config, (void*)buffer.get(), 0);
REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(buffer.get(),
myColor,
config,
5,
5));
}
void sub_clear_test(skiatest::Reporter* reporter, GrContext* context, GrPixelConfig config) {
const int width = 10;
const int height = 10;
const int subWidth = width/2;
const int subHeight = height/2;
GrVkGpu* gpu = static_cast<GrVkGpu*>(context->getGpu());
gpu->discard(NULL);
SkAutoTMalloc<GrColor> buffer(width * height);
SkAutoTMalloc<GrColor> subBuffer(subWidth * subHeight);
GrSurfaceDesc surfDesc;
surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
surfDesc.fWidth = width;
surfDesc.fHeight = height;
surfDesc.fConfig = config;
surfDesc.fSampleCnt = 0;
GrTexture* tex = gpu->createTexture(surfDesc, SkBudgeted::kNo, nullptr, 0);
SkASSERT(tex);
SkASSERT(tex->asRenderTarget());
SkIRect fullRect = SkIRect::MakeWH(10, 10);
gpu->clear(fullRect, GrColor_TRANSPARENT_BLACK, tex->asRenderTarget());
gpu->readPixels(tex, 0, 0, width, height, config, (void*)buffer.get(), 0);
REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(buffer.get(),
GrColor_TRANSPARENT_BLACK,
config,
width,
height));
SkIRect rect;
rect = SkIRect::MakeXYWH(0, 0, subWidth, subHeight);
gpu->clear(rect, GrColor_WHITE, tex->asRenderTarget());
rect = SkIRect::MakeXYWH(subWidth, 0, subWidth, subHeight);
gpu->clear(rect, GrColor_WHITE, tex->asRenderTarget());
rect = SkIRect::MakeXYWH(0, subHeight, subWidth, subHeight);
gpu->clear(rect, GrColor_WHITE, tex->asRenderTarget());
// Should fail since bottom right sub area has not been cleared to white
gpu->readPixels(tex, 0, 0, width, height, config, (void*)buffer.get(), 0);
REPORTER_ASSERT(reporter, !does_full_buffer_contain_correct_color(buffer.get(),
GrColor_WHITE,
config,
width,
height));
rect = SkIRect::MakeXYWH(subWidth, subHeight, subWidth, subHeight);
gpu->clear(rect, GrColor_WHITE, tex->asRenderTarget());
gpu->readPixels(tex, 0, 0, width, height, config, (void*)buffer.get(), 0);
REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(buffer.get(),
GrColor_WHITE,
config,
width,
height));
// Try different colors and that each sub area has correct color
GrColor subColor1 = GrColorPackRGBA(0xFF, 0x00, 0x00, 0xFF);
GrColor subColor2 = GrColorPackRGBA(0x00, 0xFF, 0x00, 0xFF);
GrColor subColor3 = GrColorPackRGBA(0x00, 0x00, 0xFF, 0xFF);
GrColor subColor4 = GrColorPackRGBA(0xFF, 0xFF, 0x00, 0xFF);
rect = SkIRect::MakeXYWH(0, 0, subWidth, subHeight);
gpu->clear(rect, subColor1, tex->asRenderTarget());
rect = SkIRect::MakeXYWH(subWidth, 0, subWidth, subHeight);
gpu->clear(rect, subColor2, tex->asRenderTarget());
rect = SkIRect::MakeXYWH(0, subHeight, subWidth, subHeight);
gpu->clear(rect, subColor3, tex->asRenderTarget());
rect = SkIRect::MakeXYWH(subWidth, subHeight, subWidth, subHeight);
gpu->clear(rect, subColor4, tex->asRenderTarget());
gpu->readPixels(tex, 0, 0, subWidth, subHeight, config, (void*)subBuffer.get(), 0);
REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(subBuffer.get(),
subColor1,
config,
subWidth,
subHeight));
gpu->readPixels(tex, subWidth, 0, subWidth, subHeight, config, (void*)subBuffer.get(), 0);
REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(subBuffer.get(),
subColor2,
config,
subWidth,
subHeight));
gpu->readPixels(tex, 0, subHeight, subWidth, subHeight, config, (void*)subBuffer.get(), 0);
REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(subBuffer.get(),
subColor3,
config,
subWidth,
subHeight));
gpu->readPixels(tex, subWidth, subHeight, subWidth, subHeight,
config, (void*)subBuffer.get(), 0);
REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(subBuffer.get(),
subColor4,
config,
subWidth,
subHeight));
}
DEF_GPUTEST(VkClearTests, reporter, factory) {
GrContextOptions opts;
opts.fSuppressPrints = true;
GrContextFactory debugFactory(opts);
for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
if (static_cast<GrContextFactory::GLContextType>(type) !=
GrContextFactory::kNative_GLContextType) {
continue;
}
GrContext* context = debugFactory.get(static_cast<GrContextFactory::GLContextType>(type));
if (context) {
basic_clear_test(reporter, context, kRGBA_8888_GrPixelConfig);
basic_clear_test(reporter, context, kBGRA_8888_GrPixelConfig);
sub_clear_test(reporter, context, kRGBA_8888_GrPixelConfig);
sub_clear_test(reporter, context, kBGRA_8888_GrPixelConfig);
}
}
}
#endif