skia2/tests/CopySurfaceTest.cpp
Greg Daniel 7bfc9139c6 Remove GrCaps isConfigTexturable.
This also makes the isTexturable that takes a color explicitly called
isFormatTexturableAndUploadable. A lot of the uses of isConfigTexturable
were changed to the Uploadable version of the check, even though this is
not where we want to land in the long run. In the long run the uploadability
will be checked via calls to supportedWritePixelsColorType and all the
isTexturable calls should purely be about texturing. However, until those
changes land we keep it safe and keep the same functionality that
isConfigTexturable had by checking uploadability as well.

Bug: skia:6718
Change-Id: I3563f33f49811923da80e676fa3036ae46c4da70
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/234323
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
2019-08-14 19:30:45 +00:00

205 lines
10 KiB
C++

/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkImageInfo.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GrContext.h"
#include "include/gpu/GrTypes.h"
#include "include/private/GrTypesPriv.h"
#include "include/private/SkTemplates.h"
#include "src/core/SkUtils.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrSurfaceContext.h"
#include "src/gpu/GrSurfaceProxy.h"
#include "src/gpu/GrTextureProxy.h"
#include "src/gpu/SkGr.h"
#include "tests/Test.h"
#include "tools/gpu/GrContextFactory.h"
#include "tools/gpu/ProxyUtils.h"
#include <initializer_list>
#include <utility>
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
static const int kW = 10;
static const int kH = 10;
static const size_t kRowBytes = sizeof(uint32_t) * kW;
SkAutoTMalloc<uint32_t> srcPixels(kW * kH);
for (int i = 0; i < kW * kH; ++i) {
srcPixels.get()[i] = i;
}
SkAutoTMalloc<uint32_t> dstPixels(kW * kH);
for (int i = 0; i < kW * kH; ++i) {
dstPixels.get()[i] = ~i;
}
static const SkIRect kSrcRects[] {
{ 0, 0, kW , kH },
{-1, -1, kW+1, kH+1},
{ 1, 1, kW-1, kH-1},
{ 5, 5, 6 , 6 },
};
static const SkIPoint kDstPoints[] {
{ 0 , 0 },
{ 1 , 1 },
{ kW/2, kH/4},
{ kW-1, kH-1},
{ kW , kH },
{ kW+1, kH+2},
{-1 , -1 },
};
static const SkImageInfo kImageInfos[] {
SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPremul_SkAlphaType),
SkImageInfo::Make(kW, kH, kBGRA_8888_SkColorType, kPremul_SkAlphaType)
};
SkAutoTMalloc<uint32_t> read(kW * kH);
for (auto sOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
for (auto dOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
for (auto sRenderable : {GrRenderable::kYes, GrRenderable::kNo}) {
for (auto dRenderable : {GrRenderable::kYes, GrRenderable::kNo}) {
for (auto srcRect : kSrcRects) {
for (auto dstPoint : kDstPoints) {
for (auto ii: kImageInfos) {
auto src = sk_gpu_test::MakeTextureProxyFromData(
context, sRenderable, kW, kH, ii.colorType(),
ii.alphaType(), sOrigin, srcPixels.get(), kRowBytes);
auto dst = sk_gpu_test::MakeTextureProxyFromData(
context, dRenderable, kW, kH, ii.colorType(),
ii.alphaType(), dOrigin, dstPixels.get(), kRowBytes);
// Should always work if the color type is RGBA, but may not work
// for BGRA
if (ii.colorType() == kRGBA_8888_SkColorType) {
if (!src || !dst) {
ERRORF(reporter,
"Could not create surfaces for copy surface test.");
continue;
}
} else {
if (!context->defaultBackendFormat(
kBGRA_8888_SkColorType, GrRenderable::kNo).isValid()) {
continue;
}
if (!src || !dst) {
ERRORF(reporter,
"Could not create surfaces for copy surface test.");
continue;
}
}
sk_sp<GrSurfaceContext> dstContext =
context->priv().makeWrappedSurfaceContext(
std::move(dst),
SkColorTypeToGrColorType(ii.colorType()),
ii.alphaType());
bool result = false;
if (sOrigin == dOrigin) {
result = dstContext->testCopy(src.get(), srcRect, dstPoint);
} else if (dRenderable == GrRenderable::kYes) {
SkASSERT(dstContext->asRenderTargetContext());
result = dstContext->asRenderTargetContext()->blitTexture(
src.get(), srcRect, dstPoint);
}
bool expectedResult = true;
SkIPoint dstOffset = { dstPoint.fX - srcRect.fLeft,
dstPoint.fY - srcRect.fTop };
SkIRect copiedDstRect = SkIRect::MakeXYWH(dstPoint.fX,
dstPoint.fY,
srcRect.width(),
srcRect.height());
SkIRect copiedSrcRect;
if (!copiedSrcRect.intersect(srcRect, SkIRect::MakeWH(kW, kH))) {
expectedResult = false;
} else {
// If the src rect was clipped, apply same clipping to each side
// of copied dst rect.
copiedDstRect.fLeft += copiedSrcRect.fLeft - srcRect.fLeft;
copiedDstRect.fTop += copiedSrcRect.fTop - srcRect.fTop;
copiedDstRect.fRight -= copiedSrcRect.fRight - srcRect.fRight;
copiedDstRect.fBottom -= copiedSrcRect.fBottom -
srcRect.fBottom;
}
if (copiedDstRect.isEmpty() ||
!copiedDstRect.intersect(SkIRect::MakeWH(kW, kH))) {
expectedResult = false;
}
if (sOrigin != dOrigin && dRenderable == GrRenderable::kNo) {
expectedResult = false;
}
// To make the copied src rect correct we would apply any dst
// clipping back to the src rect, but we don't use it again so
// don't bother.
if (expectedResult != result) {
ERRORF(reporter, "Expected return value %d from copySurface, "
"got %d.", expectedResult, result);
continue;
}
if (!expectedResult || !result) {
continue;
}
sk_memset32(read.get(), 0, kW * kH);
if (!dstContext->readPixels(ii, read.get(), kRowBytes, {0, 0})) {
ERRORF(reporter, "Error calling readPixels");
continue;
}
bool abort = false;
// Validate that pixels inside copiedDstRect received the correct
// value from src and that those outside were not modified.
for (int y = 0; y < kH && !abort; ++y) {
for (int x = 0; x < kW; ++x) {
uint32_t r = read.get()[y * kW + x];
if (copiedDstRect.contains(x, y)) {
int sx = x - dstOffset.fX;
int sy = y - dstOffset.fY;
uint32_t s = srcPixels.get()[sy * kW + sx];
if (s != r) {
ERRORF(reporter, "Expected dst %d,%d to contain "
"0x%08x copied from src location %d,%d. Got "
"0x%08x", x, y, s, sx, sy, r);
abort = true;
break;
}
} else {
uint32_t d = dstPixels.get()[y * kW + x];
if (d != r) {
ERRORF(reporter, "Expected dst %d,%d to be "
"unmodified (0x%08x). Got 0x%08x",
x, y, d, r);
abort = true;
break;
}
}
}
}
}
}
}
}
}
}
}
}