aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dm/DMSrcSink.cpp3
-rw-r--r--include/gpu/GrTypes.h41
-rw-r--r--include/private/GrTypesPriv.h70
-rw-r--r--include/private/SkImageInfoPriv.h (renamed from src/core/SkImageInfoPriv.h)47
-rw-r--r--src/core/SkGpuBlurUtils.cpp8
-rw-r--r--src/core/SkImageInfo.cpp11
-rw-r--r--src/gpu/GrCaps.cpp1
-rw-r--r--src/gpu/GrContext.cpp65
-rw-r--r--src/gpu/GrSurfaceContext.cpp3
-rw-r--r--src/gpu/SkGr.cpp51
-rw-r--r--src/gpu/effects/GrDitherEffect.fp1
-rw-r--r--src/gpu/effects/GrDitherEffect.h1
-rw-r--r--src/gpu/gl/GrGLCaps.cpp90
-rw-r--r--src/gpu/gl/GrGLCaps.h4
-rw-r--r--src/gpu/gl/GrGLGpu.cpp3
-rw-r--r--src/gpu/gl/GrGLUtil.cpp7
-rw-r--r--src/gpu/gl/GrGLUtil.h5
-rw-r--r--src/gpu/mtl/GrMtlUtil.mm3
-rw-r--r--src/gpu/vk/GrVkCaps.cpp1
-rw-r--r--src/gpu/vk/GrVkUtil.cpp3
-rw-r--r--tests/GrSurfaceTest.cpp3
-rw-r--r--tests/PackedConfigsTextureTest.cpp4
-rw-r--r--tests/ReadPixelsTest.cpp182
-rw-r--r--tests/VkUploadPixelsTests.cpp8
-rw-r--r--tests/WritePixelsTest.cpp71
-rw-r--r--tools/flags/SkCommonFlagsConfig.cpp7
26 files changed, 471 insertions, 222 deletions
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 09c88af320..cd4f111627 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -1881,7 +1881,8 @@ Error GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log,
canvas->getGrContext()->contextPriv().dumpGpuStats(log);
#endif
}
- if (info.colorType() == kRGB_565_SkColorType || info.colorType() == kARGB_4444_SkColorType) {
+ if (info.colorType() == kRGB_565_SkColorType || info.colorType() == kARGB_4444_SkColorType ||
+ info.colorType() == kRGB_888x_SkColorType) {
// We don't currently support readbacks into these formats on the GPU backend. Convert to
// 32 bit.
info = SkImageInfo::Make(size.width(), size.height(), kRGBA_8888_SkColorType,
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index 3fec742907..979014cca4 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -286,58 +286,29 @@ static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) {
}
/**
- * Pixel configurations.
+ * Pixel configurations. This type conflates texture formats, CPU pixel formats, and
+ * premultipliedness. We are moving away from it towards SkColorType and backend API (GL, Vulkan)
+ * texture formats in the pulbic API. Right now this mostly refers to texture formats as we're
+ * migrating.
*/
enum GrPixelConfig {
kUnknown_GrPixelConfig,
kAlpha_8_GrPixelConfig,
kGray_8_GrPixelConfig,
kRGB_565_GrPixelConfig,
- /**
- * Premultiplied
- */
kRGBA_4444_GrPixelConfig,
- /**
- * Premultiplied. Byte order is r,g,b,a.
- */
kRGBA_8888_GrPixelConfig,
- /**
- * Premultiplied. Byte order is b,g,r,a.
- */
+ kRGB_888_GrPixelConfig,
kBGRA_8888_GrPixelConfig,
- /**
- * Premultiplied and sRGB. Byte order is r,g,b,a.
- */
kSRGBA_8888_GrPixelConfig,
- /**
- * Premultiplied and sRGB. Byte order is b,g,r,a.
- */
kSBGRA_8888_GrPixelConfig,
-
- /**
- * Premultiplied.
- */
kRGBA_1010102_GrPixelConfig,
-
- /**
- * Byte order is r, g, b, a. This color format is 32 bits per channel
- */
kRGBA_float_GrPixelConfig,
- /**
- * Byte order is r, g. This color format is 32 bits per channel
- */
kRG_float_GrPixelConfig,
-
- /**
- * This color format is a single 16 bit float channel
- */
kAlpha_half_GrPixelConfig,
-
- /**
- * Byte order is r, g, b, a. This color format is 16 bits per channel
- */
kRGBA_half_GrPixelConfig,
+ /** For internal usage. */
kPrivateConfig1_GrPixelConfig,
kPrivateConfig2_GrPixelConfig,
kPrivateConfig3_GrPixelConfig,
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 69c79ab042..74b2425c14 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -12,6 +12,8 @@
#include "GrSharedEnums.h"
#include "GrTypes.h"
#include "SkImageInfo.h"
+#include "SkImageInfoPriv.h"
+#include "SkRefCnt.h"
#include "SkWeakRefCnt.h"
class GrCaps;
@@ -814,6 +816,7 @@ static inline GrSRGBEncoded GrPixelConfigIsSRGBEncoded(GrPixelConfig config) {
case kGray_8_as_Red_GrPixelConfig:
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kRGBA_1010102_GrPixelConfig:
@@ -852,6 +855,7 @@ static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
case kGray_8_as_Red_GrPixelConfig:
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
case kRGBA_1010102_GrPixelConfig:
case kRGBA_float_GrPixelConfig:
case kRG_float_GrPixelConfig:
@@ -879,6 +883,7 @@ static inline size_t GrBytesPerPixel(GrPixelConfig config) {
case kAlpha_half_as_Red_GrPixelConfig:
return 2;
case kRGBA_8888_GrPixelConfig:
+ case kRGB_888_GrPixelConfig: // Assuming GPUs store this 4-byte aligned.
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
@@ -900,6 +905,7 @@ static inline size_t GrBytesPerPixel(GrPixelConfig config) {
static inline bool GrPixelConfigIsOpaque(GrPixelConfig config) {
switch (config) {
case kRGB_565_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
case kGray_8_GrPixelConfig:
case kGray_8_as_Lum_GrPixelConfig:
case kGray_8_as_Red_GrPixelConfig:
@@ -940,6 +946,7 @@ static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) {
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
@@ -971,6 +978,7 @@ static inline bool GrPixelConfigIsFloatingPoint(GrPixelConfig config) {
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
@@ -992,6 +1000,7 @@ static inline bool GrPixelConfigIsUnorm(GrPixelConfig config) {
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
@@ -1024,6 +1033,7 @@ static inline GrSLPrecision GrSLSamplerPrecision(GrPixelConfig config) {
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
@@ -1059,6 +1069,7 @@ enum class GrColorType {
kRGB_565,
kABGR_4444, // This name differs from SkColorType. kARGB_4444_SkColorType is misnamed.
kRGBA_8888,
+ kRGB_888x,
kBGRA_8888,
kRGBA_1010102,
kGray_8,
@@ -1075,6 +1086,7 @@ static inline SkColorType GrColorTypeToSkColorType(GrColorType ct) {
case GrColorType::kRGB_565: return kRGB_565_SkColorType;
case GrColorType::kABGR_4444: return kARGB_4444_SkColorType;
case GrColorType::kRGBA_8888: return kRGBA_8888_SkColorType;
+ case GrColorType::kRGB_888x: return kRGB_888x_SkColorType;
case GrColorType::kBGRA_8888: return kBGRA_8888_SkColorType;
case GrColorType::kRGBA_1010102: return kRGBA_1010102_SkColorType;
case GrColorType::kGray_8: return kGray_8_SkColorType;
@@ -1094,8 +1106,8 @@ static inline GrColorType SkColorTypeToGrColorType(SkColorType ct) {
case kRGB_565_SkColorType: return GrColorType::kRGB_565;
case kARGB_4444_SkColorType: return GrColorType::kABGR_4444;
case kRGBA_8888_SkColorType: return GrColorType::kRGBA_8888;
+ case kRGB_888x_SkColorType: return GrColorType::kRGB_888x;
case kBGRA_8888_SkColorType: return GrColorType::kBGRA_8888;
- case kRGB_888x_SkColorType: return GrColorType::kUnknown;
case kGray_8_SkColorType: return GrColorType::kGray_8;
case kRGBA_F16_SkColorType: return GrColorType::kRGBA_F16;
case kRGBA_1010102_SkColorType: return GrColorType::kRGBA_1010102;
@@ -1105,6 +1117,35 @@ static inline GrColorType SkColorTypeToGrColorType(SkColorType ct) {
return GrColorType::kUnknown;
}
+static inline uint32_t GrColorTypeComponentFlags(GrColorType ct) {
+ switch (ct) {
+ case GrColorType::kUnknown: return 0;
+ case GrColorType::kAlpha_8: return kAlpha_SkColorTypeComponentFlag;
+ case GrColorType::kRGB_565: return kRGB_SkColorTypeComponentFlags;
+ case GrColorType::kABGR_4444: return kRGBA_SkColorTypeComponentFlags;
+ case GrColorType::kRGBA_8888: return kRGBA_SkColorTypeComponentFlags;
+ case GrColorType::kRGB_888x: return kRGB_SkColorTypeComponentFlags;
+ case GrColorType::kBGRA_8888: return kRGBA_SkColorTypeComponentFlags;
+ case GrColorType::kRGBA_1010102: return kRGBA_SkColorTypeComponentFlags;
+ case GrColorType::kGray_8: return kGray_SkColorTypeComponentFlag;
+ case GrColorType::kAlpha_F16: return kAlpha_SkColorTypeComponentFlag;
+ case GrColorType::kRGBA_F16: return kRGBA_SkColorTypeComponentFlags;
+ case GrColorType::kRG_F32: return kRed_SkColorTypeComponentFlag |
+ kGreen_SkColorTypeComponentFlag;
+ case GrColorType::kRGBA_F32: return kRGBA_SkColorTypeComponentFlags;
+ }
+ SK_ABORT("Invalid GrColorType");
+ return kUnknown_SkColorType;
+}
+
+static inline bool GrColorTypeIsAlphaOnly(GrColorType ct) {
+ return kAlpha_SkColorTypeComponentFlag == GrColorTypeComponentFlags(ct);
+}
+
+static inline bool GrColorTypeHasAlpha(GrColorType ct) {
+ return kAlpha_SkColorTypeComponentFlag & GrColorTypeComponentFlags(ct);
+}
+
static inline int GrColorTypeBytesPerPixel(GrColorType ct) {
switch (ct) {
case GrColorType::kUnknown: return 0;
@@ -1112,6 +1153,7 @@ static inline int GrColorTypeBytesPerPixel(GrColorType ct) {
case GrColorType::kRGB_565: return 2;
case GrColorType::kABGR_4444: return 2;
case GrColorType::kRGBA_8888: return 4;
+ case GrColorType::kRGB_888x: return 4;
case GrColorType::kBGRA_8888: return 4;
case GrColorType::kRGBA_1010102: return 4;
case GrColorType::kGray_8: return 1;
@@ -1124,25 +1166,6 @@ static inline int GrColorTypeBytesPerPixel(GrColorType ct) {
return 0;
}
-static inline int GrColorTypeIsAlphaOnly(GrColorType ct) {
- switch (ct) {
- case GrColorType::kUnknown: return false;
- case GrColorType::kAlpha_8: return true;
- case GrColorType::kRGB_565: return false;
- case GrColorType::kABGR_4444: return false;
- case GrColorType::kRGBA_8888: return false;
- case GrColorType::kBGRA_8888: return false;
- case GrColorType::kRGBA_1010102: return false;
- case GrColorType::kGray_8: return false;
- case GrColorType::kAlpha_F16: return true;
- case GrColorType::kRGBA_F16: return false;
- case GrColorType::kRG_F32: return false;
- case GrColorType::kRGBA_F32: return false;
- }
- SK_ABORT("Invalid GrColorType");
- return false;
-}
-
static inline GrColorType GrPixelConfigToColorTypeAndEncoding(GrPixelConfig config,
GrSRGBEncoded* srgbEncoded) {
SkASSERT(srgbEncoded);
@@ -1164,6 +1187,9 @@ static inline GrColorType GrPixelConfigToColorTypeAndEncoding(GrPixelConfig conf
case kRGBA_8888_GrPixelConfig:
*srgbEncoded = GrSRGBEncoded::kNo;
return GrColorType::kRGBA_8888;
+ case kRGB_888_GrPixelConfig:
+ *srgbEncoded = GrSRGBEncoded::kNo;
+ return GrColorType::kRGB_888x;
case kBGRA_8888_GrPixelConfig:
*srgbEncoded = GrSRGBEncoded::kNo;
return GrColorType::kBGRA_8888;
@@ -1238,6 +1264,10 @@ static inline GrPixelConfig GrColorTypeToPixelConfig(GrColorType config,
return (GrSRGBEncoded::kYes == srgbEncoded) ? kSRGBA_8888_GrPixelConfig
: kRGBA_8888_GrPixelConfig;
+ case GrColorType::kRGB_888x:
+ return (GrSRGBEncoded::kYes == srgbEncoded) ? kUnknown_GrPixelConfig
+ : kRGB_888_GrPixelConfig;
+
case GrColorType::kBGRA_8888:
return (GrSRGBEncoded::kYes == srgbEncoded) ? kSBGRA_8888_GrPixelConfig
: kBGRA_8888_GrPixelConfig;
diff --git a/src/core/SkImageInfoPriv.h b/include/private/SkImageInfoPriv.h
index 04779ff3fb..597906af29 100644
--- a/src/core/SkImageInfoPriv.h
+++ b/include/private/SkImageInfoPriv.h
@@ -15,10 +15,51 @@ enum class SkDestinationSurfaceColorMode {
kGammaAndColorSpaceAware,
};
+enum SkColorTypeComponentFlag {
+ kRed_SkColorTypeComponentFlag = 0x1,
+ kGreen_SkColorTypeComponentFlag = 0x2,
+ kBlue_SkColorTypeComponentFlag = 0x4,
+ kAlpha_SkColorTypeComponentFlag = 0x8,
+ kGray_SkColorTypeComponentFlag = 0x10,
+ kRGB_SkColorTypeComponentFlags = kRed_SkColorTypeComponentFlag |
+ kGreen_SkColorTypeComponentFlag |
+ kBlue_SkColorTypeComponentFlag,
+ kRGBA_SkColorTypeComponentFlags = kRGB_SkColorTypeComponentFlags |
+ kAlpha_SkColorTypeComponentFlag,
+};
+
+static inline uint32_t SkColorTypeComponentFlags(SkColorType ct) {
+ switch (ct) {
+ case kUnknown_SkColorType: return 0;
+ case kAlpha_8_SkColorType: return kAlpha_SkColorTypeComponentFlag;
+ case kRGB_565_SkColorType: return kRGB_SkColorTypeComponentFlags;
+ case kARGB_4444_SkColorType: return kRGBA_SkColorTypeComponentFlags;
+ case kRGBA_8888_SkColorType: return kRGBA_SkColorTypeComponentFlags;
+ case kRGB_888x_SkColorType: return kRGB_SkColorTypeComponentFlags;
+ case kBGRA_8888_SkColorType: return kRGBA_SkColorTypeComponentFlags;
+ case kRGBA_1010102_SkColorType: return kRGBA_SkColorTypeComponentFlags;
+ case kRGB_101010x_SkColorType: return kRGB_SkColorTypeComponentFlags;
+ case kGray_8_SkColorType: return kGray_SkColorTypeComponentFlag;
+ case kRGBA_F16_SkColorType: return kRGBA_SkColorTypeComponentFlags;
+ }
+ return 0;
+}
+
+static inline bool SkColorTypeIsAlphaOnly(SkColorType ct) {
+ return kAlpha_SkColorTypeComponentFlag == SkColorTypeComponentFlags(ct);
+}
+
static inline bool SkAlphaTypeIsValid(unsigned value) {
return value <= kLastEnum_SkAlphaType;
}
+static inline bool SkColorTypeIsGray(SkColorType ct) {
+ auto flags = SkColorTypeComponentFlags(ct);
+ // Currently assuming that a color type has only gray or does not have gray.
+ SkASSERT(!(kGray_SkColorTypeComponentFlag & flags) || kGray_SkColorTypeComponentFlag == flags);
+ return kGray_SkColorTypeComponentFlag == flags;
+}
+
static int SkColorTypeShiftPerPixel(SkColorType ct) {
switch (ct) {
case kUnknown_SkColorType: return 0;
@@ -152,8 +193,8 @@ static inline bool SkImageInfoValidConversion(const SkImageInfo& dst, const SkIm
return false;
}
- if (kGray_8_SkColorType == dst.colorType()) {
- if (kGray_8_SkColorType != src.colorType()) {
+ if (SkColorTypeIsGray(dst.colorType())) {
+ if (!SkColorTypeIsGray(src.colorType())) {
return false;
}
@@ -162,7 +203,7 @@ static inline bool SkImageInfoValidConversion(const SkImageInfo& dst, const SkIm
}
}
- if (kAlpha_8_SkColorType != dst.colorType() && kAlpha_8_SkColorType == src.colorType()) {
+ if (!SkColorTypeIsAlphaOnly(dst.colorType()) && SkColorTypeIsAlphaOnly(src.colorType())) {
return false;
}
diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp
index b42bb04782..fe614bd0df 100644
--- a/src/core/SkGpuBlurUtils.cpp
+++ b/src/core/SkGpuBlurUtils.cpp
@@ -233,10 +233,10 @@ sk_sp<GrRenderTargetContext> GaussianBlur(GrContext* context,
}
SkASSERT(kBGRA_8888_GrPixelConfig == config || kRGBA_8888_GrPixelConfig == config ||
- kRGBA_4444_GrPixelConfig == config || kRGB_565_GrPixelConfig == config ||
- kSRGBA_8888_GrPixelConfig == config || kSBGRA_8888_GrPixelConfig == config ||
- kRGBA_half_GrPixelConfig == config || kAlpha_8_GrPixelConfig == config ||
- kRGBA_1010102_GrPixelConfig == config);
+ kRGB_888_GrPixelConfig == config || kRGBA_4444_GrPixelConfig == config ||
+ kRGB_565_GrPixelConfig == config || kSRGBA_8888_GrPixelConfig == config ||
+ kSBGRA_8888_GrPixelConfig == config || kRGBA_half_GrPixelConfig == config ||
+ kAlpha_8_GrPixelConfig == config || kRGBA_1010102_GrPixelConfig == config);
const int width = dstBounds.width();
const int height = dstBounds.height();
diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp
index f9933736e3..fd5e8087ba 100644
--- a/src/core/SkImageInfo.cpp
+++ b/src/core/SkImageInfo.cpp
@@ -45,16 +45,7 @@ enum Stored_SkColorType {
};
bool SkColorTypeIsAlwaysOpaque(SkColorType ct) {
- switch (ct) {
- case kRGB_565_SkColorType:
- case kRGB_888x_SkColorType:
- case kRGB_101010x_SkColorType:
- case kGray_8_SkColorType:
- return true;
- default:
- break;
- }
- return false;
+ return !(kAlpha_SkColorTypeComponentFlag & SkColorTypeComponentFlags(ct));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 1d25c1a791..0507a3fdfb 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -24,6 +24,7 @@ static const char* pixel_config_name(GrPixelConfig config) {
case kRGB_565_GrPixelConfig: return "RGB565";
case kRGBA_4444_GrPixelConfig: return "RGBA444";
case kRGBA_8888_GrPixelConfig: return "RGBA8888";
+ case kRGB_888_GrPixelConfig: return "RGB888";
case kBGRA_8888_GrPixelConfig: return "BGRA8888";
case kSRGBA_8888_GrPixelConfig: return "SRGBA8888";
case kSBGRA_8888_GrPixelConfig: return "SBGRA8888";
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 626b3f6ecd..3baf0b9737 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -358,6 +358,7 @@ static bool valid_premul_config(GrPixelConfig config) {
case kRGB_565_GrPixelConfig: return false;
case kRGBA_4444_GrPixelConfig: return true;
case kRGBA_8888_GrPixelConfig: return true;
+ case kRGB_888_GrPixelConfig: return false;
case kBGRA_8888_GrPixelConfig: return true;
case kSRGBA_8888_GrPixelConfig: return true;
case kSBGRA_8888_GrPixelConfig: return true;
@@ -383,6 +384,7 @@ static bool valid_premul_color_type(GrColorType ct) {
case GrColorType::kRGB_565: return false;
case GrColorType::kABGR_4444: return true;
case GrColorType::kRGBA_8888: return true;
+ case GrColorType::kRGB_888x: return false;
case GrColorType::kBGRA_8888: return true;
case GrColorType::kRGBA_1010102: return true;
case GrColorType::kGray_8: return false;
@@ -402,7 +404,6 @@ static bool valid_pixel_conversion(GrColorType cpuColorType, GrPixelConfig gpuCo
(!valid_premul_color_type(cpuColorType) || !valid_premul_config(gpuConfig))) {
return false;
}
-
return true;
}
@@ -471,10 +472,20 @@ bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst, int left, int top,
int height, GrColorType srcColorType,
SkColorSpace* srcColorSpace, const void* buffer,
size_t rowBytes, uint32_t pixelOpsFlags) {
-#ifndef SK_LEGACY_GPU_PIXEL_OPS
- return this->writeSurfacePixels2(dst, left, top, width, height, srcColorType, srcColorSpace,
- buffer, rowBytes, pixelOpsFlags);
+ bool useLegacyPath = false;
+#ifdef SK_LEGACY_GPU_PIXEL_OPS
+ useLegacyPath = true;
#endif
+ // Newly added color types/configs are only supported by the new code path.
+ if (srcColorType == GrColorType::kRGB_888x ||
+ dst->asSurfaceProxy()->config() == kRGB_888_GrPixelConfig) {
+ useLegacyPath = false;
+ }
+
+ if (!useLegacyPath) {
+ return this->writeSurfacePixels2(dst, left, top, width, height, srcColorType, srcColorSpace,
+ buffer, rowBytes, pixelOpsFlags);
+ }
// TODO: Color space conversion
@@ -497,6 +508,14 @@ bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst, int left, int top,
if (!valid_pixel_conversion(srcColorType, dstProxy->config(), premul)) {
return false;
}
+ // There is no way to store alpha values in the dst.
+ if (GrColorTypeHasAlpha(srcColorType) && GrPixelConfigIsOpaque(dstProxy->config())) {
+ return false;
+ }
+ // The source has no alpha value and the dst is only alpha
+ if (!GrColorTypeHasAlpha(srcColorType) && GrPixelConfigIsAlphaOnly(dstProxy->config())) {
+ return false;
+ }
// We need to guarantee round-trip conversion if we are reading and writing 8888 non-sRGB data,
// without any color spaces attached, and the caller wants us to premul.
@@ -612,10 +631,21 @@ bool GrContextPriv::readSurfacePixels(GrSurfaceContext* src, int left, int top,
int height, GrColorType dstColorType,
SkColorSpace* dstColorSpace, void* buffer, size_t rowBytes,
uint32_t flags) {
-#ifndef SK_LEGACY_GPU_PIXEL_OPS
- return this->readSurfacePixels2(src, left, top, width, height, dstColorType, dstColorSpace,
- buffer, rowBytes, flags);
+ bool useLegacyPath = false;
+#ifdef SK_LEGACY_GPU_PIXEL_OPS
+ useLegacyPath = true;
#endif
+ // Newly added color types/configs are only supported by the new code path.
+ if (dstColorType == GrColorType::kRGB_888x ||
+ src->asSurfaceProxy()->config() == kRGB_888_GrPixelConfig) {
+ useLegacyPath = false;
+ }
+
+ if (!useLegacyPath) {
+ return this->readSurfacePixels2(src, left, top, width, height, dstColorType, dstColorSpace,
+ buffer, rowBytes, flags);
+ }
+
// TODO: Color space conversion
ASSERT_SINGLE_OWNER_PRIV
@@ -642,6 +672,18 @@ bool GrContextPriv::readSurfacePixels(GrSurfaceContext* src, int left, int top,
if (!valid_pixel_conversion(dstColorType, srcProxy->config(), unpremul)) {
return false;
}
+ // The source is alpha-only but the dst is not. TODO: Make non-alpha channels in the dst be 0?
+ if (GrPixelConfigIsAlphaOnly(srcProxy->config()) && !GrColorTypeIsAlphaOnly(dstColorType)) {
+ return false;
+ }
+ // The source has no alpha, the dst is alpha-only. TODO: set all values in dst to 1?
+ if (GrPixelConfigIsOpaque(srcProxy->config()) && GrColorTypeIsAlphaOnly(dstColorType)) {
+ return false;
+ }
+ // Not clear if we should unpremul in this case.
+ if (!GrPixelConfigIsOpaque(srcProxy->config()) && !GrColorTypeHasAlpha(dstColorType)) {
+ return false;
+ }
// We need to guarantee round-trip conversion if we are reading and writing 8888 non-sRGB data,
// without any color spaces attached, and the caller wants us to unpremul.
@@ -913,10 +955,6 @@ bool GrContextPriv::readSurfacePixels2(GrSurfaceContext* src, int left, int top,
int height, GrColorType dstColorType,
SkColorSpace* dstColorSpace, void* buffer, size_t rowBytes,
uint32_t flags) {
- SkASSERT(!(flags & kDontFlush_PixelOpsFlag));
- if (flags & kDontFlush_PixelOpsFlag){
- return false;
- }
ASSERT_SINGLE_OWNER_PRIV
RETURN_FALSE_IF_ABANDONED_PRIV
SkASSERT(src);
@@ -924,6 +962,11 @@ bool GrContextPriv::readSurfacePixels2(GrSurfaceContext* src, int left, int top,
ASSERT_OWNED_PROXY_PRIV(src->asSurfaceProxy());
GR_CREATE_TRACE_MARKER_CONTEXT("GrContextPriv", "readSurfacePixels2", fContext);
+ SkASSERT(!(flags & kDontFlush_PixelOpsFlag));
+ if (flags & kDontFlush_PixelOpsFlag) {
+ return false;
+ }
+
// MDB TODO: delay this instantiation until later in the method
if (!src->asSurfaceProxy()->instantiate(this->resourceProvider())) {
return false;
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index ab6c05a375..37d0b71fb0 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -49,7 +49,8 @@ bool GrSurfaceContext::readPixels(const SkImageInfo& dstInfo, void* dstBuffer,
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrSurfaceContext::readPixels");
// TODO: this seems to duplicate code in SkImage_Gpu::onReadPixels
- if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
+ if (kUnpremul_SkAlphaType == dstInfo.alphaType() &&
+ !GrPixelConfigIsOpaque(this->asSurfaceProxy()->config())) {
flags |= GrContextPriv::kUnpremul_PixelOpsFlag;
}
auto colorType = SkColorTypeToGrColorType(dstInfo.colorType());
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 27c9b39f5e..09155a05b3 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -264,7 +264,7 @@ GrPixelConfig SkImageInfo2GrPixelConfig(const SkColorType type, SkColorSpace* cs
// TODO: We're checking for srgbSupport, but we can then end up picking sBGRA as our pixel
// config (which may not be supported). We need a better test here.
case kRGB_888x_SkColorType:
- return kUnknown_GrPixelConfig;
+ return kRGB_888_GrPixelConfig;
case kBGRA_8888_SkColorType:
return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
? kSBGRA_8888_GrPixelConfig : kBGRA_8888_GrPixelConfig;
@@ -286,49 +286,14 @@ GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& c
}
bool GrPixelConfigToColorType(GrPixelConfig config, SkColorType* ctOut) {
- SkColorType ct;
- switch (config) {
- case kAlpha_8_GrPixelConfig: // fall through
- case kAlpha_8_as_Alpha_GrPixelConfig: // fall through
- case kAlpha_8_as_Red_GrPixelConfig:
- ct = kAlpha_8_SkColorType;
- break;
- case kGray_8_GrPixelConfig: // fall through
- case kGray_8_as_Lum_GrPixelConfig: // fall through
- case kGray_8_as_Red_GrPixelConfig:
- ct = kGray_8_SkColorType;
- break;
- case kRGB_565_GrPixelConfig:
- ct = kRGB_565_SkColorType;
- break;
- case kRGBA_4444_GrPixelConfig:
- ct = kARGB_4444_SkColorType;
- break;
- case kRGBA_8888_GrPixelConfig:
- ct = kRGBA_8888_SkColorType;
- break;
- case kBGRA_8888_GrPixelConfig:
- ct = kBGRA_8888_SkColorType;
- break;
- case kSRGBA_8888_GrPixelConfig:
- ct = kRGBA_8888_SkColorType;
- break;
- case kSBGRA_8888_GrPixelConfig:
- ct = kBGRA_8888_SkColorType;
- break;
- case kRGBA_1010102_GrPixelConfig:
- ct = kRGBA_1010102_SkColorType;
- break;
- case kRGBA_half_GrPixelConfig:
- ct = kRGBA_F16_SkColorType;
- break;
- default:
- return false;
- }
- if (ctOut) {
- *ctOut = ct;
+ SkColorType ct = GrColorTypeToSkColorType(GrPixelConfigToColorType(config));
+ if (kUnknown_SkColorType != ct) {
+ if (ctOut) {
+ *ctOut = ct;
+ }
+ return true;
}
- return true;
+ return false;
}
GrPixelConfig GrRenderableConfigForColorSpace(const SkColorSpace* colorSpace) {
diff --git a/src/gpu/effects/GrDitherEffect.fp b/src/gpu/effects/GrDitherEffect.fp
index 7cf07da311..c51865e38b 100644
--- a/src/gpu/effects/GrDitherEffect.fp
+++ b/src/gpu/effects/GrDitherEffect.fp
@@ -16,6 +16,7 @@ layout(key) in int rangeType;
case kGray_8_as_Lum_GrPixelConfig:
case kGray_8_as_Red_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
diff --git a/src/gpu/effects/GrDitherEffect.h b/src/gpu/effects/GrDitherEffect.h
index 2e650a68f4..d1bc72bf4e 100644
--- a/src/gpu/effects/GrDitherEffect.h
+++ b/src/gpu/effects/GrDitherEffect.h
@@ -25,6 +25,7 @@ public:
case kGray_8_as_Lum_GrPixelConfig:
case kGray_8_as_Red_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index e05a4bb970..9af54b1dec 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -1167,8 +1167,8 @@ void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
writer->appendHexU32("flags", fConfigTable[i].fFlags);
writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
- writer->appendHexU32("e_format",
- fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage]);
+ writer->appendHexU32("e_format_read_pixels",
+ fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage]);
writer->appendHexU32(
"e_format_teximage",
fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
@@ -1200,7 +1200,7 @@ bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig ext
bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
GrGLenum* externalFormat, GrGLenum* externalType) const {
- if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
+ if (!this->getExternalFormat(surfaceConfig, externalConfig, kReadPixels_ExternalFormatUsage,
externalFormat, externalType)) {
return false;
}
@@ -1322,6 +1322,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
bool disableSRGBWriteControlForAdreno4xx = false;
bool disableR8TexStorageForANGLEGL = false;
bool disableSRGBRenderWithMSAAForMacAMD = false;
+ bool disableRGB8ForMali400 = false;
if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
// ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
@@ -1348,6 +1349,8 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
#if defined(SK_BUILD_FOR_MAC)
disableSRGBRenderWithMSAAForMacAMD = kATI_GrGLVendor == ctxInfo.vendor();
#endif
+ // Mali-400 fails ReadPixels tests, mostly with non-0xFF alpha values when read as GL_RGBA8.
+ disableRGB8ForMali400 = kMali4xx_GrGLRenderer == ctxInfo.renderer();
}
uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
@@ -1386,14 +1389,14 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
- fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
+ fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = 0;
fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
- fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+ fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
GR_GL_RGBA;
fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
@@ -1415,7 +1418,41 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
}
fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
- fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+ fConfigTable[kRGB_888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
+ fConfigTable[kRGB_888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB8;
+ // Our external RGB data always has a byte where alpha would be. When calling read pixels we
+ // want to read to kRGB_888x color type and ensure that gets 0xFF written. Using GL_RGB would
+ // read back unaligned 24bit RGB color values. Note that this all a bit moot as we don't
+ // currently expect to ever read back GrColorType::kRGB_888x because our implementation of
+ // supportedReadPixelsColorType never returns it.
+ fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RGBA;
+ fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
+ fConfigTable[kRGB_888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
+ fConfigTable[kRGB_888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
+ if (kGL_GrGLStandard == standard) {
+ // Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be a
+ // supported render buffer format. Since we usually use render buffers for MSAA on non-ES GL
+ // we don't support MSAA for GL_RGB8. On 4.2+ we could check using
+ // glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if this
+ // becomes an issue.
+ // This also would probably work in mixed-samples mode where there is no MSAA color buffer
+ // but we don't support that just for simplicity's sake.
+ fConfigTable[kRGB_888_GrPixelConfig].fFlags |= nonMSAARenderFlags;
+ } else {
+ // 3.0 and the extension support this as a render buffer format.
+ if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
+ fConfigTable[kRGB_888_GrPixelConfig].fFlags |= allRenderFlags;
+ }
+ }
+ if (texStorageSupported) {
+ fConfigTable[kRGB_888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
+ }
+ fConfigTable[kRGB_888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
+ if (disableRGB8ForMali400) {
+ fConfigTable[kRGB_888_GrPixelConfig].fFlags = 0;
+ }
+
+ fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
GR_GL_BGRA;
fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
@@ -1527,7 +1564,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
// GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
// external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
- fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+ fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
GR_GL_RGBA;
fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
@@ -1547,7 +1584,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
// GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
// external format is GL_BGRA.
- fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+ fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
GR_GL_BGRA;
fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
@@ -1567,7 +1604,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
} else {
fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
}
- fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+ fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
GR_GL_RGB;
fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
@@ -1593,7 +1630,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
- fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+ fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
GR_GL_RGBA;
fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
@@ -1612,7 +1649,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB10_A2;
- fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+ fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
GR_GL_RGBA;
fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalType =
GR_GL_UNSIGNED_INT_2_10_10_10_REV;
@@ -1640,7 +1677,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
}
alphaInfo.fFormats.fBaseInternalFormat = GR_GL_ALPHA;
alphaInfo.fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
- alphaInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_ALPHA;
+ alphaInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_ALPHA;
alphaInfo.fSwizzle = GrSwizzle::AAAA();
if (fAlpha8IsRenderable && alpha8IsValidForGL) {
alphaInfo.fFlags |= allRenderFlags;
@@ -1651,7 +1688,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
redInfo.fFormatType = kNormalizedFixedPoint_FormatType;
redInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
redInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
- redInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED;
+ redInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
redInfo.fSwizzle = GrSwizzle::RRRR();
// ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
@@ -1680,7 +1717,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
grayLumInfo.fFormatType = kNormalizedFixedPoint_FormatType;
grayLumInfo.fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
grayLumInfo.fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
- grayLumInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_LUMINANCE;
+ grayLumInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_LUMINANCE;
grayLumInfo.fSwizzle = GrSwizzle::RGBA();
if ((standard == kGL_GrGLStandard && version <= GR_GL_VER(3, 0)) ||
(standard == kGLES_GrGLStandard && version < GR_GL_VER(3, 0))) {
@@ -1692,7 +1729,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
grayRedInfo.fFormatType = kNormalizedFixedPoint_FormatType;
grayRedInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
grayRedInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
- grayRedInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED;
+ grayRedInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
grayRedInfo.fSwizzle = GrSwizzle::RRRA();
grayRedInfo.fFlags = ConfigInfo::kTextureable_Flag;
@@ -1762,7 +1799,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
- fConfigTable[fpconfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = format;
+ fConfigTable[fpconfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = format;
fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
if (hasFPTextures) {
@@ -1794,7 +1831,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
redHalf.fFormatType = kFloat_FormatType;
redHalf.fFormats.fBaseInternalFormat = GR_GL_RED;
redHalf.fFormats.fSizedInternalFormat = GR_GL_R16F;
- redHalf.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED;
+ redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
redHalf.fSwizzle = GrSwizzle::RRRR();
if (textureRedSupport && hasHalfFPTextures) {
redHalf.fFlags = ConfigInfo::kTextureable_Flag;
@@ -1816,7 +1853,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
- fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+ fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
GR_GL_RGBA;
if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
@@ -1850,10 +1887,10 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
for (int i = 0; i < kGrPixelConfigCnt; ++i) {
- // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
- // param to glTex[Sub]Image.
+ // Almost always we want to pass fExternalFormat[kReadPixels_ExternalFormatUsage] as the
+ // <format> param to glTex[Sub]Image.
fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
- fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
+ fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage];
fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
fConfigTable[i].fFormats.fSizedInternalFormat :
fConfigTable[i].fFormats.fBaseInternalFormat;
@@ -1888,6 +1925,12 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
// unsupported. (If we have no sRGB support at all, this will get overwritten below).
fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
}
+ // On ES 2.0 we have to use GL_RGB with glTexImage as the internal/external formats must
+ // be the same. Moreover, if we write kRGB_888x data to a texture format on non-ES2 we want to
+ // be sure that we write 1 for alpha not whatever happens to be in the client provided the 'x'
+ // slot.
+ fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
+ GR_GL_RGB;
// If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
// as a base format.
@@ -2561,7 +2604,10 @@ bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* confi
}
break;
case kRGB_888x_SkColorType:
- return false;
+ if (GR_GL_RGB8 == format) {
+ *config = kRGB_888_GrPixelConfig;
+ }
+ break;
case kBGRA_8888_SkColorType:
if (GR_GL_RGBA8 == format) {
if (kGL_GrGLStandard == standard) {
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index eed3ab3a17..19d443cc1c 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -419,9 +419,9 @@ public:
private:
enum ExternalFormatUsage {
kTexImage_ExternalFormatUsage,
- kOther_ExternalFormatUsage,
+ kReadPixels_ExternalFormatUsage,
- kLast_ExternalFormatUsage = kOther_ExternalFormatUsage
+ kLast_ExternalFormatUsage = kReadPixels_ExternalFormatUsage
};
static const int kExternalFormatUsageCnt = kLast_ExternalFormatUsage + 1;
bool getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index ce81adf95f..c6e2d2537f 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -776,7 +776,7 @@ bool GrGLGpu::onWritePixels(GrSurface* surface, GrSurfaceOrigin origin, int left
srcAsConfig, texels, mipLevelCount);
}
-// For GL_[UN]PACK_ALIGNMENT.
+// For GL_[UN]PACK_ALIGNMENT. TODO: This really wants to be GrColorType.
static inline GrGLint config_alignment(GrPixelConfig config) {
switch (config) {
case kAlpha_8_GrPixelConfig:
@@ -793,6 +793,7 @@ static inline GrGLint config_alignment(GrPixelConfig config) {
case kRGBA_half_GrPixelConfig:
return 2;
case kRGBA_8888_GrPixelConfig:
+ case kRGB_888_GrPixelConfig: // We're really talking about GrColorType::kRGB_888x here.
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 6b44402c1b..3de894db82 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -380,6 +380,11 @@ GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
return kMaliT_GrGLRenderer;
}
+ int mali400Num;
+ if (1 == sscanf(rendererString, "Mali-%d", &mali400Num) && mali400Num >= 400 &&
+ mali400Num < 500) {
+ return kMali4xx_GrGLRenderer;
+ }
if (is_renderer_angle(rendererString)) {
return kANGLE_GrGLRenderer;
}
@@ -494,6 +499,8 @@ GrPixelConfig GrGLSizedFormatToPixelConfig(GrGLenum sizedFormat) {
return kAlpha_8_as_Alpha_GrPixelConfig;
case GR_GL_RGBA8:
return kRGBA_8888_GrPixelConfig;
+ case GR_GL_RGB8:
+ return kRGB_888_GrPixelConfig;
case GR_GL_BGRA8:
return kBGRA_8888_GrPixelConfig;
case GR_GL_SRGB8_ALPHA8:
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 9905d75ef1..416538a749 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -60,12 +60,13 @@ enum GrGLRenderer {
/** Either HD 6xxx or Iris 6xxx */
kIntel6xxx_GrGLRenderer,
kGalliumLLVM_GrGLRenderer,
+ kMali4xx_GrGLRenderer,
/** T-6xx, T-7xx, or T-8xx */
kMaliT_GrGLRenderer,
kANGLE_GrGLRenderer,
- kAMDRadeonHD7xxx_GrGLRenderer, // AMD Radeon HD 7000 Series
- kAMDRadeonR9M4xx_GrGLRenderer, // AMD Radeon R9 M400 Series
+ kAMDRadeonHD7xxx_GrGLRenderer, // AMD Radeon HD 7000 Series
+ kAMDRadeonR9M4xx_GrGLRenderer, // AMD Radeon R9 M400 Series
kOther_GrGLRenderer
};
diff --git a/src/gpu/mtl/GrMtlUtil.mm b/src/gpu/mtl/GrMtlUtil.mm
index 383cc98264..e8a736c8f1 100644
--- a/src/gpu/mtl/GrMtlUtil.mm
+++ b/src/gpu/mtl/GrMtlUtil.mm
@@ -21,6 +21,9 @@ bool GrPixelConfigToMTLFormat(GrPixelConfig config, MTLPixelFormat* format) {
case kRGBA_8888_GrPixelConfig:
*format = MTLPixelFormatRGBA8Unorm;
return true;
+ case kRGB_888_GrPixelConfig:
+ // TODO: MTLPixelFormatRGB8Unorm
+ return false;
case kBGRA_8888_GrPixelConfig:
*format = MTLPixelFormatBGRA8Unorm;
return true;
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 0d75cbc56e..83546da5c4 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -466,6 +466,7 @@ bool validate_image_info(VkFormat format, SkColorType ct, GrPixelConfig* config)
}
break;
case kRGB_888x_SkColorType:
+ // TODO: VK_FORMAT_R8G8B8_UNORM
return false;
case kBGRA_8888_SkColorType:
if (VK_FORMAT_B8G8R8A8_UNORM == format) {
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index 4f0acdb8f4..e61d7bca17 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -22,6 +22,9 @@ bool GrPixelConfigToVkFormat(GrPixelConfig config, VkFormat* format) {
case kRGBA_8888_GrPixelConfig:
*format = VK_FORMAT_R8G8B8A8_UNORM;
return true;
+ case kRGB_888_GrPixelConfig:
+ // TODO: VK_FORMAT_R8G8B8_UNORM
+ return false;
case kBGRA_8888_GrPixelConfig:
*format = VK_FORMAT_B8G8R8A8_UNORM;
return true;
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index a7c688d361..c56b1eabbb 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -87,6 +87,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(GrSurfaceRenderability, reporter, ctxInfo) {
kRGB_565_GrPixelConfig,
kRGBA_4444_GrPixelConfig,
kRGBA_8888_GrPixelConfig,
+ kRGB_888_GrPixelConfig,
kBGRA_8888_GrPixelConfig,
kSRGBA_8888_GrPixelConfig,
kSBGRA_8888_GrPixelConfig,
@@ -97,7 +98,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(GrSurfaceRenderability, reporter, ctxInfo) {
kAlpha_half_as_Red_GrPixelConfig,
kRGBA_half_GrPixelConfig,
};
- SkASSERT(kGrPixelConfigCnt == SK_ARRAY_COUNT(configs));
+ GR_STATIC_ASSERT(kGrPixelConfigCnt == SK_ARRAY_COUNT(configs));
GrSurfaceDesc desc;
desc.fWidth = 64;
diff --git a/tests/PackedConfigsTextureTest.cpp b/tests/PackedConfigsTextureTest.cpp
index 5f18ef3d57..adc8a3de7c 100644
--- a/tests/PackedConfigsTextureTest.cpp
+++ b/tests/PackedConfigsTextureTest.cpp
@@ -109,8 +109,8 @@ static void run_test(skiatest::Reporter* reporter, GrContext* context, int array
controlPixelData[i + 1] = 0xFA62;
}
- const SkImageInfo dstInfo = SkImageInfo::Make(DEV_W, DEV_H,
- kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
+ const SkImageInfo dstInfo =
+ SkImageInfo::Make(DEV_W, DEV_H, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
for (auto origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
auto proxy = sk_gpu_test::MakeTextureProxyFromData(context, false, DEV_W, DEV_H,
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp
index ccb2ced4fd..867f766d17 100644
--- a/tests/ReadPixelsTest.cpp
+++ b/tests/ReadPixelsTest.cpp
@@ -67,6 +67,7 @@ static SkPMColor get_dst_bmp_init_color(int x, int y, int w) {
return SkPackARGB32(0xff, r, g , b);
}
+// TODO: Make this consider both ATs
static SkPMColor convert_to_pmcolor(SkColorType ct, SkAlphaType at, const uint32_t* addr,
bool* doUnpremul) {
*doUnpremul = (kUnpremul_SkAlphaType == at);
@@ -80,10 +81,12 @@ static SkPMColor convert_to_pmcolor(SkColorType ct, SkAlphaType at, const uint32
r = static_cast<U8CPU>(c[2]);
a = static_cast<U8CPU>(c[3]);
break;
+ case kRGB_888x_SkColorType: // fallthrough
case kRGBA_8888_SkColorType:
r = static_cast<U8CPU>(c[0]);
g = static_cast<U8CPU>(c[1]);
b = static_cast<U8CPU>(c[2]);
+ // We set this even when for kRGB_888x because our caller will validate that it is 0xff.
a = static_cast<U8CPU>(c[3]);
break;
default:
@@ -165,16 +168,13 @@ static bool check_read_pixel(SkPMColor a, SkPMColor b, bool didPremulConversion)
// checks the bitmap contains correct pixels after the readPixels
// if the bitmap was prefilled with pixels it checks that these weren't
// overwritten in the area outside the readPixels.
-static bool check_read(skiatest::Reporter* reporter,
- const SkBitmap& bitmap,
- int x, int y,
- bool checkCanvasPixels,
- bool checkBitmapPixels,
- SkColorType ct,
- SkAlphaType at) {
- SkASSERT(ct == bitmap.colorType() && at == bitmap.alphaType());
+static bool check_read(skiatest::Reporter* reporter, const SkBitmap& bitmap, int x, int y,
+ bool checkSurfacePixels, bool checkBitmapPixels,
+ SkAlphaType surfaceAlphaType) {
+ SkAlphaType bmpAT = bitmap.alphaType();
+ SkColorType bmpCT = bitmap.colorType();
SkASSERT(!bitmap.isNull());
- SkASSERT(checkCanvasPixels || checkBitmapPixels);
+ SkASSERT(checkSurfacePixels || checkBitmapPixels);
int bw = bitmap.width();
int bh = bitmap.height();
@@ -184,7 +184,7 @@ static bool check_read(skiatest::Reporter* reporter,
if (!clippedSrcRect.intersect(srcRect)) {
clippedSrcRect.setEmpty();
}
- if (kAlpha_8_SkColorType == ct) {
+ if (kAlpha_8_SkColorType == bmpCT) {
for (int by = 0; by < bh; ++by) {
for (int bx = 0; bx < bw; ++bx) {
int devx = bx + srcRect.fLeft;
@@ -192,11 +192,14 @@ static bool check_read(skiatest::Reporter* reporter,
const uint8_t* alpha = bitmap.getAddr8(bx, by);
if (clippedSrcRect.contains(devx, devy)) {
- if (checkCanvasPixels) {
- uint8_t canvasAlpha = SkGetPackedA32(get_src_color(devx, devy));
- if (canvasAlpha != *alpha) {
- ERRORF(reporter, "Expected readback alpha (%d, %d) value 0x%02x, got 0x%02x. ",
- bx, by, canvasAlpha, *alpha);
+ if (checkSurfacePixels) {
+ uint8_t surfaceAlpha = (surfaceAlphaType == kOpaque_SkAlphaType)
+ ? 0xFF
+ : SkGetPackedA32(get_src_color(devx, devy));
+ if (surfaceAlpha != *alpha) {
+ ERRORF(reporter,
+ "Expected readback alpha (%d, %d) value 0x%02x, got 0x%02x. ",
+ bx, by, surfaceAlpha, *alpha);
return false;
}
}
@@ -220,13 +223,18 @@ static bool check_read(skiatest::Reporter* reporter,
const uint32_t* pixel = bitmap.getAddr32(bx, by);
if (clippedSrcRect.contains(devx, devy)) {
- if (checkCanvasPixels) {
- SkPMColor canvasPixel = get_src_color(devx, devy);
+ if (checkSurfacePixels) {
+ SkPMColor surfacePMColor = get_src_color(devx, devy);
+ if (kOpaque_SkAlphaType == surfaceAlphaType || kOpaque_SkAlphaType == bmpAT) {
+ surfacePMColor |= 0xFF000000;
+ }
bool didPremul;
- SkPMColor pmPixel = convert_to_pmcolor(ct, at, pixel, &didPremul);
- if (!check_read_pixel(pmPixel, canvasPixel, didPremul)) {
- ERRORF(reporter, "Expected readback pixel (%d, %d) value 0x%08x, got 0x%08x. "
- "Readback was unpremul: %d", bx, by, canvasPixel, pmPixel, didPremul);
+ SkPMColor pmPixel = convert_to_pmcolor(bmpCT, bmpAT, pixel, &didPremul);
+ if (!check_read_pixel(pmPixel, surfacePMColor, didPremul)) {
+ ERRORF(reporter,
+ "Expected readback pixel (%d, %d) value 0x%08x, got 0x%08x. "
+ "Readback was unpremul: %d",
+ bx, by, surfacePMColor, pmPixel, didPremul);
return false;
}
}
@@ -288,11 +296,12 @@ static const struct {
SkColorType fColorType;
SkAlphaType fAlphaType;
} gReadPixelsConfigs[] = {
- { kRGBA_8888_SkColorType, kPremul_SkAlphaType },
- { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType },
- { kBGRA_8888_SkColorType, kPremul_SkAlphaType },
- { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType },
- { kAlpha_8_SkColorType, kPremul_SkAlphaType },
+ {kRGBA_8888_SkColorType, kPremul_SkAlphaType},
+ {kRGBA_8888_SkColorType, kUnpremul_SkAlphaType},
+ {kRGB_888x_SkColorType, kOpaque_SkAlphaType},
+ {kBGRA_8888_SkColorType, kPremul_SkAlphaType},
+ {kBGRA_8888_SkColorType, kUnpremul_SkAlphaType},
+ {kAlpha_8_SkColorType, kPremul_SkAlphaType},
};
const SkIRect gReadPixelsTestRects[] = {
// entire thing
@@ -341,8 +350,58 @@ const SkIRect gReadPixelsTestRects[] = {
SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10),
};
+enum class ReadSuccessExpectation {
+ kNo,
+ kMaybe,
+ kYes,
+};
+
+bool check_success_expectation(ReadSuccessExpectation expectation, bool actualSuccess) {
+ switch (expectation) {
+ case ReadSuccessExpectation::kMaybe:
+ return true;
+ case ReadSuccessExpectation::kNo:
+ return !actualSuccess;
+ case ReadSuccessExpectation::kYes:
+ return actualSuccess;
+ }
+ return false;
+}
+
+ReadSuccessExpectation read_should_succeed(const SkIRect& srcRect, const SkImageInfo& dstInfo,
+ const SkImageInfo& srcInfo, bool isGPU) {
+ if (!SkIRect::Intersects(srcRect, DEV_RECT)) {
+ return ReadSuccessExpectation::kNo;
+ }
+ if (!SkImageInfoValidConversion(dstInfo, srcInfo)) {
+ return ReadSuccessExpectation::kNo;
+ }
+ if (!isGPU) {
+ return ReadSuccessExpectation::kYes;
+ }
+ // This serves more as documentation of what currently works on the GPU rather than desired
+ // expectations. Once we make GrSurfaceContext color/alpha type aware and clean up some read
+ // pixels code we will make more scenarios work.
+
+ // The GPU code current only does the premul->unpremul conversion, not the reverse.
+ if (srcInfo.alphaType() == kUnpremul_SkAlphaType &&
+ dstInfo.alphaType() == kPremul_SkAlphaType) {
+ return ReadSuccessExpectation::kNo;
+ }
+ // We don't currently require reading alpha-only surfaces to succeed because of some pessimistic
+ // caps decisions and alpha/red complexity in GL.
+ if (SkColorTypeIsAlphaOnly(srcInfo.colorType())) {
+ return ReadSuccessExpectation::kMaybe;
+ }
+ if (!SkColorTypeIsAlwaysOpaque(srcInfo.colorType()) &&
+ SkColorTypeIsAlwaysOpaque(dstInfo.colorType())) {
+ return ReadSuccessExpectation::kNo;
+ }
+ return ReadSuccessExpectation::kYes;
+}
+
static void test_readpixels(skiatest::Reporter* reporter, const sk_sp<SkSurface>& surface,
- BitmapInit lastBitmapInit) {
+ const SkImageInfo& surfaceInfo, BitmapInit lastBitmapInit) {
SkCanvas* canvas = surface->getCanvas();
fill_src_canvas(canvas);
for (size_t rect = 0; rect < SK_ARRAY_COUNT(gReadPixelsTestRects); ++rect) {
@@ -363,18 +422,21 @@ static void test_readpixels(skiatest::Reporter* reporter, const sk_sp<SkSurface>
bool success = surface->readPixels(bmp, srcRect.fLeft, srcRect.fTop);
uint32_t idAfter = surface->generationID();
- // we expect to succeed when the read isn't fully clipped
- // out.
- bool expectSuccess = SkIRect::Intersects(srcRect, DEV_RECT);
+ // we expect to succeed when the read isn't fully clipped out and the infos are
+ // compatible.
+ bool isGPU = SkToBool(surface->getCanvas()->getGrContext());
+ auto expectSuccess = read_should_succeed(srcRect, bmp.info(), surfaceInfo, isGPU);
// determine whether we expected the read to succeed.
- REPORTER_ASSERT(reporter, success == expectSuccess);
+ REPORTER_ASSERT(reporter, check_success_expectation(expectSuccess, success),
+ "Read succeed=%d unexpectedly, src ct/at: %d/%d, dst ct/at: %d/%d",
+ success, surfaceInfo.colorType(), surfaceInfo.alphaType(),
+ bmp.info().colorType(), bmp.info().alphaType());
// read pixels should never change the gen id
REPORTER_ASSERT(reporter, idBefore == idAfter);
if (success || startsWithPixels) {
- check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop,
- success, startsWithPixels,
- gReadPixelsConfigs[c].fColorType, gReadPixelsConfigs[c].fAlphaType);
+ check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop, success,
+ startsWithPixels, surfaceInfo.alphaType());
} else {
// if we had no pixels beforehand and the readPixels
// failed then our bitmap should still not have pixels
@@ -384,11 +446,12 @@ static void test_readpixels(skiatest::Reporter* reporter, const sk_sp<SkSurface>
}
}
}
+
DEF_TEST(ReadPixels, reporter) {
const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
auto surface(SkSurface::MakeRaster(info));
// SW readback fails a premul check when reading back to an unaligned rowbytes.
- test_readpixels(reporter, surface, kLastAligned_BitmapInit);
+ test_readpixels(reporter, surface, info, kLastAligned_BitmapInit);
}
#if SK_SUPPORT_GPU
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Gpu, reporter, ctxInfo) {
@@ -399,18 +462,29 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Gpu, reporter, ctxInfo) {
return;
}
- const SkImageInfo ii = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
- for (auto& origin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
- sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctxInfo.grContext(), SkBudgeted::kNo,
- ii, 0, origin, nullptr));
- test_readpixels(reporter, surface, kLast_BitmapInit);
+ static const SkImageInfo kImageInfos[] = {
+ SkImageInfo::Make(DEV_W, DEV_H, kRGBA_8888_SkColorType, kPremul_SkAlphaType),
+ SkImageInfo::Make(DEV_W, DEV_H, kBGRA_8888_SkColorType, kPremul_SkAlphaType),
+ SkImageInfo::Make(DEV_W, DEV_H, kRGB_888x_SkColorType, kOpaque_SkAlphaType),
+ SkImageInfo::Make(DEV_W, DEV_H, kAlpha_8_SkColorType, kPremul_SkAlphaType),
+ };
+ for (const auto& ii : kImageInfos) {
+ for (auto& origin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
+ sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(
+ ctxInfo.grContext(), SkBudgeted::kNo, ii, 0, origin, nullptr));
+ if (!surface) {
+ continue;
+ }
+ test_readpixels(reporter, surface, ii, kLast_BitmapInit);
+ }
}
}
#endif
#if SK_SUPPORT_GPU
static void test_readpixels_texture(skiatest::Reporter* reporter,
- sk_sp<GrSurfaceContext> sContext) {
+ sk_sp<GrSurfaceContext> sContext,
+ const SkImageInfo& surfaceInfo) {
for (size_t rect = 0; rect < SK_ARRAY_COUNT(gReadPixelsTestRects); ++rect) {
const SkIRect& srcRect = gReadPixelsTestRects[rect];
for (BitmapInit bmi = kFirstBitmapInit; bmi <= kLast_BitmapInit; bmi = nextBMI(bmi)) {
@@ -426,15 +500,32 @@ static void test_readpixels_texture(skiatest::Reporter* reporter,
if (startsWithPixels) {
fill_dst_bmp_with_init_data(&bmp);
uint32_t flags = 0;
+ // TODO: These two hacks can go away when the surface context knows the alpha
+ // type.
+ // Tell the read to perform an unpremul step since it doesn't know alpha type.
if (gReadPixelsConfigs[c].fAlphaType == kUnpremul_SkAlphaType) {
flags = GrContextPriv::kUnpremul_PixelOpsFlag;
}
+ // The surface context doesn't know that the src is opaque. We don't support
+ // converting non-opaque data to opaque during a read.
+ if (bmp.alphaType() == kOpaque_SkAlphaType &&
+ surfaceInfo.alphaType() != kOpaque_SkAlphaType) {
+ continue;
+ }
bool success = sContext->readPixels(bmp.info(), bmp.getPixels(),
bmp.rowBytes(),
srcRect.fLeft, srcRect.fTop, flags);
- check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop,
- success, true,
- gReadPixelsConfigs[c].fColorType, gReadPixelsConfigs[c].fAlphaType);
+ auto expectSuccess =
+ read_should_succeed(srcRect, bmp.info(), surfaceInfo, true);
+ REPORTER_ASSERT(
+ reporter, check_success_expectation(expectSuccess, success),
+ "Read succeed=%d unexpectedly, src ct/at: %d/%d, dst ct/at: %d/%d",
+ success, surfaceInfo.colorType(), surfaceInfo.alphaType(),
+ bmp.info().colorType(), bmp.info().alphaType());
+ if (success) {
+ check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop, success, true,
+ surfaceInfo.alphaType());
+ }
}
}
}
@@ -460,7 +551,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Texture, reporter, ctxInfo) {
bmp.rowBytes());
sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(
std::move(proxy));
- test_readpixels_texture(reporter, std::move(sContext));
+ auto info = SkImageInfo::Make(DEV_W, DEV_H, kN32_SkColorType, kPremul_SkAlphaType);
+ test_readpixels_texture(reporter, std::move(sContext), info);
}
}
}
diff --git a/tests/VkUploadPixelsTests.cpp b/tests/VkUploadPixelsTests.cpp
index acadf7dc1d..27d30bda65 100644
--- a/tests/VkUploadPixelsTests.cpp
+++ b/tests/VkUploadPixelsTests.cpp
@@ -67,7 +67,7 @@ void basic_texture_test(skiatest::Reporter* reporter, GrContext* context, SkColo
if (proxy) {
sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(proxy);
- SkImageInfo dstInfo = SkImageInfo::Make(kWidth, kHeight, ct, kOpaque_SkAlphaType);
+ SkImageInfo dstInfo = SkImageInfo::Make(kWidth, kHeight, ct, kPremul_SkAlphaType);
bool result = sContext->readPixels(dstInfo, dstBuffer, 0, 0, 0);
REPORTER_ASSERT(reporter, result);
@@ -76,7 +76,7 @@ void basic_texture_test(skiatest::Reporter* reporter, GrContext* context, SkColo
kWidth,
kHeight));
- dstInfo = SkImageInfo::Make(10, 2, ct, kOpaque_SkAlphaType);
+ dstInfo = SkImageInfo::Make(10, 2, ct, kPremul_SkAlphaType);
result = sContext->writePixels(dstInfo, srcBuffer, 0, 2, 10);
REPORTER_ASSERT(reporter, result);
@@ -97,7 +97,7 @@ void basic_texture_test(skiatest::Reporter* reporter, GrContext* context, SkColo
if (proxy) {
sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(proxy);
- SkImageInfo dstInfo = SkImageInfo::Make(kWidth, kHeight, ct, kOpaque_SkAlphaType);
+ SkImageInfo dstInfo = SkImageInfo::Make(kWidth, kHeight, ct, kPremul_SkAlphaType);
bool result = sContext->readPixels(dstInfo, dstBuffer, 0, 0, 0);
REPORTER_ASSERT(reporter, result);
@@ -106,7 +106,7 @@ void basic_texture_test(skiatest::Reporter* reporter, GrContext* context, SkColo
kWidth,
kHeight));
- dstInfo = SkImageInfo::Make(4, 5, ct, kOpaque_SkAlphaType);
+ dstInfo = SkImageInfo::Make(4, 5, ct, kPremul_SkAlphaType);
result = sContext->writePixels(dstInfo, srcBuffer, 0, 5, 4);
REPORTER_ASSERT(reporter, result);
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index f00d092d03..1f5758184f 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -7,6 +7,7 @@
#include "SkCanvas.h"
#include "SkColorData.h"
+#include "SkImageInfoPriv.h"
#include "SkMathPriv.h"
#include "SkSurface.h"
#include "Test.h"
@@ -67,7 +68,8 @@ static uint32_t pack_color_type(SkColorType ct, U8CPU a, U8CPU r, U8CPU g, U8CPU
result[2] = r;
result[3] = a;
break;
- case kRGBA_8888_SkColorType:
+ case kRGBA_8888_SkColorType: // fallthrough
+ case kRGB_888x_SkColorType:
result[0] = r;
result[1] = g;
result[2] = b;
@@ -144,6 +146,7 @@ static SkPMColor convert_to_PMColor(SkColorType ct, SkAlphaType at, uint32_t col
}
switch (ct) {
case kRGBA_8888_SkColorType:
+ case kRGB_888x_SkColorType: // fallthrough
color = SkSwizzle_RGBA_to_PMColor(color);
break;
case kBGRA_8888_SkColorType:
@@ -176,8 +179,32 @@ static bool check_pixel(SkPMColor a, SkPMColor b, bool didPremulConversion) {
SkAbs32(aB - bB) <= 1;
}
-static bool check_write(skiatest::Reporter* reporter, SkSurface* surf, const SkBitmap& bitmap,
- int writeX, int writeY) {
+bool write_should_succeed(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo, bool isGPU) {
+ if (!SkImageInfoValidConversion(dstInfo, srcInfo)) {
+ return false;
+ }
+ if (!isGPU) {
+ return true;
+ }
+ // The GPU backend supports writing unpremul data to a premul dst but not vice versa.
+ if (srcInfo.alphaType() == kPremul_SkAlphaType &&
+ dstInfo.alphaType() == kUnpremul_SkAlphaType) {
+ return false;
+ }
+ if (!SkColorTypeIsAlwaysOpaque(srcInfo.colorType()) &&
+ SkColorTypeIsAlwaysOpaque(dstInfo.colorType())) {
+ return false;
+ }
+ // The source has no alpha value and the dst is only alpha
+ if (SkColorTypeIsAlwaysOpaque(srcInfo.colorType()) &&
+ SkColorTypeIsAlphaOnly(dstInfo.colorType())) {
+ return false;
+ }
+ return true;
+}
+
+static bool check_write(skiatest::Reporter* reporter, SkSurface* surf, SkAlphaType surfaceAlphaType,
+ const SkBitmap& bitmap, int writeX, int writeY) {
size_t canvasRowBytes;
const uint32_t* canvasPixels;
@@ -215,6 +242,10 @@ static bool check_write(skiatest::Reporter* reporter, SkSurface* surf, const SkB
bool mul = (kUnpremul_SkAlphaType == bmInfo.alphaType());
SkPMColor bmpPMColor = convert_to_PMColor(bmInfo.colorType(), bmInfo.alphaType(),
bmpColor8888);
+ if (bmInfo.alphaType() == kOpaque_SkAlphaType ||
+ surfaceAlphaType == kOpaque_SkAlphaType) {
+ bmpPMColor |= 0xFF000000;
+ }
if (!check_pixel(bmpPMColor, canvasPixel, mul)) {
ERRORF(reporter, "Expected canvas pixel at %d, %d to be 0x%08x, got 0x%08x. "
"Write performed premul: %d", cx, cy, bmpPMColor, canvasPixel, mul);
@@ -293,7 +324,8 @@ DEF_TEST(WritePixelsSurfaceGenID, reporter) {
REPORTER_ASSERT(reporter, genID1 != genID2);
}
-static void test_write_pixels(skiatest::Reporter* reporter, SkSurface* surface) {
+static void test_write_pixels(skiatest::Reporter* reporter, SkSurface* surface,
+ const SkImageInfo& surfaceInfo) {
const SkIRect testRects[] = {
// entire thing
DEV_RECT,
@@ -347,10 +379,11 @@ static void test_write_pixels(skiatest::Reporter* reporter, SkSurface* surface)
SkColorType fColorType;
SkAlphaType fAlphaType;
} gSrcConfigs[] = {
- { kRGBA_8888_SkColorType, kPremul_SkAlphaType },
- { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType },
- { kBGRA_8888_SkColorType, kPremul_SkAlphaType },
- { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType },
+ {kRGBA_8888_SkColorType, kPremul_SkAlphaType},
+ {kRGBA_8888_SkColorType, kUnpremul_SkAlphaType},
+ {kRGB_888x_SkColorType, kOpaque_SkAlphaType},
+ {kBGRA_8888_SkColorType, kPremul_SkAlphaType},
+ {kBGRA_8888_SkColorType, kUnpremul_SkAlphaType},
};
for (size_t r = 0; r < SK_ARRAY_COUNT(testRects); ++r) {
const SkIRect& rect = testRects[r];
@@ -359,6 +392,7 @@ static void test_write_pixels(skiatest::Reporter* reporter, SkSurface* surface)
const SkColorType ct = gSrcConfigs[c].fColorType;
const SkAlphaType at = gSrcConfigs[c].fAlphaType;
+ bool isGPU = SkToBool(surface->getCanvas()->getGrContext());
fill_surface(surface);
SkBitmap bmp;
REPORTER_ASSERT(reporter, setup_bitmap(&bmp, ct, at, rect.width(),
@@ -369,19 +403,21 @@ static void test_write_pixels(skiatest::Reporter* reporter, SkSurface* surface)
surface->writePixels(bmp, rect.fLeft, rect.fTop);
uint32_t idAfter = surface->generationID();
- REPORTER_ASSERT(reporter, check_write(reporter, surface, bmp,
- rect.fLeft, rect.fTop));
+ REPORTER_ASSERT(reporter, check_write(reporter, surface, surfaceInfo.alphaType(),
+ bmp, rect.fLeft, rect.fTop));
// we should change the genID iff pixels were actually written.
SkIRect canvasRect = SkIRect::MakeSize(canvas->getBaseLayerSize());
SkIRect writeRect = SkIRect::MakeXYWH(rect.fLeft, rect.fTop,
bmp.width(), bmp.height());
- bool intersects = SkIRect::Intersects(canvasRect, writeRect) ;
- REPORTER_ASSERT(reporter, intersects == (idBefore != idAfter));
+ bool expectSuccess = SkIRect::Intersects(canvasRect, writeRect) &&
+ write_should_succeed(surfaceInfo, bmp.info(), isGPU);
+ REPORTER_ASSERT(reporter, expectSuccess == (idBefore != idAfter));
}
}
}
}
+
DEF_TEST(WritePixels, reporter) {
const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
for (auto& tightRowBytes : { true, false }) {
@@ -394,9 +430,10 @@ DEF_TEST(WritePixels, reporter) {
}
auto surface(SkSurface::MakeRasterDirectReleaseProc(info, pixels, rowBytes,
free_pixels, nullptr));
- test_write_pixels(reporter, surface.get());
+ test_write_pixels(reporter, surface.get(), info);
}
}
+
#if SK_SUPPORT_GPU
static void test_write_pixels(skiatest::Reporter* reporter, GrContext* context, int sampleCnt) {
const SkImageInfo ii = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
@@ -405,7 +442,7 @@ static void test_write_pixels(skiatest::Reporter* reporter, GrContext* context,
SkBudgeted::kNo, ii, sampleCnt,
origin, nullptr));
if (surface) {
- test_write_pixels(reporter, surface.get());
+ test_write_pixels(reporter, surface.get(), ii);
}
}
}
@@ -425,11 +462,15 @@ static void test_write_pixels_non_texture(skiatest::Reporter* reporter, GrContex
for (auto& origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
nullptr, DEV_W, DEV_H, kSkia8888_GrPixelConfig, true, GrMipMapped::kNo);
+ if (!backendTex.isValid()) {
+ continue;
+ }
SkColorType colorType = kN32_SkColorType;
sk_sp<SkSurface> surface(SkSurface::MakeFromBackendTextureAsRenderTarget(
context, backendTex, origin, sampleCnt, colorType, nullptr, nullptr));
if (surface) {
- test_write_pixels(reporter, surface.get());
+ auto ii = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
+ test_write_pixels(reporter, surface.get(), ii);
}
gpu->deleteTestingOnlyBackendTexture(backendTex);
}
diff --git a/tools/flags/SkCommonFlagsConfig.cpp b/tools/flags/SkCommonFlagsConfig.cpp
index b8fd4190a6..934fe146e9 100644
--- a/tools/flags/SkCommonFlagsConfig.cpp
+++ b/tools/flags/SkCommonFlagsConfig.cpp
@@ -51,10 +51,12 @@ static const struct {
{ "gl4444", "gpu", "api=gl,color=4444" },
{ "gl565", "gpu", "api=gl,color=565" },
{ "glf16", "gpu", "api=gl,color=f16" },
+ { "gl888x", "gpu", "api=gl,color=888x" },
{ "gl1010102", "gpu", "api=gl,color=1010102" },
{ "glsrgb", "gpu", "api=gl,color=srgb" },
{ "glsrgbnl", "gpu", "api=gl,color=srgbnl" },
{ "glesf16", "gpu", "api=gles,color=f16" },
+ { "gles888x", "gpu", "api=gles,color=888x" },
{ "gles1010102", "gpu", "api=gles,color=1010102" },
{ "glessrgb", "gpu", "api=gles,color=srgb" },
{ "glessrgbnl", "gpu", "api=gles,color=srgbnl" },
@@ -148,6 +150,7 @@ static const char configExtendedHelp[] =
"\t Select framebuffer color format.\n"
"\t Options:\n"
"\t\t8888\t\t\tLinear 8888.\n"
+ "\t\t888x\t\t\tLinear 888x.\n"
"\t\t4444\t\t\tLinear 4444.\n"
"\t\t565\t\t\tLinear 565.\n"
"\t\tf16{_gamut}\t\tLinear 16-bit floating point.\n"
@@ -296,6 +299,10 @@ static bool parse_option_gpu_color(const SkString& value,
*outColorType = kRGBA_8888_SkColorType;
*outColorSpace = nullptr;
return true;
+ } else if (value.equals("888x")) {
+ *outColorType = kRGB_888x_SkColorType;
+ *outColorSpace = nullptr;
+ return true;
} else if (value.equals("4444")) {
*outColorType = kARGB_4444_SkColorType;
*outColorSpace = nullptr;