Make pixel comparison utility in ReadPixelsTest shareable
Also make it support GrColorType Change-Id: I2aecb82dd1b8e3bc942549f2023ff5cae9deb4f3 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/227403 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
acf98df7a1
commit
85aeccfb9d
@ -19,6 +19,7 @@
|
||||
#include "src/gpu/GrProxyProvider.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
#include "tests/Test.h"
|
||||
#include "tests/TestUtils.h"
|
||||
#include "tools/gpu/GrContextFactory.h"
|
||||
#include "tools/gpu/ProxyUtils.h"
|
||||
|
||||
@ -619,45 +620,6 @@ DEF_TEST(ReadPixels_ValidConversion, reporter) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
using ComparePixmapsErrorReporter = void(int x, int y, const float diffs[4]);
|
||||
} // anonymous namespace
|
||||
|
||||
static void compare_pixmaps(const SkPixmap& a, const SkPixmap& b, const float tol[4],
|
||||
std::function<ComparePixmapsErrorReporter>& error) {
|
||||
if (a.width() != b.width() || a.height() != b.height()) {
|
||||
static constexpr float kDummyDiffs[4] = {};
|
||||
error(-1, -1, kDummyDiffs);
|
||||
return;
|
||||
}
|
||||
SkAutoPixmapStorage afloat;
|
||||
SkAutoPixmapStorage bfloat;
|
||||
afloat.alloc(a.info().makeColorType(kRGBA_F32_SkColorType));
|
||||
bfloat.alloc(b.info().makeColorType(kRGBA_F32_SkColorType));
|
||||
SkConvertPixels(afloat.info(), afloat.writable_addr(), afloat.rowBytes(), a.info(), a.addr(),
|
||||
a.rowBytes());
|
||||
SkConvertPixels(bfloat.info(), bfloat.writable_addr(), bfloat.rowBytes(), b.info(), b.addr(),
|
||||
b.rowBytes());
|
||||
for (int y = 0; y < a.height(); ++y) {
|
||||
for (int x = 0; x < a.width(); ++x) {
|
||||
const float* rgbaA = static_cast<const float*>(afloat.addr(x, y));
|
||||
const float* rgbaB = static_cast<const float*>(bfloat.addr(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]) > tol[i]) {
|
||||
bad = true;
|
||||
}
|
||||
}
|
||||
if (bad) {
|
||||
error(x, y, diffs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int min_rgb_channel_bits(SkColorType ct) {
|
||||
switch (ct) {
|
||||
case kUnknown_SkColorType: return 0;
|
||||
@ -781,6 +743,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(AsyncReadPixels, reporter, ctxInfo) {
|
||||
const float tols[4] = {tol, tol, tol, 0};
|
||||
auto error = std::function<ComparePixmapsErrorReporter>(
|
||||
[&](int x, int y, const float diffs[4]) {
|
||||
SkASSERT(x >= 0 && y >= 0);
|
||||
ERRORF(reporter,
|
||||
"Surf Color Type: %d, Read CT: %d, Rect [%d, %d, %d, %d]"
|
||||
", origin: %d, CS conversion: %d\n"
|
||||
@ -789,7 +752,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(AsyncReadPixels, reporter, ctxInfo) {
|
||||
rect.fBottom, origin, (bool)readCS, x, y, diffs[0],
|
||||
diffs[1], diffs[2], diffs[3]);
|
||||
});
|
||||
compare_pixmaps(ref, result, tols, error);
|
||||
compare_pixels(ref, result, tols, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,6 +172,70 @@ bool bitmap_to_base64_data_uri(const SkBitmap& bitmap, SkString* dst) {
|
||||
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) {
|
||||
if (infoA.width() != infoB.width() || infoA.height() != infoB.height()) {
|
||||
static constexpr float kDummyDiffs[4] = {};
|
||||
error(-1, -1, kDummyDiffs);
|
||||
return false;
|
||||
}
|
||||
|
||||
SkAlphaType floatAlphaType = infoA.alphaType();
|
||||
// If one is premul and the other is unpremul we do the comparison in premul space.
|
||||
if ((infoA.alphaType() == kPremul_SkAlphaType ||
|
||||
infoB.alphaType() == kPremul_SkAlphaType) &&
|
||||
(infoA.alphaType() == kUnpremul_SkAlphaType ||
|
||||
infoB.alphaType() == kUnpremul_SkAlphaType)) {
|
||||
floatAlphaType = kPremul_SkAlphaType;
|
||||
}
|
||||
sk_sp<SkColorSpace> floatCS;
|
||||
if (SkColorSpace::Equals(infoA.colorSpace(), infoB.colorSpace())) {
|
||||
floatCS = infoA.refColorSpace();
|
||||
} else {
|
||||
floatCS = SkColorSpace::MakeSRGBLinear();
|
||||
}
|
||||
GrPixelInfo floatInfo(GrColorType::kRGBA_F32, floatAlphaType, std::move(floatCS),
|
||||
infoA.width(), infoA.height());
|
||||
|
||||
size_t floatBpp = GrColorTypeBytesPerPixel(GrColorType::kRGBA_F32);
|
||||
size_t floatRowBytes = floatBpp * infoA.width();
|
||||
std::unique_ptr<char[]> floatA(new char[floatRowBytes * infoA.height()]);
|
||||
std::unique_ptr<char[]> floatB(new char[floatRowBytes * infoA.height()]);
|
||||
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;
|
||||
}
|
||||
|
||||
bool compare_pixels(const SkPixmap& a, const SkPixmap& b, const float tolRGBA[4],
|
||||
std::function<ComparePixmapsErrorReporter>& error) {
|
||||
return compare_pixels(a.info(), static_cast<const char*>(a.addr()), a.rowBytes(),
|
||||
b.info(), static_cast<const char*>(b.addr()), b.rowBytes(),
|
||||
tolRGBA, error);
|
||||
}
|
||||
|
||||
#include "src/utils/SkCharToGlyphCache.h"
|
||||
|
||||
static SkGlyphID hash_to_glyph(uint32_t value) {
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "include/core/SkBitmap.h"
|
||||
#include "src/gpu/GrDataUtils.h"
|
||||
#include "tests/Test.h"
|
||||
|
||||
class GrSurfaceContext;
|
||||
@ -44,3 +45,33 @@ bool does_full_buffer_contain_correct_color(const GrColor* srcBuffer, const GrCo
|
||||
// Encodes the bitmap into a data:/image/png;base64,... url suitable to view in a browser after
|
||||
// printing to a log. If false is returned, dst holds an error message instead of a URI.
|
||||
bool bitmap_to_base64_data_uri(const SkBitmap& bitmap, SkString* dst);
|
||||
|
||||
/** Used by compare_pixels. */
|
||||
using ComparePixmapsErrorReporter = void(int x, int y, const float diffs[4]);
|
||||
|
||||
/**
|
||||
* Compares pixels pointed to by 'a' with 'infoA' and rowBytesA to pixels pointed to by 'b' with
|
||||
* 'infoB' and 'rowBytesB'.
|
||||
*
|
||||
* If the infos have different dimensions error is called with negative coordinate values and
|
||||
* zero diffs and no comparisons are made.
|
||||
*
|
||||
* Before comparison pixels are converted to a common color type, alpha type, and color space.
|
||||
* The color type is always 32 bit float. The alpha type is premul if one of 'infoA' and 'infoB' is
|
||||
* premul and the other is unpremul. The color space is linear sRGB if 'infoA' and 'infoB' have
|
||||
* different colorspaces, otherwise their common color space is used.
|
||||
*
|
||||
* 'tolRGBA' expresses the allowed difference between pixels in the comparison space per channel. If
|
||||
* pixel components differ more than by 'tolRGBA' in absolute value in any channel then 'error' is
|
||||
* called with the coordinate and difference in the comparison space (B - A).
|
||||
*
|
||||
* The function quits after a single error is reported and returns false if 'error' was called and
|
||||
* true otherwise.
|
||||
*/
|
||||
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);
|
||||
|
||||
/** 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);
|
||||
|
Loading…
Reference in New Issue
Block a user