Index: src/core/SkRasterPipelineBlitter.cpp |
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp |
index 9d89b4dcfceeb8cd327c11d8e0b2091cfc0c9993..6518a88fa91ec29ac06c1206c61556594dc33ee9 100644 |
--- a/src/core/SkRasterPipelineBlitter.cpp |
+++ b/src/core/SkRasterPipelineBlitter.cpp |
@@ -8,6 +8,7 @@ |
#include "SkBlitter.h" |
#include "SkColor.h" |
#include "SkColorFilter.h" |
+#include "SkHalf.h" |
#include "SkPM4f.h" |
#include "SkRasterPipeline.h" |
#include "SkShader.h" |
@@ -224,6 +225,59 @@ static void SK_VECTORCALL store_565_1(SkRasterPipeline::Stage* st, size_t x, |
*ptr = to_565(r,g,b)[0]; |
} |
+// Load 4 F16 pixels. |
+static void SK_VECTORCALL load_d_f16(SkRasterPipeline::Stage* st, size_t x, |
+ Sk4f r, Sk4f g, Sk4f b, Sk4f a, |
+ Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { |
+ auto ptr = st->ctx<const uint64_t*>() + x; |
+ |
+ // TODO: This can be made a lot more efficient with platform-specific code. |
+ auto p0 = SkHalfToFloat_finite(ptr[0]), |
+ p1 = SkHalfToFloat_finite(ptr[1]), |
+ p2 = SkHalfToFloat_finite(ptr[2]), |
+ p3 = SkHalfToFloat_finite(ptr[3]); |
+ dr = { p0[0], p1[0], p2[0], p3[0] }; |
+ dg = { p0[1], p1[1], p2[1], p3[1] }; |
+ db = { p0[2], p1[2], p2[2], p3[2] }; |
+ da = { p0[3], p1[3], p2[3], p3[3] }; |
+ |
+ st->next(x, r,g,b,a, dr,dg,db,da); |
+} |
+ |
+// Load 1 F16 pixel. |
+static void SK_VECTORCALL load_d_f16_1(SkRasterPipeline::Stage* st, size_t x, |
+ Sk4f r, Sk4f g, Sk4f b, Sk4f a, |
+ Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { |
+ auto ptr = st->ctx<const uint64_t*>() + x; |
+ |
+ auto p0 = SkHalfToFloat_finite(ptr[0]); |
+ dr = { p0[0],0,0,0 }; |
+ dg = { p0[1],0,0,0 }; |
+ db = { p0[2],0,0,0 }; |
+ da = { p0[3],0,0,0 }; |
+ |
+ st->next(x, r,g,b,a, dr,dg,db,da); |
+} |
+ |
+// Store 4 F16 pixels. |
+static void SK_VECTORCALL store_f16(SkRasterPipeline::Stage* st, size_t x, |
+ Sk4f r, Sk4f g, Sk4f b, Sk4f a, |
+ Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { |
+ auto ptr = st->ctx<uint64_t*>() + x; |
+ |
+ Sk4h_store4(ptr, SkFloatToHalf_finite(r), SkFloatToHalf_finite(g), |
+ SkFloatToHalf_finite(b), SkFloatToHalf_finite(a)); |
+} |
+ |
+// Store 1 F16 pixel. |
+static void SK_VECTORCALL store_f16_1(SkRasterPipeline::Stage* st, size_t x, |
+ Sk4f r, Sk4f g, Sk4f b, Sk4f a, |
+ Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { |
+ auto ptr = st->ctx<uint64_t*>() + x; |
+ |
+ SkFloatToHalf_finite({r[0], g[0], b[0], a[0]}).store(ptr); |
+} |
+ |
// Load 4 8-bit sRGB pixels from SkPMColor order to RGBA. |
static void SK_VECTORCALL load_d_srgb(SkRasterPipeline::Stage* st, size_t x, |
Sk4f r, Sk4f g, Sk4f b, Sk4f a, |
@@ -290,11 +344,11 @@ static void SK_VECTORCALL store_srgb_1(SkRasterPipeline::Stage* st, size_t x, |
} |
static bool supported(const SkImageInfo& info) { |
- // TODO: f16, more? |
switch (info.colorType()) { |
- case kN32_SkColorType: return info.gammaCloseToSRGB(); |
- case kRGB_565_SkColorType: return true; |
- default: return false; |
+ case kN32_SkColorType: return info.gammaCloseToSRGB(); |
+ case kRGBA_F16_SkColorType: return true; |
+ case kRGB_565_SkColorType: return true; |
+ default: return false; |
} |
} |
@@ -323,7 +377,7 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst, |
uint32_t paintColor = paint.getColor(); |
SkColor4f color; |
- if (dst.info().colorSpace()) { |
+ if (SkImageInfoIsGammaCorrect(dst.info())) { |
color = SkColor4f::FromColor(paintColor); |
} else { |
swizzle_rb(SkNx_cast<float>(Sk4b::Load(&paintColor)) * (1/255.0f)).store(&color); |
@@ -353,6 +407,9 @@ void SkRasterPipelineBlitter::append_load_d(SkRasterPipeline* p, const void* dst |
p->append(load_d_srgb, load_d_srgb_1, dst); |
} |
break; |
+ case kRGBA_F16_SkColorType: |
+ p->append(load_d_f16, load_d_f16_1, dst); |
+ break; |
case kRGB_565_SkColorType: |
p->append(load_d_565, load_d_565_1, dst); |
break; |
@@ -370,6 +427,9 @@ void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p, void* dst) const |
p->append(store_srgb, store_srgb_1, dst); |
} |
break; |
+ case kRGBA_F16_SkColorType: |
+ p->append(store_f16, store_f16_1, dst); |
+ break; |
case kRGB_565_SkColorType: |
p->append(store_565, store_565_1, dst); |
break; |