Update comparison in BackendAllocation tests
Change-Id: I11760741251b03dfb457d4b07ef3cb6a560c6f7b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/240683
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index ee0b610..53ac706 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -1515,7 +1515,7 @@
case GrColorType::kUnknown: return "kUnknown";
case GrColorType::kAlpha_8: return "kAlpha_8";
case GrColorType::kBGR_565: return "kRGB_565";
- case GrColorType::kABGR_4444: return "kARGB_4444";
+ case GrColorType::kABGR_4444: return "kABGR_4444";
case GrColorType::kRGBA_8888: return "kRGBA_8888";
case GrColorType::kRGBA_8888_SRGB: return "kRGBA_8888_SRGB";
case GrColorType::kRGB_888x: return "kRGB_888x";
diff --git a/tests/BackendAllocationTest.cpp b/tests/BackendAllocationTest.cpp
index 8632dad..276b80c 100644
--- a/tests/BackendAllocationTest.cpp
+++ b/tests/BackendAllocationTest.cpp
@@ -12,6 +12,8 @@
#include "src/gpu/GrContextPriv.h"
#include "src/image/SkImage_Base.h"
#include "tests/Test.h"
+#include "tests/TestUtils.h"
+#include "tools/ToolUtils.h"
#ifdef SK_GL
#include "src/gpu/gl/GrGLGpu.h"
@@ -91,38 +93,51 @@
context->deleteBackendTexture(backendTex);
}
-static bool colors_eq(SkColor colA, SkColor colB, int tol) {
- int maxDiff = 0;
- for (int i = 0; i < 4; ++i) {
- int diff = SkTAbs<int>((0xFF & (colA >> i*8)) - (0xFF & (colB >> i*8)));
- if (maxDiff < diff) {
- maxDiff = diff;
- }
- }
+static void check_solid_pixmap(skiatest::Reporter* reporter,
+ const SkColor4f& expected, const SkPixmap& actual,
+ SkColorType ct, const char* label) {
+ // we need 0.001f across the board just for noise
+ // we need 0.01f across the board for 1010102
+ const float tols[4] = {0.01f, 0.01f, 0.01f, 0.01f};
- return maxDiff <= tol;
+ auto error = std::function<ComparePixmapsErrorReporter>(
+ [reporter, ct, label](int x, int y, const float diffs[4]) {
+ SkASSERT(x >= 0 && y >= 0);
+ ERRORF(reporter, "%s %s - mismatch at %d, %d (%f, %f, %f %f)",
+ ToolUtils::colortype_name(ct), label, x, y,
+ diffs[0], diffs[1], diffs[2], diffs[3]);
+ });
+
+ check_solid_pixels(expected, actual, tols, error);
}
-static void compare_pixmaps(const SkPixmap& expected, const SkPixmap& actual,
- SkColorType colorType, skiatest::Reporter* reporter) {
- SkASSERT(expected.info() == actual.info());
- for (int y = 0; y < expected.height(); ++y) {
- for (int x = 0; x < expected.width(); ++x) {
+static SkColor4f get_expected_color(SkColor4f orig, SkColorType ct) {
- SkColor expectedCol = expected.getColor(x, y);
- SkColor actualCol = actual.getColor(x, y);
+ uint32_t components = SkColorTypeComponentFlags(ct);
- // GPU and raster differ a bit on kGray_8_SkColorType and kRGBA_1010102_SkColorType
- if (colors_eq(actualCol, expectedCol, 12)) {
- continue;
- }
-
- ERRORF(reporter,
- "Mismatched pixels at %d %d ct: %d expected: 0x%x actual: 0x%x\n",
- x, y, colorType, expectedCol, actualCol);
- return;
- }
+ if (components & kGray_SkColorTypeComponentFlag) {
+ // For the GPU backends, gray implies a single channel which is opaque.
+ return { orig.fA, orig.fA, orig.fA, 1 };
}
+
+ float r = orig.fR, g = orig.fG, b = orig.fB, a = orig.fA;
+
+ // Missing channels are set to 0
+ if (!(components & kRed_SkColorTypeComponentFlag)) {
+ r = 0;
+ }
+ if (!(components & kGreen_SkColorTypeComponentFlag)) {
+ g = 0;
+ }
+ if (!(components & kBlue_SkColorTypeComponentFlag)) {
+ b = 0;
+ }
+ // except for missing alpha - which gets set to 1
+ if (!(components & kAlpha_SkColorTypeComponentFlag)) {
+ a = 1;
+ }
+
+ return { r, g, b, a };
}
// Test initialization of GrBackendObjects to a specific color
@@ -153,24 +168,7 @@
SkImageInfo ii = SkImageInfo::Make(32, 32, skColorType, at);
- SkColor4f rasterColor = color;
- if (kGray_8_SkColorType == skColorType) {
- // For the GPU backends, gray implies a single channel which is opaque.
- rasterColor.fR = color.fA;
- rasterColor.fG = color.fA;
- rasterColor.fB = color.fA;
- rasterColor.fA = 1.0f;
- } else if (kAlpha_8_SkColorType == skColorType) {
- // For the GPU backends, alpha implies a single alpha channel.
- rasterColor.fR = 0;
- rasterColor.fG = 0;
- rasterColor.fB = 0;
- rasterColor.fA = color.fA;
- }
-
- SkAutoPixmapStorage expected;
- SkAssertResult(expected.tryAlloc(ii));
- expected.erase(rasterColor);
+ SkColor4f expectedColor = get_expected_color(color, skColorType);
SkAutoPixmapStorage actual;
SkAssertResult(actual.tryAlloc(ii));
@@ -187,7 +185,8 @@
bool result = surf->readPixels(actual, 0, 0);
REPORTER_ASSERT(reporter, result);
- compare_pixmaps(expected, actual, skColorType, reporter);
+ check_solid_pixmap(reporter, expectedColor, actual, skColorType,
+ "SkSurface::readPixels");
actual.erase(SkColors::kTransparent);
}
@@ -212,7 +211,8 @@
colorType);
#endif
} else {
- compare_pixmaps(expected, actual, skColorType, reporter);
+ check_solid_pixmap(reporter, expectedColor, actual, skColorType,
+ "SkImage::readPixels");
}
}
@@ -235,10 +235,6 @@
SkImageInfo newII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
kPremul_SkAlphaType);
- SkAutoPixmapStorage actual2;
- SkAssertResult(actual2.tryAlloc(newII));
- actual2.erase(SkColors::kTransparent);
-
sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context,
SkBudgeted::kNo,
newII, 1,
@@ -263,15 +259,18 @@
canvas->clear(SK_ColorTRANSPARENT);
canvas->drawImageRect(img, r, &p);
+ SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
+ kRGBA_8888_SkColorType,
+ kPremul_SkAlphaType);
+ SkAutoPixmapStorage actual2;
+ SkAssertResult(actual2.tryAlloc(readbackII));
+ actual2.erase(SkColors::kTransparent);
+
bool result = surf->readPixels(actual2, 0, 0);
REPORTER_ASSERT(reporter, result);
- SkColor actualColor = actual2.getColor(0, 0);
-
- if (!colors_eq(actualColor, rasterColor.toSkColor(), 1)) {
- ERRORF(reporter, "Pixel mismatch colorType %d: level: %d e: 0x%x a: 0x%x\n",
- skColorType, i, rasterColor.toSkColor(), actualColor);
- }
+ check_solid_pixmap(reporter, expectedColor, actual2, skColorType,
+ "mip-level failure");
}
}
}
@@ -408,25 +407,24 @@
struct {
SkColorType fColorType;
- GrPixelConfig fConfig;
SkColor4f fColor;
} combinations[] = {
- { kAlpha_8_SkColorType, kAlpha_8_GrPixelConfig, kTransCol },
- { kRGB_565_SkColorType, kRGB_565_GrPixelConfig, SkColors::kRed },
- { kARGB_4444_SkColorType, kRGBA_4444_GrPixelConfig, SkColors::kGreen },
- { kRGBA_8888_SkColorType, kRGBA_8888_GrPixelConfig, SkColors::kBlue },
- { kRGB_888x_SkColorType, kRGB_888_GrPixelConfig, SkColors::kCyan },
+ { kAlpha_8_SkColorType, kTransCol },
+ { kRGB_565_SkColorType, SkColors::kRed },
+ { kARGB_4444_SkColorType, SkColors::kGreen },
+ { kRGBA_8888_SkColorType, SkColors::kBlue },
+ { kRGB_888x_SkColorType, SkColors::kCyan },
// TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
- { kBGRA_8888_SkColorType, kBGRA_8888_GrPixelConfig, { 1, 0, 0, 1.0f } },
+ { kBGRA_8888_SkColorType, { 1, 0, 0, 1.0f } },
// TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
- { kRGBA_1010102_SkColorType, kRGBA_1010102_GrPixelConfig, { 0.5f, 0, 0, 1.0f }},
+ { kRGBA_1010102_SkColorType, { .25f, .5f, .75f, 1.0f }},
// The kRGB_101010x_SkColorType has no Ganesh correlate
- { kRGB_101010x_SkColorType, kUnknown_GrPixelConfig, { 0, 0.5f, 0, 0.5f }},
- { kGray_8_SkColorType, kGray_8_GrPixelConfig, kGrayCol },
- { kRGBA_F16Norm_SkColorType, kRGBA_half_Clamped_GrPixelConfig, SkColors::kLtGray },
- { kRGBA_F16_SkColorType, kRGBA_half_GrPixelConfig, SkColors::kYellow },
- { kRGBA_F32_SkColorType, kRGBA_float_GrPixelConfig, SkColors::kGray },
- { kRG_88_SkColorType, kRG_88_GrPixelConfig, SkColors::kRed },
+ { kRGB_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
+ { kGray_8_SkColorType, kGrayCol },
+ { kRGBA_F16Norm_SkColorType, SkColors::kLtGray },
+ { kRGBA_F16_SkColorType, SkColors::kYellow },
+ { kRGBA_F32_SkColorType, SkColors::kGray },
+ { kRG_88_SkColorType, { .25f, .75f, 0, 0 } },
};
GR_STATIC_ASSERT(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
diff --git a/tests/ExtendedSkColorTypeTests.cpp b/tests/ExtendedSkColorTypeTests.cpp
index db8fb65..c334ebf 100644
--- a/tests/ExtendedSkColorTypeTests.cpp
+++ b/tests/ExtendedSkColorTypeTests.cpp
@@ -12,6 +12,7 @@
#include "tests/Test.h"
#include "tests/TestUtils.h"
+#include "tools/ToolUtils.h"
static constexpr int kSize = 32;
@@ -151,14 +152,14 @@
static void compare_pixmaps(skiatest::Reporter* reporter,
const SkPixmap& expected, const SkPixmap& actual,
- SkColorType nativeCT, const char* label) {
+ SkColorType ct, const char* label) {
const float tols[4] = {0.0f, 0.0f, 0.0f, 0};
auto error = std::function<ComparePixmapsErrorReporter>(
- [reporter, nativeCT, label](int x, int y, const float diffs[4]) {
+ [reporter, ct, label](int x, int y, const float diffs[4]) {
SkASSERT(x >= 0 && y >= 0);
- ERRORF(reporter, "%d %s - mismatch at %d, %d (%f, %f, %f %f)",
- nativeCT, label, x, y,
+ ERRORF(reporter, "%s %s - mismatch at %d, %d (%f, %f, %f %f)",
+ ToolUtils::colortype_name(ct), label, x, y,
diffs[0], diffs[1], diffs[2], diffs[3]);
});
diff --git a/tests/TestUtils.cpp b/tests/TestUtils.cpp
index 42cb808..b813ff8 100644
--- a/tests/TestUtils.cpp
+++ b/tests/TestUtils.cpp
@@ -177,6 +177,34 @@
return true;
}
+using AccessPixelFn = const float*(const char* floatBuffer, int x, int y);
+
+bool compare_pixels(int width, int height,
+ const char* floatA, std::function<AccessPixelFn>& atA,
+ const char* floatB, std::function<AccessPixelFn>& atB,
+ const float tolRGBA[4], std::function<ComparePixmapsErrorReporter>& error) {
+
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ const float* rgbaA = atA(floatA, x, y);
+ const float* rgbaB = atB(floatB, x, y);
+ float diffs[4];
+ bool bad = false;
+ for (int i = 0; i < 4; ++i) {
+ diffs[i] = rgbaB[i] - rgbaA[i];
+ if (std::abs(diffs[i]) > std::abs(tolRGBA[i])) {
+ bad = true;
+ }
+ }
+ if (bad) {
+ error(x, y, diffs);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
bool compare_pixels(const GrPixelInfo& infoA, const char* a, size_t rowBytesA,
const GrPixelInfo& infoB, const char* b, size_t rowBytesB,
const float tolRGBA[4], std::function<ComparePixmapsErrorReporter>& error) {
@@ -210,28 +238,14 @@
SkAssertResult(GrConvertPixels(floatInfo, floatA.get(), floatRowBytes, infoA, a, rowBytesA));
SkAssertResult(GrConvertPixels(floatInfo, floatB.get(), floatRowBytes, infoB, b, rowBytesB));
- auto at = [floatBpp, floatRowBytes](const char* floatBuffer, int x, int y) {
- return reinterpret_cast<const float*>(floatBuffer + y * floatRowBytes + x * floatBpp);
- };
- for (int y = 0; y < infoA.height(); ++y) {
- for (int x = 0; x < infoA.width(); ++x) {
- const float* rgbaA = at(floatA.get(), x, y);
- const float* rgbaB = at(floatB.get(), x, y);
- float diffs[4];
- bool bad = false;
- for (int i = 0; i < 4; ++i) {
- diffs[i] = rgbaB[i] - rgbaA[i];
- if (std::abs(diffs[i]) > std::abs(tolRGBA[i])) {
- bad = true;
- }
- }
- if (bad) {
- error(x, y, diffs);
- return false;
- }
- }
- }
- return true;
+ auto at = std::function<AccessPixelFn>(
+ [floatBpp, floatRowBytes](const char* floatBuffer, int x, int y) {
+ return reinterpret_cast<const float*>(floatBuffer + y * floatRowBytes + x * floatBpp);
+ });
+
+ return compare_pixels(infoA.width(), infoA.height(),
+ floatA.get(), at, floatB.get(), at,
+ tolRGBA, error);
}
bool compare_pixels(const SkPixmap& a, const SkPixmap& b, const float tolRGBA[4],
@@ -241,6 +255,47 @@
tolRGBA, error);
}
+bool check_solid_pixels(const SkColor4f& col, const SkPixmap& pixmap,
+ const float tolRGBA[4], std::function<ComparePixmapsErrorReporter>& error) {
+
+ size_t floatBpp = GrColorTypeBytesPerPixel(GrColorType::kRGBA_F32);
+
+ std::unique_ptr<char[]> floatA(new char[floatBpp]);
+ // First convert 'col' to be compatible with 'pixmap'
+ {
+ sk_sp<SkColorSpace> srcCS = SkColorSpace::MakeSRGBLinear();
+ GrPixelInfo srcInfo(GrColorType::kRGBA_F32, kUnpremul_SkAlphaType, std::move(srcCS), 1, 1);
+ GrPixelInfo dstInfo(GrColorType::kRGBA_F32, pixmap.alphaType(), pixmap.refColorSpace(), 1, 1);
+
+ SkAssertResult(GrConvertPixels(dstInfo, floatA.get(), floatBpp, srcInfo,
+ col.vec(), floatBpp));
+ }
+
+ size_t floatRowBytes = floatBpp * pixmap.width();
+ std::unique_ptr<char[]> floatB(new char[floatRowBytes * pixmap.height()]);
+ // Then convert 'pixmap' to RGBA_F32
+ {
+ GrPixelInfo dstInfo(GrColorType::kRGBA_F32, pixmap.alphaType(), pixmap.refColorSpace(),
+ pixmap.width(), pixmap.height());
+
+ SkAssertResult(GrConvertPixels(dstInfo, floatB.get(), floatRowBytes, pixmap.info(),
+ pixmap.addr(), pixmap.rowBytes()));
+ }
+
+ auto atA = std::function<AccessPixelFn>(
+ [](const char* floatBuffer, int /* x */, int /* y */) {
+ return reinterpret_cast<const float*>(floatBuffer);
+ });
+
+ auto atB = std::function<AccessPixelFn>(
+ [floatBpp, floatRowBytes](const char* floatBuffer, int x, int y) {
+ return reinterpret_cast<const float*>(floatBuffer + y * floatRowBytes + x * floatBpp);
+ });
+
+ return compare_pixels(pixmap.width(), pixmap.height(), floatA.get(), atA, floatB.get(), atB,
+ tolRGBA, error);
+}
+
#include "src/utils/SkCharToGlyphCache.h"
static SkGlyphID hash_to_glyph(uint32_t value) {
diff --git a/tests/TestUtils.h b/tests/TestUtils.h
index 660cdb4..347139d 100644
--- a/tests/TestUtils.h
+++ b/tests/TestUtils.h
@@ -75,3 +75,9 @@
/** Convenience version of above that takes SkPixmap inputs. */
bool compare_pixels(const SkPixmap& a, const SkPixmap& b, const float tolRGBA[4],
std::function<ComparePixmapsErrorReporter>& error);
+
+/**
+ * Convenience version that checks that 'pixmap' is a solid field of 'col'
+ */
+bool check_solid_pixels(const SkColor4f& col, const SkPixmap& pixmap,
+ const float tolRGBA[4], std::function<ComparePixmapsErrorReporter>& error);