Add kRG_88_SkColorType
Bug: skia:9121
Change-Id: Id2a12a5d607b84ce393d2b58233bf8e23f646059
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/235797
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/tests/BackendAllocationTest.cpp b/tests/BackendAllocationTest.cpp
index 70a1c6b..8632dad 100644
--- a/tests/BackendAllocationTest.cpp
+++ b/tests/BackendAllocationTest.cpp
@@ -47,7 +47,7 @@
return;
}
- if (GrRenderable::kYes == renderable) {
+ if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
backendTex,
kTopLeft_GrSurfaceOrigin,
@@ -176,7 +176,7 @@
SkAssertResult(actual.tryAlloc(ii));
actual.erase(SkColors::kTransparent);
- if (GrRenderable::kYes == renderable) {
+ if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
backendTex,
kTopLeft_GrSurfaceOrigin,
@@ -426,6 +426,7 @@
{ 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 },
};
GR_STATIC_ASSERT(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
@@ -571,7 +572,7 @@
{ GrColorType::kRGBA_F16_Clamped, GR_GL_RGBA16F, SkColors::kLtGray },
{ GrColorType::kRGBA_F16, GR_GL_RGBA16F, SkColors::kYellow },
- { GrColorType::kRG_88, GR_GL_RG8, { 0.5f, 0.5f, 0, 0 } },
+ { GrColorType::kRG_88, GR_GL_RG8, { 1, 0.5f, 0, 1 } },
{ GrColorType::kAlpha_F16, GR_GL_R16F, { 1.0f, 0, 0, 0.5f } },
{ GrColorType::kAlpha_F16, GR_GL_LUMINANCE16F, kGrayCol },
@@ -707,7 +708,7 @@
{ GrColorType::kRGBA_F16, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kYellow },
// These backend formats don't have SkColorType equivalents
- { GrColorType::kRG_88, VK_FORMAT_R8G8_UNORM, { 0.5f, 0.5f, 0, 0 }},
+ { GrColorType::kRG_88, VK_FORMAT_R8G8_UNORM, { 1, 0.5f, 0, 1 } },
{ GrColorType::kAlpha_F16, VK_FORMAT_R16_SFLOAT, { 1.0f, 0, 0, 0.5f }},
{ GrColorType::kR_16, VK_FORMAT_R16_UNORM, SkColors::kRed },
diff --git a/tests/BitmapTest.cpp b/tests/BitmapTest.cpp
index dbc5150..259ab08 100644
--- a/tests/BitmapTest.cpp
+++ b/tests/BitmapTest.cpp
@@ -178,20 +178,9 @@
// Test that SkBitmap::ComputeOpaque() is correct for various colortypes.
DEF_TEST(Bitmap_compute_is_opaque, r) {
- SkColorType colorTypes[] = {
- kAlpha_8_SkColorType,
- kRGB_565_SkColorType,
- kARGB_4444_SkColorType,
- kRGBA_8888_SkColorType,
- kRGB_888x_SkColorType,
- kBGRA_8888_SkColorType,
- kRGBA_1010102_SkColorType,
- kRGB_101010x_SkColorType,
- kGray_8_SkColorType,
- kRGBA_F16_SkColorType,
- kRGBA_F32_SkColorType,
- };
- for (auto ct : colorTypes) {
+
+ for (int i = 1; i <= kLastEnum_SkColorType; ++i) {
+ SkColorType ct = (SkColorType) i;
SkBitmap bm;
SkAlphaType at = SkColorTypeIsAlwaysOpaque(ct) ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
bm.allocPixels(SkImageInfo::Make(13, 17, ct, at));
@@ -342,6 +331,7 @@
} recs[] = {
{ kRGB_565_SkColorType, opaque },
{ kGray_8_SkColorType, opaque },
+ { kRG_88_SkColorType, opaque },
{ kRGB_888x_SkColorType, opaque },
{ kRGB_101010x_SkColorType, opaque },
diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp
index 03b12e1..7328dd0 100644
--- a/tests/DeferredDisplayListTest.cpp
+++ b/tests/DeferredDisplayListTest.cpp
@@ -144,6 +144,10 @@
SkSurfaceCharacterization createCharacterization(GrContext* context) const {
size_t maxResourceBytes = context->getResourceCacheLimit();
+ if (!context->colorTypeSupportedAsSurface(fColorType)) {
+ return SkSurfaceCharacterization();
+ }
+
// Note that Ganesh doesn't make use of the SkImageInfo's alphaType
SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
kPremul_SkAlphaType, fColorSpace);
diff --git a/tests/ExtendedSkColorTypeTests.cpp b/tests/ExtendedSkColorTypeTests.cpp
new file mode 100644
index 0000000..db8fb65
--- /dev/null
+++ b/tests/ExtendedSkColorTypeTests.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/core/SkImage.h"
+#include "include/core/SkSurface.h"
+#include "src/core/SkAutoPixmapStorage.h"
+#include "src/gpu/GrContextPriv.h"
+
+#include "tests/Test.h"
+#include "tests/TestUtils.h"
+
+static constexpr int kSize = 32;
+
+static SkColor4f get_trans_black_expected_color(SkColorTypeComponentFlag components) {
+ float a = 0;
+ if (!(components & kAlpha_SkColorTypeComponentFlag)) {
+ a = 1;
+ }
+
+ return { 0, 0, 0, a };
+}
+
+static SkColor4f get_opaque_white_expected_color(SkColorTypeComponentFlag components) {
+
+ if (components & kGray_SkColorTypeComponentFlag) {
+ return { 1, 1, 1, 1 };
+ }
+
+ float r = 1, g = 1, b = 1;
+ if (!(components & kRed_SkColorTypeComponentFlag)) {
+ r = 0;
+ }
+ if (!(components & kGreen_SkColorTypeComponentFlag)) {
+ g = 0;
+ }
+ if (!(components & kBlue_SkColorTypeComponentFlag)) {
+ b = 0;
+ }
+
+ return { r, g, b, 1.0f };
+}
+
+struct TestCase {
+ SkColorType fColorType;
+ SkAlphaType fAlphaType;
+ SkColorTypeComponentFlag fComponents;
+ bool fCanMakeSurfaces;
+};
+
+static const TestCase gTests[] = {
+ { kAlpha_8_SkColorType, kPremul_SkAlphaType, kAlpha_SkColorTypeComponentFlag, true },
+ { kRGB_565_SkColorType, kOpaque_SkAlphaType, kRGB_SkColorTypeComponentFlags, true },
+ { kARGB_4444_SkColorType, kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true },
+ { kRGBA_8888_SkColorType, kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true },
+ { kRGB_888x_SkColorType, kOpaque_SkAlphaType, kRGB_SkColorTypeComponentFlags, true },
+ { kBGRA_8888_SkColorType, kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true },
+ { kRGBA_1010102_SkColorType, kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true },
+ { kRGB_101010x_SkColorType, kOpaque_SkAlphaType, kRGB_SkColorTypeComponentFlags, true },
+ { kGray_8_SkColorType, kOpaque_SkAlphaType, kGray_SkColorTypeComponentFlag, true },
+ { kRGBA_F16Norm_SkColorType, kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true },
+ { kRGBA_F16_SkColorType, kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true },
+ { kRGBA_F32_SkColorType, kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true },
+ { kRG_88_SkColorType, kOpaque_SkAlphaType, kRG_SkColorTypeComponentFlags, false }
+};
+
+static void raster_tests(skiatest::Reporter* reporter, const TestCase& test) {
+
+ const SkImageInfo nativeII = SkImageInfo::Make(kSize, kSize, test.fColorType, test.fAlphaType);
+ const SkImageInfo f32Unpremul = SkImageInfo::Make(kSize, kSize, kRGBA_F32_SkColorType,
+ kUnpremul_SkAlphaType);
+
+ uint32_t actualComponents = SkColorTypeComponentFlags(test.fColorType);
+ REPORTER_ASSERT(reporter, test.fComponents == actualComponents);
+
+ // Not all colorTypes can be drawn to
+ {
+ auto s = SkSurface::MakeRaster(nativeII);
+ REPORTER_ASSERT(reporter, SkToBool(s) == test.fCanMakeSurfaces);
+ }
+
+ // opaque formats should make transparent black become opaque
+ {
+ SkAutoPixmapStorage pm;
+ pm.alloc(nativeII);
+ pm.erase(SkColors::kTransparent);
+ SkColor actual = pm.getColor(0, 0);
+ SkColor4f expected = get_trans_black_expected_color(test.fComponents);
+ REPORTER_ASSERT(reporter, expected.toSkColor() == actual);
+ }
+
+ // unused channels should drop out
+ {
+ SkAutoPixmapStorage pm;
+ pm.alloc(nativeII);
+ pm.erase(SkColors::kWhite);
+ SkColor actual = pm.getColor(0, 0);
+ SkColor4f expected = get_opaque_white_expected_color(test.fComponents);
+ REPORTER_ASSERT(reporter, expected.toSkColor() == actual);
+ }
+
+ // Reading back from an image to the same colorType should always work
+ {
+ SkAutoPixmapStorage srcPM;
+ srcPM.alloc(nativeII);
+ srcPM.erase(SkColors::kWhite);
+ auto i = SkImage::MakeFromRaster(srcPM, nullptr, nullptr);
+ REPORTER_ASSERT(reporter, SkToBool(i));
+
+ SkAutoPixmapStorage readbackPM;
+ readbackPM.alloc(nativeII);
+ readbackPM.erase(SkColors::kTransparent);
+
+ REPORTER_ASSERT(reporter, i->readPixels(readbackPM, 0, 0));
+
+ SkColor expected = srcPM.getColor(0, 0);
+ SkColor actual = readbackPM.getColor(0, 0);
+ REPORTER_ASSERT(reporter, expected == actual);
+ }
+
+ // Rendering to an F32 surface should always work
+ {
+ SkAutoPixmapStorage srcPM;
+ srcPM.alloc(nativeII);
+ srcPM.erase(SkColors::kWhite);
+ auto i = SkImage::MakeFromRaster(srcPM, nullptr, nullptr);
+ REPORTER_ASSERT(reporter, SkToBool(i));
+
+ auto s = SkSurface::MakeRaster(f32Unpremul);
+ REPORTER_ASSERT(reporter, SkToBool(s));
+
+ {
+ auto c = s->getCanvas();
+ c->drawImage(i, 0, 0);
+ }
+
+ SkAutoPixmapStorage readbackPM;
+ readbackPM.alloc(f32Unpremul);
+ readbackPM.erase(SkColors::kTransparent);
+
+ REPORTER_ASSERT(reporter, i->readPixels(readbackPM, 0, 0));
+
+ SkColor expected = srcPM.getColor(0, 0);
+ SkColor actual = readbackPM.getColor(0, 0);
+ REPORTER_ASSERT(reporter, expected == actual);
+ }
+}
+
+static void compare_pixmaps(skiatest::Reporter* reporter,
+ const SkPixmap& expected, const SkPixmap& actual,
+ SkColorType nativeCT, 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]) {
+ SkASSERT(x >= 0 && y >= 0);
+ ERRORF(reporter, "%d %s - mismatch at %d, %d (%f, %f, %f %f)",
+ nativeCT, label, x, y,
+ diffs[0], diffs[1], diffs[2], diffs[3]);
+ });
+
+ compare_pixels(expected, actual, tols, error);
+}
+
+static void gpu_tests(GrContext* context, skiatest::Reporter* reporter, const TestCase& test) {
+
+ const SkImageInfo nativeII = SkImageInfo::Make(kSize, kSize, test.fColorType, test.fAlphaType);
+ const SkImageInfo f32Unpremul = SkImageInfo::Make(kSize, kSize, kRGBA_F32_SkColorType,
+ kUnpremul_SkAlphaType);
+
+ // We had better not be able to render to prohibited colorTypes
+ if (!test.fCanMakeSurfaces) {
+ auto s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, nativeII);
+ REPORTER_ASSERT(reporter, !SkToBool(s));
+ }
+
+ if (!context->colorTypeSupportedAsImage(test.fColorType)) {
+ return;
+ }
+
+ SkAutoPixmapStorage nativeExpected;
+ nativeExpected.alloc(nativeII);
+ nativeExpected.erase(SkColors::kWhite);
+
+ for (bool fullInit : { false, true }) {
+ GrBackendTexture backendTex;
+
+ if (fullInit) {
+ backendTex = context->priv().createBackendTexture(&nativeExpected, 1,
+ GrRenderable::kNo,
+ GrProtected::kNo);
+ } else {
+ backendTex = context->createBackendTexture(kSize, kSize, test.fColorType,
+ SkColors::kWhite, GrMipMapped::kNo,
+ GrRenderable::kNo, GrProtected::kNo);
+ }
+ REPORTER_ASSERT(reporter, backendTex.isValid());
+
+ auto img = SkImage::MakeFromTexture(context, backendTex, kTopLeft_GrSurfaceOrigin,
+ test.fColorType, test.fAlphaType, nullptr);
+ REPORTER_ASSERT(reporter, SkToBool(img));
+
+ {
+ SkAutoPixmapStorage nativeActual;
+ nativeActual.alloc(nativeII);
+ nativeActual.erase(SkColors::kTransparent);
+
+ if (img->readPixels(nativeActual, 0, 0)) {
+ compare_pixmaps(reporter, nativeExpected, nativeActual,
+ test.fColorType, "SkImage::readPixels to native CT");
+ }
+
+ // SkSurface::readPixels with the same colorType as the source pixels round trips
+ // (when allowed)
+ if (context->colorTypeSupportedAsSurface(test.fColorType)) {
+ auto s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, nativeII);
+ REPORTER_ASSERT(reporter, SkToBool(s));
+
+ {
+ SkCanvas* c = s->getCanvas();
+ c->drawImage(img, 0, 0);
+ }
+
+ nativeActual.erase(SkColors::kTransparent);
+ REPORTER_ASSERT(reporter, s->readPixels(nativeActual, 0, 0));
+
+ compare_pixmaps(reporter, nativeExpected, nativeActual,
+ test.fColorType, "SkSurface::readPixels to native CT");
+ }
+ }
+
+ {
+ SkAutoPixmapStorage f32Expected;
+ f32Expected.alloc(f32Unpremul);
+ f32Expected.erase(get_opaque_white_expected_color(test.fComponents));
+
+ // read back to F32 if possible
+ {
+ SkAutoPixmapStorage f32Actual;
+ f32Actual.alloc(f32Unpremul);
+ f32Actual.erase(SkColors::kTransparent);
+ if (img->readPixels(f32Actual, 0, 0)) {
+ compare_pixmaps(reporter, f32Expected, f32Actual,
+ test.fColorType, "SkImage::readPixels to F32");
+ }
+ }
+
+ // drawing a native SkImage works appropriately (as assessed by reading back from an
+ // RGBA8 surface to an F32 pixmap)
+ {
+ const SkImageInfo rgba8888Premul = SkImageInfo::Make(kSize, kSize,
+ kRGBA_8888_SkColorType,
+ kPremul_SkAlphaType);
+
+ auto s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, rgba8888Premul);
+ REPORTER_ASSERT(reporter, SkToBool(s));
+
+ {
+ SkCanvas* c = s->getCanvas();
+ c->drawImage(img, 0, 0);
+ }
+
+ SkAutoPixmapStorage f32Actual;
+ f32Actual.alloc(f32Unpremul);
+ f32Actual.erase(SkColors::kTransparent);
+ REPORTER_ASSERT(reporter, s->readPixels(f32Actual, 0, 0));
+
+ compare_pixmaps(reporter, f32Expected, f32Actual,
+ test.fColorType, "SkSurface::drawn to RGBA8888");
+ }
+ }
+
+ img.reset();
+ context->flush();
+ context->deleteBackendTexture(backendTex);
+ }
+}
+
+DEF_TEST(ExtendedSkColorTypeTests_raster, reporter) {
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); ++i) {
+ raster_tests(reporter, gTests[i]);
+ }
+}
+
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ExtendedSkColorTypeTests_gpu, reporter, ctxInfo) {
+ GrContext* context = ctxInfo.grContext();
+
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); ++i) {
+ gpu_tests(context, reporter, gTests[i]);
+ }
+}
diff --git a/tests/MtlBackendAllocationTest.mm b/tests/MtlBackendAllocationTest.mm
index 3137e23..81803d6 100644
--- a/tests/MtlBackendAllocationTest.mm
+++ b/tests/MtlBackendAllocationTest.mm
@@ -63,7 +63,7 @@
{ GrColorType::kRGBA_F16_Clamped, MTLPixelFormatRGBA16Float, SkColors::kLtGray },
{ GrColorType::kRGBA_F16, MTLPixelFormatRGBA16Float, SkColors::kYellow },
- { GrColorType::kRG_88, MTLPixelFormatRG8Unorm, { 0.5f, 0.5f, 0, 0 } },
+ { GrColorType::kRG_88, MTLPixelFormatRG8Unorm, { 0.5f, 0.5f, 0, 1 } },
{ GrColorType::kAlpha_F16, MTLPixelFormatR16Float, { 1.0f, 0, 0, 0.5f } },
{ GrColorType::kR_16, MTLPixelFormatR16Unorm, SkColors::kRed },
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp
index 438f2ca..b1450a1 100644
--- a/tests/ReadPixelsTest.cpp
+++ b/tests/ReadPixelsTest.cpp
@@ -626,6 +626,7 @@
case kAlpha_8_SkColorType: return 8;
case kRGB_565_SkColorType: return 5;
case kARGB_4444_SkColorType: return 4;
+ case kRG_88_SkColorType: return 8;
case kRGBA_8888_SkColorType: return 8;
case kRGB_888x_SkColorType: return 8;
case kBGRA_8888_SkColorType: return 8;