skia2/tests/CompressedBackendAllocationTest.cpp

336 lines
14 KiB
C++
Raw Normal View History

/*
* Copyright 2019 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/SkCanvas.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrRecordingContext.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkCompressedDataUtils.h"
#include "src/core/SkMipmap.h"
#include "src/core/SkPaintPriv.h"
#include "src/gpu/GrBackendUtils.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/image/SkImage_Base.h"
#include "tests/Test.h"
#include "tests/TestUtils.h"
#include "tools/ToolUtils.h"
// Just verify that 'actual' is entirely 'expected'
static void check_solid_pixmap(skiatest::Reporter* reporter,
const SkColor4f& expected, const SkPixmap& actual,
const char* label0, const char* label1, const char* label2) {
const float tols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
auto error = std::function<ComparePixmapsErrorReporter>(
[reporter, label0, label1, label2](int x, int y, const float diffs[4]) {
SkASSERT(x >= 0 && y >= 0);
ERRORF(reporter, "%s %s %s - mismatch at %d, %d (%f, %f, %f %f)",
label0, label1, label2, x, y,
diffs[0], diffs[1], diffs[2], diffs[3]);
});
CheckSolidPixels(expected, actual, tols, error);
}
// Create an SkImage to wrap 'backendTex'
Reland "Migrate SkImage::MakeFromTexture to GrRecordingContext" This reverts commit 74b83a4ea9e31dbdc1996a1ed2d1844d5cdbe9b7. Reason for revert: Flutter is updated Original change's description: > Revert "Migrate SkImage::MakeFromTexture to GrRecordingContext" > > This reverts commit daa9e7455d4f0f54dc07f405becba5d0c5964847. > > Reason for revert: Broke Build-Debian9-Clang-arm-Release-Flutter_Android_Docker > > Original change's description: > > Migrate SkImage::MakeFromTexture to GrRecordingContext > > > > Android migration landed in Android CL 12234077 > > Chrome migration is landing in Chrome CL 2335812 > > > > Note: makeFromCompressedTexture is not used by Chrome. > > > > Bug: skia:104662 > > Change-Id: Ibbe6d412cf22e87188926383d10b21f780208e48 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/305102 > > Commit-Queue: Adlai Holler <adlai@google.com> > > Reviewed-by: Robert Phillips <robertphillips@google.com> > > Reviewed-by: Brian Salomon <bsalomon@google.com> > > Auto-Submit: Adlai Holler <adlai@google.com> > > TBR=bsalomon@google.com,robertphillips@google.com,adlai@google.com > > Change-Id: I570945521c6cd78dfeea81e492b7e2b31dd0e6f5 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: skia:104662 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/308505 > Reviewed-by: Adlai Holler <adlai@google.com> > Commit-Queue: Adlai Holler <adlai@google.com> TBR=bsalomon@google.com,robertphillips@google.com,adlai@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Bug: skia:104662 Change-Id: Ie1d7fd9e597e6e6e5bd91bec086e83a8c1f45a37 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309321 Reviewed-by: Adlai Holler <adlai@google.com> Commit-Queue: Adlai Holler <adlai@google.com> Auto-Submit: Adlai Holler <adlai@google.com>
2020-08-11 15:48:49 +00:00
sk_sp<SkImage> create_image(GrDirectContext* dContext, const GrBackendTexture& backendTex) {
SkImage::CompressionType compression =
GrBackendFormatToCompressionType(backendTex.getBackendFormat());
SkAlphaType at = SkCompressionTypeIsOpaque(compression) ? kOpaque_SkAlphaType
: kPremul_SkAlphaType;
Reland "Migrate SkImage::MakeFromTexture to GrRecordingContext" This reverts commit 74b83a4ea9e31dbdc1996a1ed2d1844d5cdbe9b7. Reason for revert: Flutter is updated Original change's description: > Revert "Migrate SkImage::MakeFromTexture to GrRecordingContext" > > This reverts commit daa9e7455d4f0f54dc07f405becba5d0c5964847. > > Reason for revert: Broke Build-Debian9-Clang-arm-Release-Flutter_Android_Docker > > Original change's description: > > Migrate SkImage::MakeFromTexture to GrRecordingContext > > > > Android migration landed in Android CL 12234077 > > Chrome migration is landing in Chrome CL 2335812 > > > > Note: makeFromCompressedTexture is not used by Chrome. > > > > Bug: skia:104662 > > Change-Id: Ibbe6d412cf22e87188926383d10b21f780208e48 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/305102 > > Commit-Queue: Adlai Holler <adlai@google.com> > > Reviewed-by: Robert Phillips <robertphillips@google.com> > > Reviewed-by: Brian Salomon <bsalomon@google.com> > > Auto-Submit: Adlai Holler <adlai@google.com> > > TBR=bsalomon@google.com,robertphillips@google.com,adlai@google.com > > Change-Id: I570945521c6cd78dfeea81e492b7e2b31dd0e6f5 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: skia:104662 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/308505 > Reviewed-by: Adlai Holler <adlai@google.com> > Commit-Queue: Adlai Holler <adlai@google.com> TBR=bsalomon@google.com,robertphillips@google.com,adlai@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Bug: skia:104662 Change-Id: Ie1d7fd9e597e6e6e5bd91bec086e83a8c1f45a37 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309321 Reviewed-by: Adlai Holler <adlai@google.com> Commit-Queue: Adlai Holler <adlai@google.com> Auto-Submit: Adlai Holler <adlai@google.com>
2020-08-11 15:48:49 +00:00
return SkImage::MakeFromCompressedTexture(dContext,
backendTex,
kTopLeft_GrSurfaceOrigin,
at,
nullptr);
}
// Draw the compressed backend texture (wrapped in an SkImage) into an RGBA surface, attempting
// to access all the mipMap levels.
static void check_compressed_mipmaps(GrRecordingContext* rContext, sk_sp<SkImage> img,
SkImage::CompressionType compressionType,
const SkColor4f expectedColors[6],
GrMipmapped mipMapped,
skiatest::Reporter* reporter, const char* label) {
SkImageInfo readbackSurfaceII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
kPremul_SkAlphaType);
sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(rContext,
SkBudgeted::kNo,
readbackSurfaceII, 1,
kTopLeft_GrSurfaceOrigin,
nullptr);
if (!surf) {
return;
}
SkCanvas* canvas = surf->getCanvas();
const SkSamplingOptions sampling(SkFilterMode::kLinear,
SkMipmapMode::kLinear);
SkPaint p;
p.setBlendMode(SkBlendMode::kSrc);
int numMipLevels = 1;
if (mipMapped == GrMipmapped::kYes) {
numMipLevels = SkMipmap::ComputeLevelCount(32, 32)+1;
}
for (int i = 0, rectSize = 32; i < numMipLevels; ++i, rectSize /= 2) {
SkASSERT(rectSize >= 1);
canvas->clear(SK_ColorTRANSPARENT);
SkRect r = SkRect::MakeWH(rectSize, rectSize);
canvas->drawImageRect(img, r, sampling, &p);
SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
kRGBA_8888_SkColorType,
kUnpremul_SkAlphaType);
SkAutoPixmapStorage actual2;
SkAssertResult(actual2.tryAlloc(readbackII));
actual2.erase(SkColors::kTransparent);
bool result = surf->readPixels(actual2, 0, 0);
REPORTER_ASSERT(reporter, result);
SkString str;
str.appendf("mip-level %d", i);
check_solid_pixmap(reporter, expectedColors[i], actual2,
GrCompressionTypeToStr(compressionType), label, str.c_str());
}
}
// Verify that we can readback from a compressed texture
static void check_readback(GrDirectContext* dContext, sk_sp<SkImage> img,
SkImage::CompressionType compressionType,
const SkColor4f& expectedColor,
skiatest::Reporter* reporter, const char* label) {
#ifdef SK_BUILD_FOR_IOS
// reading back ETC2 is broken on Metal/iOS (skbug.com/9839)
if (dContext->backend() == GrBackendApi::kMetal) {
return;
}
#endif
SkAutoPixmapStorage actual;
SkImageInfo readBackII = SkImageInfo::Make(img->width(), img->height(),
kRGBA_8888_SkColorType,
kUnpremul_SkAlphaType);
SkAssertResult(actual.tryAlloc(readBackII));
actual.erase(SkColors::kTransparent);
bool result = img->readPixels(dContext, actual, 0, 0);
REPORTER_ASSERT(reporter, result);
check_solid_pixmap(reporter, expectedColor, actual,
GrCompressionTypeToStr(compressionType), label, "");
}
// Test initialization of compressed GrBackendTextures to a specific color
static void test_compressed_color_init(GrDirectContext* dContext,
skiatest::Reporter* reporter,
std::function<GrBackendTexture (GrDirectContext*,
const SkColor4f&,
GrMipmapped)> create,
const SkColor4f& color,
SkImage::CompressionType compression,
GrMipmapped mipMapped) {
GrBackendTexture backendTex = create(dContext, color, mipMapped);
if (!backendTex.isValid()) {
return;
}
sk_sp<SkImage> img = create_image(dContext, backendTex);
if (!img) {
return;
}
SkColor4f expectedColors[6] = { color, color, color, color, color, color };
check_compressed_mipmaps(dContext, img, compression, expectedColors, mipMapped,
reporter, "colorinit");
Reland "Add GrContext api to update compressed backend textures." This reverts commit ceebe424b1475ebdcf55f769e58b5e1a45b272c9. Reason for revert: relanding with fix Original change's description: > Revert "Add GrContext api to update compressed backend textures." > > This reverts commit 2c180304dc239a44770df7bf2649f3138f25922c. > > Reason for revert: attempted workaround did not fix techno spark so needs further investigation > > Original change's description: > > Add GrContext api to update compressed backend textures. > > > > Bug: chromium:1099255 > > Change-Id: I0c3f25ddb037e47e3b910fa89c3d8b3aa27b3114 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302265 > > Reviewed-by: Brian Salomon <bsalomon@google.com> > > Reviewed-by: Robert Phillips <robertphillips@google.com> > > Commit-Queue: Greg Daniel <egdaniel@google.com> > > TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com > > Change-Id: Ib5433def02dc5dad97dcdbd4476ced6de2361e6a > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: chromium:1099255 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302576 > Reviewed-by: Greg Daniel <egdaniel@google.com> > Commit-Queue: Greg Daniel <egdaniel@google.com> TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Bug: chromium:1099255 Change-Id: Ie238a56b7f12fea8b6e251a050e5e2f4b20d2ede Reviewed-on: https://skia-review.googlesource.com/c/skia/+/304741 Reviewed-by: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
2020-07-22 16:09:26 +00:00
check_readback(dContext, img, compression, color, reporter, "solid readback");
SkColor4f newColor;
newColor.fR = color.fB;
newColor.fG = color.fR;
newColor.fB = color.fG;
newColor.fA = color.fA;
bool result = dContext->updateCompressedBackendTexture(backendTex, newColor, nullptr, nullptr);
// Since we were able to create the compressed texture we should be able to update it.
REPORTER_ASSERT(reporter, result);
SkColor4f expectedNewColors[6] = {newColor, newColor, newColor, newColor, newColor, newColor};
check_compressed_mipmaps(dContext, img, compression, expectedNewColors, mipMapped, reporter,
"colorinit");
check_readback(dContext, std::move(img), compression, newColor, reporter, "solid readback");
dContext->deleteBackendTexture(backendTex);
}
// Create compressed data pulling the color for each mipmap level from 'levelColors'.
static std::unique_ptr<const char[]> make_compressed_data(SkImage::CompressionType compression,
SkColor4f levelColors[6],
GrMipmapped mipMapped) {
SkISize dimensions { 32, 32 };
int numMipLevels = 1;
if (mipMapped == GrMipmapped::kYes) {
numMipLevels = SkMipmap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
}
SkTArray<size_t> mipMapOffsets(numMipLevels);
size_t dataSize = SkCompressedDataSize(compression, dimensions, &mipMapOffsets,
mipMapped == GrMipmapped::kYes);
char* data = new char[dataSize];
for (int level = 0; level < numMipLevels; ++level) {
// We have to do this a level at a time bc we might have a different color for
// each level
GrFillInCompressedData(compression, dimensions,
GrMipmapped::kNo, &data[mipMapOffsets[level]], levelColors[level]);
dimensions = {std::max(1, dimensions.width() /2), std::max(1, dimensions.height()/2)};
}
return std::unique_ptr<const char[]>(data);
}
// Verify that we can initialize a compressed backend texture with data (esp.
// the mipmap levels).
static void test_compressed_data_init(GrDirectContext* dContext,
skiatest::Reporter* reporter,
std::function<GrBackendTexture (GrDirectContext*,
const char* data,
size_t dataSize,
GrMipmapped)> create,
SkImage::CompressionType compression,
GrMipmapped mipMapped) {
SkColor4f expectedColors[6] = {
{ 1.0f, 0.0f, 0.0f, 1.0f }, // R
{ 0.0f, 1.0f, 0.0f, 1.0f }, // G
{ 0.0f, 0.0f, 1.0f, 1.0f }, // B
{ 0.0f, 1.0f, 1.0f, 1.0f }, // C
{ 1.0f, 0.0f, 1.0f, 1.0f }, // M
{ 1.0f, 1.0f, 0.0f, 1.0f }, // Y
};
std::unique_ptr<const char[]> data(make_compressed_data(compression, expectedColors,
mipMapped));
size_t dataSize = SkCompressedDataSize(compression, { 32, 32 }, nullptr,
mipMapped == GrMipmapped::kYes);
GrBackendTexture backendTex = create(dContext, data.get(), dataSize, mipMapped);
if (!backendTex.isValid()) {
return;
}
sk_sp<SkImage> img = create_image(dContext, backendTex);
if (!img) {
return;
}
check_compressed_mipmaps(dContext, img, compression, expectedColors,
mipMapped, reporter, "pixmap");
Reland "Add GrContext api to update compressed backend textures." This reverts commit ceebe424b1475ebdcf55f769e58b5e1a45b272c9. Reason for revert: relanding with fix Original change's description: > Revert "Add GrContext api to update compressed backend textures." > > This reverts commit 2c180304dc239a44770df7bf2649f3138f25922c. > > Reason for revert: attempted workaround did not fix techno spark so needs further investigation > > Original change's description: > > Add GrContext api to update compressed backend textures. > > > > Bug: chromium:1099255 > > Change-Id: I0c3f25ddb037e47e3b910fa89c3d8b3aa27b3114 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302265 > > Reviewed-by: Brian Salomon <bsalomon@google.com> > > Reviewed-by: Robert Phillips <robertphillips@google.com> > > Commit-Queue: Greg Daniel <egdaniel@google.com> > > TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com > > Change-Id: Ib5433def02dc5dad97dcdbd4476ced6de2361e6a > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: chromium:1099255 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302576 > Reviewed-by: Greg Daniel <egdaniel@google.com> > Commit-Queue: Greg Daniel <egdaniel@google.com> TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Bug: chromium:1099255 Change-Id: Ie238a56b7f12fea8b6e251a050e5e2f4b20d2ede Reviewed-on: https://skia-review.googlesource.com/c/skia/+/304741 Reviewed-by: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
2020-07-22 16:09:26 +00:00
check_readback(dContext, img, compression, expectedColors[0], reporter, "data readback");
SkColor4f expectedColorsNew[6] = {
{1.0f, 1.0f, 0.0f, 1.0f}, // Y
{1.0f, 0.0f, 0.0f, 1.0f}, // R
{0.0f, 1.0f, 0.0f, 1.0f}, // G
{0.0f, 0.0f, 1.0f, 1.0f}, // B
{0.0f, 1.0f, 1.0f, 1.0f}, // C
{1.0f, 0.0f, 1.0f, 1.0f}, // M
};
std::unique_ptr<const char[]> dataNew(
make_compressed_data(compression, expectedColorsNew, mipMapped));
size_t dataNewSize =
SkCompressedDataSize(compression, {32, 32}, nullptr, mipMapped == GrMipMapped::kYes);
bool result = dContext->updateCompressedBackendTexture(backendTex, dataNew.get(), dataNewSize,
nullptr, nullptr);
// Since we were able to create the compressed texture we should be able to update it.
REPORTER_ASSERT(reporter, result);
check_compressed_mipmaps(dContext, img, compression, expectedColorsNew, mipMapped, reporter,
"pixmap");
check_readback(dContext, std::move(img), compression, expectedColorsNew[0], reporter,
"data readback");
dContext->deleteBackendTexture(backendTex);
}
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CompressedBackendAllocationTest, reporter, ctxInfo) {
auto dContext = ctxInfo.directContext();
const GrCaps* caps = dContext->priv().caps();
struct {
SkImage::CompressionType fCompression;
SkColor4f fColor;
} combinations[] = {
{ SkImage::CompressionType::kETC2_RGB8_UNORM, SkColors::kRed },
{ SkImage::CompressionType::kBC1_RGB8_UNORM, SkColors::kBlue },
{ SkImage::CompressionType::kBC1_RGBA8_UNORM, SkColors::kTransparent },
};
for (auto combo : combinations) {
GrBackendFormat format = dContext->compressedBackendFormat(combo.fCompression);
if (!format.isValid()) {
continue;
}
if (!caps->isFormatTexturable(format)) {
continue;
}
for (auto mipMapped : { GrMipmapped::kNo, GrMipmapped::kYes }) {
if (GrMipmapped::kYes == mipMapped && !caps->mipmapSupport()) {
continue;
}
// color initialized
{
auto createWithColorMtd = [format](GrDirectContext* dContext,
const SkColor4f& color,
GrMipmapped mipMapped) {
return dContext->createCompressedBackendTexture(32, 32, format, color,
mipMapped, GrProtected::kNo);
};
test_compressed_color_init(dContext, reporter, createWithColorMtd,
combo.fColor, combo.fCompression, mipMapped);
}
// data initialized
{
auto createWithDataMtd = [format](GrDirectContext* dContext,
const char* data, size_t dataSize,
GrMipmapped mipMapped) {
return dContext->createCompressedBackendTexture(32, 32, format, data, dataSize,
mipMapped, GrProtected::kNo);
};
test_compressed_data_init(dContext, reporter, createWithDataMtd,
combo.fCompression, mipMapped);
}
}
}
}