basic first pass at RGBA F32 support

Draws basically the same as f16.

The existing load_f32, load_f32_dst, and store_f32 stages all had the
same bug that we'd never noticed because dy was always 0 until now.

Change-Id: Ibbd393fa1acc5df414be4cdef0f5a9d11dcccdb3
Reviewed-on: https://skia-review.googlesource.com/137585
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
Mike Klein 2018-06-26 11:43:06 -04:00 committed by Skia Commit-Bot
parent 9b6125d046
commit 3785471ff6
29 changed files with 206 additions and 55 deletions

View File

@ -926,6 +926,8 @@ static Sink* create_sink(const GrContextOptions& grCtxOptions, const SkCommandLi
SINK( "esrgb", RasterSink, kRGBA_F16_SkColorType, srgb );
SINK( "narrow", RasterSink, kRGBA_8888_SkColorType, narrow );
SINK("enarrow", RasterSink, kRGBA_F16_SkColorType, narrow );
SINK( "f32", RasterSink, kRGBA_F32_SkColorType, srgbLinear);
}
#undef SINK
return nullptr;

View File

@ -22,6 +22,7 @@ static const char* color_type_name(SkColorType colorType) {
case kRGB_101010x_SkColorType: return "101010x";
case kGray_8_SkColorType: return "G8";
case kRGBA_F16_SkColorType: return "F16";
case kRGBA_F32_SkColorType: return "F32";
}
return "";
}

View File

@ -141,6 +141,7 @@ static void draw_gamut_grid(SkCanvas* canvas, SkTArray<std::unique_ptr<CellRende
wideGamutRGB_toXYZD50);
break;
case kRGBA_F16_SkColorType:
case kRGBA_F32_SkColorType:
srgbCS = SkColorSpace::MakeSRGBLinear();
wideCS = SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
wideGamutRGB_toXYZD50);

View File

@ -93,7 +93,8 @@ enum SkColorType {
kRGB_101010x_SkColorType, //!< pixel with 10 bits each for red, green, blue; in 32-bit word
kGray_8_SkColorType, //!< pixel with grayscale level in 8-bit byte
kRGBA_F16_SkColorType, //!< pixel with half floats for red, green, blue, alpha; in 64-bit word
kLastEnum_SkColorType = kRGBA_F16_SkColorType,//!< last valid value
kRGBA_F32_SkColorType, //!< pixel with single floats for red, green, blue, alpha
kLastEnum_SkColorType = kRGBA_F32_SkColorType,//!< last valid value
#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
kN32_SkColorType = kBGRA_8888_SkColorType,//!< native ARGB 32-bit encoding

View File

@ -1241,7 +1241,7 @@ static inline SkColorType GrColorTypeToSkColorType(GrColorType ct) {
case GrColorType::kAlpha_F16: return kUnknown_SkColorType;
case GrColorType::kRGBA_F16: return kRGBA_F16_SkColorType;
case GrColorType::kRG_F32: return kUnknown_SkColorType;
case GrColorType::kRGBA_F32: return kUnknown_SkColorType;
case GrColorType::kRGBA_F32: return kRGBA_F32_SkColorType;
}
SK_ABORT("Invalid GrColorType");
return kUnknown_SkColorType;
@ -1260,6 +1260,7 @@ static inline GrColorType SkColorTypeToGrColorType(SkColorType ct) {
case kRGBA_F16_SkColorType: return GrColorType::kRGBA_F16;
case kRGBA_1010102_SkColorType: return GrColorType::kRGBA_1010102;
case kRGB_101010x_SkColorType: return GrColorType::kUnknown;
case kRGBA_F32_SkColorType: return GrColorType::kRGBA_F32;
}
SK_ABORT("Invalid SkColorType");
return GrColorType::kUnknown;

View File

@ -36,6 +36,7 @@ static inline uint32_t SkColorTypeComponentFlags(SkColorType ct) {
case kRGB_101010x_SkColorType: return kRGB_SkColorTypeComponentFlags;
case kGray_8_SkColorType: return kGray_SkColorTypeComponentFlag;
case kRGBA_F16_SkColorType: return kRGBA_SkColorTypeComponentFlags;
case kRGBA_F32_SkColorType: return kRGBA_SkColorTypeComponentFlags;
}
return 0;
}
@ -68,6 +69,7 @@ static int SkColorTypeShiftPerPixel(SkColorType ct) {
case kRGB_101010x_SkColorType: return 2;
case kGray_8_SkColorType: return 0;
case kRGBA_F16_SkColorType: return 3;
case kRGBA_F32_SkColorType: return 4;
}
return 0;
}

View File

@ -365,6 +365,10 @@ static void pick_memory_stages(SkColorType ct, SkRasterPipeline::StockStage* loa
if (load) *load = SkRasterPipeline::load_f16;
if (store) *store = SkRasterPipeline::store_f16;
break;
case kRGBA_F32_SkColorType:
if (load) *load = SkRasterPipeline::load_f32;
if (store) *store = SkRasterPipeline::store_f32;
break;
}
}

View File

@ -384,6 +384,9 @@ void* SkBitmap::getAddr(int x, int y) const {
if (base) {
base += y * this->rowBytes();
switch (this->colorType()) {
case kRGBA_F32_SkColorType:
base += x << 4;
break;
case kRGBA_F16_SkColorType:
base += x << 3;
break;

View File

@ -210,6 +210,7 @@ static bool valid_for_bitmap_device(const SkImageInfo& info,
case kBGRA_8888_SkColorType:
case kRGBA_1010102_SkColorType:
case kRGBA_F16_SkColorType:
case kRGBA_F32_SkColorType:
break;
case kGray_8_SkColorType:
case kRGB_565_SkColorType:

View File

@ -123,6 +123,7 @@ public:
case kRGBA_8888_SkColorType: p.append(SkRasterPipeline::load_8888, ctx); break;
case kRGBA_1010102_SkColorType: p.append(SkRasterPipeline::load_1010102, ctx); break;
case kRGBA_F16_SkColorType: p.append(SkRasterPipeline::load_f16, ctx); break;
case kRGBA_F32_SkColorType: p.append(SkRasterPipeline::load_f32, ctx); break;
case kRGB_888x_SkColorType: p.append(SkRasterPipeline::load_8888, ctx);
p.append(SkRasterPipeline::force_opaque ); break;

View File

@ -2871,6 +2871,7 @@ static bool supported_for_raster_canvas(const SkImageInfo& info) {
case kRGB_565_SkColorType:
case kN32_SkColorType:
case kRGBA_F16_SkColorType:
case kRGBA_F32_SkColorType:
case kRGBA_1010102_SkColorType:
break;
default:

View File

@ -231,6 +231,16 @@ static void convert_to_alpha8(uint8_t* dst, size_t dstRB, const SkImageInfo& src
}
break;
}
case kRGBA_F32_SkColorType: {
auto rgba = (const float*)src;
for (int y = 0; y < srcInfo.height(); y++) {
for (int x = 0; x < srcInfo.width(); x++) {
dst[x] = (uint8_t)(255.0f * rgba[4*x+3]);
}
dst = SkTAddOffset<uint8_t>(dst, dstRB);
rgba = SkTAddOffset<const float>(rgba, srcRB);
}
} break;
default:
SkASSERT(false);
break;
@ -270,6 +280,9 @@ static void convert_with_pipeline(const SkImageInfo& dstInfo, void* dstRow, size
case kRGBA_F16_SkColorType:
pipeline.append(SkRasterPipeline::load_f16, &src);
break;
case kRGBA_F32_SkColorType:
pipeline.append(SkRasterPipeline::load_f32, &src);
break;
case kGray_8_SkColorType:
pipeline.append(SkRasterPipeline::load_g8, &src);
break;
@ -381,6 +394,9 @@ static void convert_with_pipeline(const SkImageInfo& dstInfo, void* dstRow, size
case kRGBA_F16_SkColorType:
pipeline.append(SkRasterPipeline::store_f16, &dst);
break;
case kRGBA_F32_SkColorType:
pipeline.append(SkRasterPipeline::store_f32, &dst);
break;
case kARGB_4444_SkColorType:
pipeline.append(SkRasterPipeline::store_4444, &dst);
break;

View File

@ -23,6 +23,7 @@ int SkColorTypeBytesPerPixel(SkColorType ct) {
case kRGB_101010x_SkColorType: return 4;
case kGray_8_SkColorType: return 1;
case kRGBA_F16_SkColorType: return 8;
case kRGBA_F32_SkColorType: return 16;
}
return 0;
}
@ -74,6 +75,7 @@ bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
case kBGRA_8888_SkColorType:
case kRGBA_1010102_SkColorType:
case kRGBA_F16_SkColorType:
case kRGBA_F32_SkColorType:
if (kUnknown_SkAlphaType == alphaType) {
return false;
}

View File

@ -230,6 +230,7 @@ bool SkPixmap::erase(SkColor color, const SkIRect& inArea) const {
}
case kRGBA_F16_SkColorType:
case kRGBA_F32_SkColorType:
// The colorspace is unspecified, so assume linear just like getColor().
this->erase(SkColor4f{(1 / 255.0f) * r,
(1 / 255.0f) * g,
@ -254,15 +255,29 @@ bool SkPixmap::erase(const SkColor4f& origColor, const SkIRect* subset) const {
const SkColor4f color = origColor.pin();
if (kRGBA_F16_SkColorType != pm.colorType()) {
return pm.erase(color.toSkColor());
if (pm.colorType() == kRGBA_F16_SkColorType) {
const uint64_t half4 = color.premul().toF16();
for (int y = 0; y < pm.height(); ++y) {
sk_memset64(pm.writable_addr64(0, y), half4, pm.width());
}
return true;
}
const uint64_t half4 = color.premul().toF16();
for (int y = 0; y < pm.height(); ++y) {
sk_memset64(pm.writable_addr64(0, y), half4, pm.width());
if (pm.colorType() == kRGBA_F32_SkColorType) {
const SkPM4f rgba = color.premul();
for (int y = 0; y < pm.height(); ++y) {
auto row = (float*)pm.writable_addr();
for (int x = 0; x < pm.width(); ++x) {
row[4*x+0] = rgba.r();
row[4*x+1] = rgba.g();
row[4*x+2] = rgba.b();
row[4*x+3] = rgba.a();
}
}
return true;
}
return true;
return pm.erase(color.toSkColor());
}
bool SkPixmap::scalePixels(const SkPixmap& actualDst, SkFilterQuality quality) const {
@ -396,17 +411,31 @@ SkColor SkPixmap::getColor(int x, int y) const {
| (uint32_t)( a * 255.0f ) << 24;
}
case kRGBA_F16_SkColorType: {
const uint64_t* addr =
(const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
Sk4f p4 = SkHalfToFloat_finite_ftz(*addr);
if (p4[3] && needsUnpremul) {
float inva = 1 / p4[3];
p4 = p4 * Sk4f(inva, inva, inva, 1);
}
SkColor c;
SkNx_cast<uint8_t>(p4 * Sk4f(255) + Sk4f(0.5f)).store(&c);
// p4 is RGBA, but we want BGRA, so we need to swap next
return SkSwizzle_RB(c);
const uint64_t* addr =
(const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;
Sk4f p4 = SkHalfToFloat_finite_ftz(*addr);
if (p4[3] && needsUnpremul) {
float inva = 1 / p4[3];
p4 = p4 * Sk4f(inva, inva, inva, 1);
}
SkColor c;
SkNx_cast<uint8_t>(p4 * Sk4f(255) + Sk4f(0.5f)).store(&c);
// p4 is RGBA, but we want BGRA, so we need to swap next
return SkSwizzle_RB(c);
}
case kRGBA_F32_SkColorType: {
const float* rgba =
(const float*)fPixels + 4*y*(fRowBytes >> 4) + 4*x;
Sk4f p4 = Sk4f::Load(rgba);
// From here on, just like F16:
if (p4[3] && needsUnpremul) {
float inva = 1 / p4[3];
p4 = p4 * Sk4f(inva, inva, inva, 1);
}
SkColor c;
SkNx_cast<uint8_t>(p4 * Sk4f(255) + Sk4f(0.5f)).store(&c);
// p4 is RGBA, but we want BGRA, so we need to swap next
return SkSwizzle_RB(c);
}
default:
SkDEBUGFAIL("");

View File

@ -49,7 +49,7 @@
M(load_565) M(load_565_dst) M(store_565) M(gather_565) \
M(load_4444) M(load_4444_dst) M(store_4444) M(gather_4444) \
M(load_f16) M(load_f16_dst) M(store_f16) M(gather_f16) \
M(load_f32) M(load_f32_dst) M(store_f32) \
M(load_f32) M(load_f32_dst) M(store_f32) M(gather_f32) \
M(load_8888) M(load_8888_dst) M(store_8888) M(gather_8888) \
M(load_bgra) M(load_bgra_dst) M(store_bgra) M(gather_bgra) \
M(load_1010102) M(load_1010102_dst) M(store_1010102) M(gather_1010102) \

View File

@ -210,7 +210,8 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
// When we're drawing a constant color in Src mode, we can sometimes just memset.
// (The previous two optimizations help find more opportunities for this one.)
if (is_constant && blitter->fBlend == SkBlendMode::kSrc) {
if (is_constant && blitter->fBlend == SkBlendMode::kSrc
&& blitter->fDst.shiftPerPixel() <= 3 /*TODO: F32*/) {
// Run our color pipeline all the way through to produce what we'd memset when we can.
// Not all blits can memset, so we need to keep colorPipeline too.
SkRasterPipeline_<256> p;
@ -243,6 +244,7 @@ void SkRasterPipelineBlitter::append_load_dst(SkRasterPipeline* p) const {
case kRGBA_8888_SkColorType: p->append(SkRasterPipeline::load_8888_dst, ctx); break;
case kRGBA_1010102_SkColorType: p->append(SkRasterPipeline::load_1010102_dst, ctx); break;
case kRGBA_F16_SkColorType: p->append(SkRasterPipeline::load_f16_dst, ctx); break;
case kRGBA_F32_SkColorType: p->append(SkRasterPipeline::load_f32_dst, ctx); break;
case kRGB_888x_SkColorType: p->append(SkRasterPipeline::load_8888_dst, ctx);
p->append(SkRasterPipeline::force_opaque_dst ); break;
@ -275,6 +277,7 @@ void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p) const {
case kRGBA_8888_SkColorType: p->append(SkRasterPipeline::store_8888, ctx); break;
case kRGBA_1010102_SkColorType: p->append(SkRasterPipeline::store_1010102, ctx); break;
case kRGBA_F16_SkColorType: p->append(SkRasterPipeline::store_f16, ctx); break;
case kRGBA_F32_SkColorType: p->append(SkRasterPipeline::store_f32, ctx); break;
case kRGB_888x_SkColorType: p->append(SkRasterPipeline::force_opaque );
p->append(SkRasterPipeline::store_8888, ctx); break;
@ -305,7 +308,7 @@ void SkRasterPipelineBlitter::blitRect(int x, int y, int w, int h) {
case 1: sk_memset16(fDst.writable_addr16(x,y), fMemsetColor, w); break;
case 2: sk_memset32(fDst.writable_addr32(x,y), fMemsetColor, w); break;
case 3: sk_memset64(fDst.writable_addr64(x,y), fMemsetColor, w); break;
default: break;
default: SkASSERT(false); break;
}
}
return;

View File

@ -252,6 +252,8 @@ GrPixelConfig SkColorType2GrPixelConfig(const SkColorType type) {
return kGray_8_GrPixelConfig;
case kRGBA_F16_SkColorType:
return kRGBA_half_GrPixelConfig;
case kRGBA_F32_SkColorType:
return kRGBA_float_GrPixelConfig;
}
SkASSERT(0); // shouldn't get here
return kUnknown_GrPixelConfig;

View File

@ -2894,6 +2894,11 @@ bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* confi
*config = kRGBA_half_GrPixelConfig;
}
break;
case kRGBA_F32_SkColorType:
if (GR_GL_RGBA32F == format) {
*config = kRGBA_float_GrPixelConfig;
}
break;
}
return kUnknown_GrPixelConfig != *config;

View File

@ -625,6 +625,11 @@ bool validate_image_info(VkFormat format, SkColorType ct, GrPixelConfig* config)
*config = kRGBA_half_GrPixelConfig;
}
break;
case kRGBA_F32_SkColorType:
if (VK_FORMAT_R32G32B32A32_SFLOAT == format) {
*config = kRGBA_float_GrPixelConfig;
}
break;
}
return kUnknown_GrPixelConfig != *config;

View File

@ -269,6 +269,7 @@ bool SkSurface_Gpu::onDraw(const SkDeferredDisplayList* ddl) {
bool SkSurface_Gpu::Valid(const SkImageInfo& info) {
switch (info.colorType()) {
case kRGBA_F16_SkColorType:
case kRGBA_F32_SkColorType:
case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
return true;
@ -283,6 +284,7 @@ bool SkSurface_Gpu::Valid(const GrCaps* caps, GrPixelConfig config, SkColorSpace
case kSBGRA_8888_GrPixelConfig:
return caps->srgbSupport();
case kRGBA_half_GrPixelConfig:
case kRGBA_float_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
return true;

View File

@ -62,6 +62,7 @@ bool SkSurfaceValidateRasterInfo(const SkImageInfo& info, size_t rowBytes) {
case kBGRA_8888_SkColorType:
break;
case kRGBA_F16_SkColorType:
case kRGBA_F32_SkColorType:
break;
default:
return false;

View File

@ -410,6 +410,39 @@ static inline void transform_scanline_F16_to_premul_8888(char* SK_RESTRICT dst,
p.run(0,0, width,1);
}
/**
* Transform from kRGBA_F32 to 8-bytes-per-pixel RGBA.
*/
static inline void transform_scanline_F32(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
int width, int, const SkPMColor*) {
SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
dst_ctx = { (void*)dst, 0 };
SkRasterPipeline_<256> p;
p.append(SkRasterPipeline::load_f32, &src_ctx);
p.append(SkRasterPipeline::clamp_0); // F32 values may be out of [0,1] range, so clamp.
p.append(SkRasterPipeline::clamp_1);
p.append(SkRasterPipeline::to_srgb);
p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
p.run(0,0, width,1);
}
/**
* Transform from kPremul, kRGBA_F32 to 8-bytes-per-pixel RGBA.
*/
static inline void transform_scanline_F32_premul(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
int width, int, const SkPMColor*) {
SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
dst_ctx = { (void*)dst, 0 };
SkRasterPipeline_<256> p;
p.append(SkRasterPipeline::load_f32, &src_ctx);
p.append(SkRasterPipeline::unpremul);
p.append(SkRasterPipeline::clamp_0); // F32 values may be out of [0,1] range, so clamp.
p.append(SkRasterPipeline::clamp_1);
p.append(SkRasterPipeline::to_srgb);
p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
p.run(0,0, width,1);
}
static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
SkColorSpace* cs = info.colorSpace();
if (!cs) {
@ -417,7 +450,8 @@ static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
}
sk_sp<SkColorSpace> owned;
if (kRGBA_F16_SkColorType == info.colorType()) {
if (kRGBA_F16_SkColorType == info.colorType() ||
kRGBA_F32_SkColorType == info.colorType()) {
owned = cs->makeSRGBGamma();
cs = owned.get();
}

View File

@ -106,6 +106,7 @@ bool SkPngEncoderMgr::setHeader(const SkImageInfo& srcInfo, const SkPngEncoder::
int bitDepth = 8;
switch (srcInfo.colorType()) {
case kRGBA_F16_SkColorType:
case kRGBA_F32_SkColorType:
SkASSERT(srcInfo.colorSpace());
sigBit.red = 16;
sigBit.green = 16;
@ -288,6 +289,17 @@ static transform_scanline_proc choose_proc(const SkImageInfo& info,
SkASSERT(false);
return nullptr;
}
case kRGBA_F32_SkColorType:
switch (info.alphaType()) {
case kOpaque_SkAlphaType:
case kUnpremul_SkAlphaType:
return transform_scanline_F32;
case kPremul_SkAlphaType:
return transform_scanline_F32_premul;
default:
SkASSERT(false);
return nullptr;
}
case kRGBA_1010102_SkColorType:
switch (info.alphaType()) {
case kOpaque_SkAlphaType:

View File

@ -1712,15 +1712,23 @@ STAGE(store_u16_be, const SkJumper_MemoryCtx* ctx) {
}
STAGE(load_f32, const SkJumper_MemoryCtx* ctx) {
auto ptr = ptr_at_xy<const float>(ctx, 4*dx,dy);
auto ptr = ptr_at_xy<const float>(ctx, 4*dx,4*dy);
load4(ptr,tail, &r,&g,&b,&a);
}
STAGE(load_f32_dst, const SkJumper_MemoryCtx* ctx) {
auto ptr = ptr_at_xy<const float>(ctx, 4*dx,dy);
auto ptr = ptr_at_xy<const float>(ctx, 4*dx,4*dy);
load4(ptr,tail, &dr,&dg,&db,&da);
}
STAGE(gather_f32, const SkJumper_GatherCtx* ctx) {
const float* ptr;
U32 ix = ix_and_ptr(&ptr, ctx, r,g);
r = gather(ptr, 4*ix + 0);
g = gather(ptr, 4*ix + 1);
b = gather(ptr, 4*ix + 2);
a = gather(ptr, 4*ix + 3);
}
STAGE(store_f32, const SkJumper_MemoryCtx* ctx) {
auto ptr = ptr_at_xy<float>(ctx, 4*dx,dy);
auto ptr = ptr_at_xy<float>(ctx, 4*dx,4*dy);
store4(ptr,tail, r,g,b,a);
}

View File

@ -369,6 +369,7 @@ bool SkImageShader::onAppendStages(const StageRec& rec) const {
case kRGBA_8888_SkColorType: p->append(SkRasterPipeline::gather_8888, ctx); break;
case kRGBA_1010102_SkColorType: p->append(SkRasterPipeline::gather_1010102, ctx); break;
case kRGBA_F16_SkColorType: p->append(SkRasterPipeline::gather_f16, ctx); break;
case kRGBA_F32_SkColorType: p->append(SkRasterPipeline::gather_f32, ctx); break;
case kRGB_888x_SkColorType: p->append(SkRasterPipeline::gather_8888, ctx);
p->append(SkRasterPipeline::force_opaque ); break;

View File

@ -132,6 +132,8 @@ static GrBackendFormat create_backend_format(GrContext* context,
return GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D);
}
break;
case kRGBA_F32_SkColorType:
return GrBackendFormat();
}
}
break;
@ -199,6 +201,8 @@ static GrBackendFormat create_backend_format(GrContext* context,
return GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_SFLOAT);
}
break;
case kRGBA_F32_SkColorType:
return GrBackendFormat();
}
break;
#endif
@ -267,6 +271,8 @@ static GrBackendFormat create_backend_format(GrContext* context,
return GrBackendFormat::MakeMock(config);
}
break;
case kRGBA_F32_SkColorType:
return GrBackendFormat();
}
break;
default:

View File

@ -104,11 +104,13 @@ DEF_TEST(PictureImageGenerator, reporter) {
{ kRGBA_8888_SkColorType, kPremul_SkAlphaType, kRGBA_8888_SkColorType == kN32_SkColorType },
{ kBGRA_8888_SkColorType, kPremul_SkAlphaType, kBGRA_8888_SkColorType == kN32_SkColorType },
{ kRGBA_F16_SkColorType, kPremul_SkAlphaType, true },
{ kRGBA_F32_SkColorType, kPremul_SkAlphaType, true },
{ kRGBA_1010102_SkColorType, kPremul_SkAlphaType, true },
{ kRGBA_8888_SkColorType, kUnpremul_SkAlphaType, false },
{ kBGRA_8888_SkColorType, kUnpremul_SkAlphaType, false },
{ kRGBA_F16_SkColorType, kUnpremul_SkAlphaType, false },
{ kRGBA_F32_SkColorType, kUnpremul_SkAlphaType, false },
{ kRGBA_1010102_SkColorType, kUnpremul_SkAlphaType, false },
};
@ -118,7 +120,7 @@ DEF_TEST(PictureImageGenerator, reporter) {
SkImage::BitDepth::kU8, colorspace);
// worst case for all requests
SkAutoMalloc storage(100 * 100 * SkColorTypeBytesPerPixel(kRGBA_F16_SkColorType));
SkAutoMalloc storage(100 * 100 * SkColorTypeBytesPerPixel(kRGBA_F32_SkColorType));
for (const auto& rec : recs) {
SkImageInfo info = SkImageInfo::Make(100, 100, rec.fColorType, rec.fAlphaType, colorspace);

View File

@ -894,7 +894,8 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceAttachStencil_Gpu, reporter, ctxInf
static void test_surface_creation_and_snapshot_with_color_space(
skiatest::Reporter* reporter,
const char* prefix,
bool f16Support,
bool supportsF16,
bool supportsF32,
bool supports1010102,
std::function<sk_sp<SkSurface>(const SkImageInfo&)> surfaceMaker) {
@ -914,17 +915,21 @@ static void test_surface_creation_and_snapshot_with_color_space(
bool fShouldWork;
const char* fDescription;
} testConfigs[] = {
{ kN32_SkColorType, nullptr, true, "N32-nullptr" },
{ kN32_SkColorType, linearColorSpace, true, "N32-linear" },
{ kN32_SkColorType, srgbColorSpace, true, "N32-srgb" },
{ kN32_SkColorType, oddColorSpace, true, "N32-odd" },
{ kRGBA_F16_SkColorType, nullptr, true, "F16-nullptr" },
{ kRGBA_F16_SkColorType, linearColorSpace, true, "F16-linear" },
{ kRGBA_F16_SkColorType, srgbColorSpace, true, "F16-srgb" },
{ kRGBA_F16_SkColorType, oddColorSpace, true, "F16-odd" },
{ kRGB_565_SkColorType, srgbColorSpace, false, "565-srgb" },
{ kAlpha_8_SkColorType, srgbColorSpace, false, "A8-srgb" },
{ kRGBA_1010102_SkColorType, nullptr, true, "1010102-nullptr" },
{ kN32_SkColorType, nullptr, true, "N32-nullptr" },
{ kN32_SkColorType, linearColorSpace, true, "N32-linear" },
{ kN32_SkColorType, srgbColorSpace, true, "N32-srgb" },
{ kN32_SkColorType, oddColorSpace, true, "N32-odd" },
{ kRGBA_F16_SkColorType, nullptr, supportsF16, "F16-nullptr" },
{ kRGBA_F16_SkColorType, linearColorSpace, supportsF16, "F16-linear" },
{ kRGBA_F16_SkColorType, srgbColorSpace, supportsF16, "F16-srgb" },
{ kRGBA_F16_SkColorType, oddColorSpace, supportsF16, "F16-odd" },
{ kRGBA_F32_SkColorType, nullptr, supportsF32, "F32-nullptr" },
{ kRGBA_F32_SkColorType, linearColorSpace, supportsF32, "F32-linear" },
{ kRGBA_F32_SkColorType, srgbColorSpace, supportsF32, "F32-srgb" },
{ kRGBA_F32_SkColorType, oddColorSpace, supportsF32, "F32-odd" },
{ kRGB_565_SkColorType, srgbColorSpace, false, "565-srgb" },
{ kAlpha_8_SkColorType, srgbColorSpace, false, "A8-srgb" },
{ kRGBA_1010102_SkColorType, nullptr, supports1010102, "1010102-nullptr" },
};
for (auto& testConfig : testConfigs) {
@ -932,16 +937,11 @@ static void test_surface_creation_and_snapshot_with_color_space(
SkImageInfo info = SkImageInfo::Make(10, 10, testConfig.fColorType, kPremul_SkAlphaType,
testConfig.fColorSpace);
// For some GPU contexts (eg ANGLE), we don't have f16 support, so we should fail to create
// any surface of that type:
bool shouldWork = testConfig.fShouldWork &&
(f16Support || kRGBA_F16_SkColorType != testConfig.fColorType) &&
(supports1010102 || kRGBA_1010102_SkColorType != testConfig.fColorType);
auto surface(surfaceMaker(info));
REPORTER_ASSERT(reporter, SkToBool(surface) == shouldWork, fullTestName.c_str());
REPORTER_ASSERT(reporter,
SkToBool(surface) == testConfig.fShouldWork, fullTestName.c_str());
if (shouldWork && surface) {
if (testConfig.fShouldWork && surface) {
sk_sp<SkImage> image(surface->makeImageSnapshot());
REPORTER_ASSERT(reporter, image, testConfig.fDescription);
SkColorSpace* imageColorSpace = as_IB(image)->onImageInfo().colorSpace();
@ -956,22 +956,25 @@ DEF_TEST(SurfaceCreationWithColorSpace, reporter) {
return SkSurface::MakeRaster(info);
};
test_surface_creation_and_snapshot_with_color_space(reporter, "raster", true, true,
test_surface_creation_and_snapshot_with_color_space(reporter, "raster",
true, true, true,
surfaceMaker);
}
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCreationWithColorSpace_Gpu, reporter, ctxInfo) {
auto context = ctxInfo.grContext();
bool f16Support = context->contextPriv().caps()->isConfigRenderable(kRGBA_half_GrPixelConfig);
bool supports1010102 =
context->contextPriv().caps()->isConfigRenderable(kRGBA_1010102_GrPixelConfig);
bool supportsF16 = context->contextPriv().caps()->isConfigRenderable(kRGBA_half_GrPixelConfig),
supportsF32 = context->contextPriv().caps()->isConfigRenderable(kRGBA_float_GrPixelConfig),
supports1010102 = context->contextPriv().caps()->isConfigRenderable(kRGBA_1010102_GrPixelConfig);
auto surfaceMaker = [context](const SkImageInfo& info) {
return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info);
};
test_surface_creation_and_snapshot_with_color_space(reporter, "gpu", f16Support,
supports1010102, surfaceMaker);
test_surface_creation_and_snapshot_with_color_space(reporter, "gpu",
supportsF16, supportsF32, supports1010102,
surfaceMaker);
std::vector<GrBackendTexture> backendTextures;
auto wrappedSurfaceMaker = [ context, &backendTextures ](const SkImageInfo& info) {
@ -996,8 +999,9 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCreationWithColorSpace_Gpu, reporter,
sk_ref_sp(info.colorSpace()), nullptr);
};
test_surface_creation_and_snapshot_with_color_space(reporter, "wrapped", f16Support,
supports1010102, wrappedSurfaceMaker);
test_surface_creation_and_snapshot_with_color_space(reporter, "wrapped",
supportsF16, supportsF32, supports1010102,
wrappedSurfaceMaker);
context->flush();

View File

@ -55,6 +55,7 @@ const char* colortype_name(SkColorType ct) {
case kRGB_101010x_SkColorType: return "RGB_101010x";
case kGray_8_SkColorType: return "Gray_8";
case kRGBA_F16_SkColorType: return "RGBA_F16";
case kRGBA_F32_SkColorType: return "RGBA_F32";
}
SkASSERT(false);
return "unexpected colortype";