Revert "Use RasterPipeline to support full precision on 16-bit RGBA pngs"

This reverts commit bb2339da39.

Reason for revert: Breaks MSAN

Original change's description:
> Use RasterPipeline to support full precision on 16-bit RGBA pngs
> 
> TODO: Support more precision on 16-bit RGB pngs
> 
> BUG=skia:
> 
> CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD
> 
> Change-Id: I89dfef3b4887b9c4895c17309933883ab90ffa4d
> Reviewed-on: https://skia-review.googlesource.com/6260
> Reviewed-by: Mike Reed <reed@google.com>
> Reviewed-by: Leon Scroggins <scroggo@google.com>
> Reviewed-by: Mike Klein <mtklein@chromium.org>
> Commit-Queue: Matt Sarett <msarett@google.com>
> 

TBR=mtklein@chromium.org,mtklein@google.com,msarett@google.com,scroggo@google.com,reed@google.com,reviews@skia.org
BUG=skia:
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Change-Id: I47579c20af033a75883e2b35567cb9c690ce54b0
Reviewed-on: https://skia-review.googlesource.com/6975
Commit-Queue: Matt Sarett <msarett@google.com>
Reviewed-by: Matt Sarett <msarett@google.com>
This commit is contained in:
Matt Sarett 2017-01-12 21:03:17 +00:00 committed by Skia Commit-Bot
parent 9e937af9bd
commit 25b60833e7
13 changed files with 352 additions and 379 deletions

View File

@ -27,12 +27,8 @@ public:
enum ColorFormat { enum ColorFormat {
kRGBA_8888_ColorFormat, kRGBA_8888_ColorFormat,
kBGRA_8888_ColorFormat, kBGRA_8888_ColorFormat,
kRGBA_F16_ColorFormat,
// Unsigned, big-endian, 16-bit integer kRGBA_F32_ColorFormat,
kRGBA_U16_BE_ColorFormat, // Src only
kRGBA_F16_ColorFormat, // Dst only
kRGBA_F32_ColorFormat, // Dst only
}; };
/** /**
@ -46,6 +42,7 @@ public:
* @param len Number of pixels in the buffers * @param len Number of pixels in the buffers
* @param dstColorFormat Describes color format of |dst| * @param dstColorFormat Describes color format of |dst|
* @param srcColorFormat Describes color format of |src| * @param srcColorFormat Describes color format of |src|
* Must be kRGBA_8888 or kBGRA_8888
* @param alphaType Describes alpha properties of the |dst| (and |src|) * @param alphaType Describes alpha properties of the |dst| (and |src|)
* kUnpremul preserves input alpha values * kUnpremul preserves input alpha values
* kPremul performs a premultiplication and also preserves alpha values * kPremul performs a premultiplication and also preserves alpha values

View File

@ -1 +1 @@
18 17

File diff suppressed because it is too large Load Diff

View File

@ -427,19 +427,8 @@ void SkPngCodec::allocateStorage(const SkImageInfo& dstInfo) {
} }
} }
static SkColorSpaceXform::ColorFormat png_select_xform_format(const SkEncodedInfo& info) {
// We always use kRGBA because color PNGs are always RGB or RGBA.
// TODO (msarett): Support kRGB_U16 inputs as well.
if (16 == info.bitsPerComponent() && SkEncodedInfo::kRGBA_Color == info.color()) {
return SkColorSpaceXform::kRGBA_U16_BE_ColorFormat;
}
return SkColorSpaceXform::kRGBA_8888_ColorFormat;
}
void SkPngCodec::applyXformRow(void* dst, const void* src) { void SkPngCodec::applyXformRow(void* dst, const void* src) {
const SkColorSpaceXform::ColorFormat srcColorFormat = const SkColorSpaceXform::ColorFormat srcColorFormat = select_xform_format(kXformSrcColorType);
png_select_xform_format(this->getEncodedInfo());
switch (fXformMode) { switch (fXformMode) {
case kSwizzleOnly_XformMode: case kSwizzleOnly_XformMode:
fSwizzler->swizzle(dst, (const uint8_t*) src); fSwizzler->swizzle(dst, (const uint8_t*) src);
@ -1086,7 +1075,7 @@ bool SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const Options& opt
// If the image is 32-bit RGBA and we have a color xform, we can skip the swizzler. // If the image is 32-bit RGBA and we have a color xform, we can skip the swizzler.
if (this->colorXform() && SkEncodedInfo::kRGBA_Color == this->getEncodedInfo().color() && if (this->colorXform() && SkEncodedInfo::kRGBA_Color == this->getEncodedInfo().color() &&
!options.fSubset) 8 == this->getEncodedInfo().bitsPerComponent() && !options.fSubset)
{ {
fXformMode = kColorOnly_XformMode; fXformMode = kColorOnly_XformMode;
return true; return true;
@ -1101,7 +1090,7 @@ bool SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const Options& opt
// Copy the color table to the client if they request kIndex8 mode. // Copy the color table to the client if they request kIndex8 mode.
copy_color_table(dstInfo, fColorTable.get(), ctable, ctableCount); copy_color_table(dstInfo, fColorTable.get(), ctable, ctableCount);
this->initializeSwizzler(dstInfo, options, false); this->initializeSwizzler(dstInfo, options);
return true; return true;
} }
@ -1124,8 +1113,7 @@ void SkPngCodec::initializeXformParams() {
} }
} }
void SkPngCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options, void SkPngCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options) {
bool skipFormatConversion) {
SkImageInfo swizzlerInfo = dstInfo; SkImageInfo swizzlerInfo = dstInfo;
Options swizzlerOptions = options; Options swizzlerOptions = options;
fXformMode = kSwizzleOnly_XformMode; fXformMode = kSwizzleOnly_XformMode;
@ -1147,7 +1135,7 @@ void SkPngCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& o
const SkPMColor* colors = get_color_ptr(fColorTable.get()); const SkPMColor* colors = get_color_ptr(fColorTable.get());
fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colors, swizzlerInfo, fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colors, swizzlerInfo,
swizzlerOptions, nullptr, skipFormatConversion)); swizzlerOptions));
SkASSERT(fSwizzler); SkASSERT(fSwizzler);
} }
@ -1156,7 +1144,7 @@ SkSampler* SkPngCodec::getSampler(bool createIfNecessary) {
return fSwizzler.get(); return fSwizzler.get();
} }
this->initializeSwizzler(this->dstInfo(), this->options(), true); this->initializeSwizzler(this->dstInfo(), this->options());
return fSwizzler.get(); return fSwizzler.get();
} }

View File

@ -119,7 +119,7 @@ private:
// Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info. // Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
bool initializeXforms(const SkImageInfo& dstInfo, const Options&, SkPMColor* colorPtr, bool initializeXforms(const SkImageInfo& dstInfo, const Options&, SkPMColor* colorPtr,
int* colorCount); int* colorCount);
void initializeSwizzler(const SkImageInfo& dstInfo, const Options&, bool skipFormatConversion); void initializeSwizzler(const SkImageInfo& dstInfo, const Options&);
void allocateStorage(const SkImageInfo& dstInfo); void allocateStorage(const SkImageInfo& dstInfo);
void destroyReadStruct(); void destroyReadStruct();

View File

@ -51,16 +51,6 @@ static void sample4(void* dst, const uint8_t* src, int width, int bpp, int delta
} }
} }
static void sample8(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
const SkPMColor ctable[]) {
src += offset;
uint64_t* dst64 = (uint64_t*) dst;
for (int x = 0; x < width; x++) {
dst64[x] = *((const uint64_t*) src);
src += deltaSrc;
}
}
// kBit // kBit
// These routines exclusively choose between white and black // These routines exclusively choose between white and black
@ -818,9 +808,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
break; break;
case kRGBA_8888_SkColorType: case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType: case kBGRA_8888_SkColorType:
SkASSERT(16 == encodedInfo.bitsPerComponent() || proc = &sample4;
8 == encodedInfo.bitsPerComponent());
proc = (8 == encodedInfo.bitsPerComponent()) ? &sample4 : &sample8;
fastProc = &copy; fastProc = &copy;
break; break;
default: default:

View File

@ -327,14 +327,110 @@ std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace
switch (csm) { switch (csm) {
case kNone_ColorSpaceMatch: case kNone_ColorSpaceMatch:
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ switch (dstSpaceXYZ->gammaNamed()) {
<kNone_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ)); case kSRGB_SkGammaNamed:
if (srcSpaceXYZ->gammaIsLinear()) {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
} else {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
}
case k2Dot2Curve_SkGammaNamed:
if (srcSpaceXYZ->gammaIsLinear()) {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
} else {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
}
case kLinear_SkGammaNamed:
if (srcSpaceXYZ->gammaIsLinear()) {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
} else {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
}
default:
if (srcSpaceXYZ->gammaIsLinear()) {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
} else {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
}
}
case kGamut_ColorSpaceMatch: case kGamut_ColorSpaceMatch:
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ switch (dstSpaceXYZ->gammaNamed()) {
<kGamut_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ)); case kSRGB_SkGammaNamed:
if (srcSpaceXYZ->gammaIsLinear()) {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
} else {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
}
case k2Dot2Curve_SkGammaNamed:
if (srcSpaceXYZ->gammaIsLinear()) {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
} else {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
}
case kLinear_SkGammaNamed:
if (srcSpaceXYZ->gammaIsLinear()) {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
} else {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
}
default:
if (srcSpaceXYZ->gammaIsLinear()) {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
} else {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
}
}
case kFull_ColorSpaceMatch: case kFull_ColorSpaceMatch:
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ switch (dstSpaceXYZ->gammaNamed()) {
<kFull_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ)); case kSRGB_SkGammaNamed:
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kSRGB_DstGamma, kFull_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
case k2Dot2Curve_SkGammaNamed:
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, k2Dot2_DstGamma, kFull_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
case kLinear_SkGammaNamed:
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kLinear_DstGamma, kFull_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
default:
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kTable_DstGamma, kFull_ColorSpaceMatch>
(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
}
default: default:
SkASSERT(false); SkASSERT(false);
return nullptr; return nullptr;
@ -969,8 +1065,8 @@ static AI int num_tables(SkColorSpace_XYZ* space) {
} }
} }
template <ColorSpaceMatch kCSM> template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
SkColorSpaceXform_XYZ<kCSM> SkColorSpaceXform_XYZ<kSrc, kDst, kCSM>
::SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst, ::SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst,
SkColorSpace_XYZ* dstSpace) SkColorSpace_XYZ* dstSpace)
{ {
@ -997,29 +1093,6 @@ SkColorSpaceXform_XYZ<kCSM>
const int numDstTables = num_tables(dstSpace); const int numDstTables = num_tables(dstSpace);
dstSpace->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables); dstSpace->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables);
if (srcSpace->gammaIsLinear()) {
fSrcGamma = kLinear_SrcGamma;
} else if (kSRGB_SkGammaNamed == srcSpace->gammaNamed()) {
fSrcGamma = kSRGB_SrcGamma;
} else {
fSrcGamma = kTable_SrcGamma;
}
switch (dstSpace->gammaNamed()) {
case kSRGB_SkGammaNamed:
fDstGamma = kSRGB_DstGamma;
break;
case k2Dot2Curve_SkGammaNamed:
fDstGamma = k2Dot2_DstGamma;
break;
case kLinear_SkGammaNamed:
fDstGamma = kLinear_DstGamma;
break;
default:
fDstGamma = kTable_DstGamma;
break;
}
} }
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@ -1046,28 +1119,27 @@ static AI bool apply_set_alpha(void* dst, const void* src, int len, SkAlphaType
} }
} }
template <DstFormat kDst, ColorSpaceMatch kCSM> template <SrcGamma kSrc, DstFormat kDst, ColorSpaceMatch kCSM>
static AI bool apply_set_src(void* dst, const void* src, int len, SkAlphaType alphaType, static AI bool apply_set_src(void* dst, const void* src, int len, SkAlphaType alphaType,
const float* const srcTables[3], const float matrix[13], const float* const srcTables[3], const float matrix[13],
const uint8_t* const dstTables[3], const uint8_t* const dstTables[3],
SkColorSpaceXform::ColorFormat srcColorFormat, SkColorSpaceXform::ColorFormat srcColorFormat) {
SrcGamma srcGamma) {
switch (srcColorFormat) { switch (srcColorFormat) {
case SkColorSpaceXform::kRGBA_8888_ColorFormat: case SkColorSpaceXform::kRGBA_8888_ColorFormat:
switch (srcGamma) { switch (kSrc) {
case kLinear_SrcGamma: case kLinear_SrcGamma:
return apply_set_alpha<kRGBA_8888_Linear_SrcFormat, kDst, kCSM> return apply_set_alpha<kRGBA_8888_Linear_SrcFormat, kDst, kCSM>
(dst, src, len, alphaType, nullptr, matrix, dstTables); (dst, src, len, alphaType, nullptr, matrix, dstTables);
default: case kTable_SrcGamma:
return apply_set_alpha<kRGBA_8888_Table_SrcFormat, kDst, kCSM> return apply_set_alpha<kRGBA_8888_Table_SrcFormat, kDst, kCSM>
(dst, src, len, alphaType, srcTables, matrix, dstTables); (dst, src, len, alphaType, srcTables, matrix, dstTables);
} }
case SkColorSpaceXform::kBGRA_8888_ColorFormat: case SkColorSpaceXform::kBGRA_8888_ColorFormat:
switch (srcGamma) { switch (kSrc) {
case kLinear_SrcGamma: case kLinear_SrcGamma:
return apply_set_alpha<kBGRA_8888_Linear_SrcFormat, kDst, kCSM> return apply_set_alpha<kBGRA_8888_Linear_SrcFormat, kDst, kCSM>
(dst, src, len, alphaType, nullptr, matrix, dstTables); (dst, src, len, alphaType, nullptr, matrix, dstTables);
default: case kTable_SrcGamma:
return apply_set_alpha<kBGRA_8888_Table_SrcFormat, kDst, kCSM> return apply_set_alpha<kBGRA_8888_Table_SrcFormat, kDst, kCSM>
(dst, src, len, alphaType, srcTables, matrix, dstTables); (dst, src, len, alphaType, srcTables, matrix, dstTables);
} }
@ -1078,8 +1150,8 @@ static AI bool apply_set_src(void* dst, const void* src, int len, SkAlphaType al
#undef AI #undef AI
template <ColorSpaceMatch kCSM> template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
bool SkColorSpaceXform_XYZ<kCSM> bool SkColorSpaceXform_XYZ<kSrc, kDst, kCSM>
::onApply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, const void* src, ::onApply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, const void* src,
int len, SkAlphaType alphaType) const int len, SkAlphaType alphaType) const
{ {
@ -1104,55 +1176,55 @@ bool SkColorSpaceXform_XYZ<kCSM>
} }
} }
if (kRGBA_F32_ColorFormat == dstColorFormat || kRGBA_U16_BE_ColorFormat == srcColorFormat) { if (kRGBA_F32_ColorFormat == dstColorFormat) {
return this->applyPipeline(dstColorFormat, dst, srcColorFormat, src, len, alphaType); return this->applyPipeline(dstColorFormat, dst, srcColorFormat, src, len, alphaType);
} }
switch (dstColorFormat) { switch (dstColorFormat) {
case kRGBA_8888_ColorFormat: case kRGBA_8888_ColorFormat:
switch (fDstGamma) { switch (kDst) {
case kLinear_DstGamma: case kLinear_DstGamma:
return apply_set_src<kRGBA_8888_Linear_DstFormat, kCSM> return apply_set_src<kSrc, kRGBA_8888_Linear_DstFormat, kCSM>
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr,
srcColorFormat, fSrcGamma); srcColorFormat);
case kSRGB_DstGamma: case kSRGB_DstGamma:
return apply_set_src<kRGBA_8888_SRGB_DstFormat, kCSM> return apply_set_src<kSrc, kRGBA_8888_SRGB_DstFormat, kCSM>
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr,
srcColorFormat, fSrcGamma); srcColorFormat);
case k2Dot2_DstGamma: case k2Dot2_DstGamma:
return apply_set_src<kRGBA_8888_2Dot2_DstFormat, kCSM> return apply_set_src<kSrc, kRGBA_8888_2Dot2_DstFormat, kCSM>
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr,
srcColorFormat, fSrcGamma); srcColorFormat);
case kTable_DstGamma: case kTable_DstGamma:
return apply_set_src<kRGBA_8888_Table_DstFormat, kCSM> return apply_set_src<kSrc, kRGBA_8888_Table_DstFormat, kCSM>
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables, (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables,
srcColorFormat, fSrcGamma); srcColorFormat);
} }
case kBGRA_8888_ColorFormat: case kBGRA_8888_ColorFormat:
switch (fDstGamma) { switch (kDst) {
case kLinear_DstGamma: case kLinear_DstGamma:
return apply_set_src<kBGRA_8888_Linear_DstFormat, kCSM> return apply_set_src<kSrc, kBGRA_8888_Linear_DstFormat, kCSM>
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr,
srcColorFormat, fSrcGamma); srcColorFormat);
case kSRGB_DstGamma: case kSRGB_DstGamma:
return apply_set_src<kBGRA_8888_SRGB_DstFormat, kCSM> return apply_set_src<kSrc, kBGRA_8888_SRGB_DstFormat, kCSM>
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr,
srcColorFormat, fSrcGamma); srcColorFormat);
case k2Dot2_DstGamma: case k2Dot2_DstGamma:
return apply_set_src<kBGRA_8888_2Dot2_DstFormat, kCSM> return apply_set_src<kSrc, kBGRA_8888_2Dot2_DstFormat, kCSM>
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr,
srcColorFormat, fSrcGamma); srcColorFormat);
case kTable_DstGamma: case kTable_DstGamma:
return apply_set_src<kBGRA_8888_Table_DstFormat, kCSM> return apply_set_src<kSrc, kBGRA_8888_Table_DstFormat, kCSM>
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables, (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables,
srcColorFormat, fSrcGamma); srcColorFormat);
} }
case kRGBA_F16_ColorFormat: case kRGBA_F16_ColorFormat:
switch (fDstGamma) { switch (kDst) {
case kLinear_DstGamma: case kLinear_DstGamma:
return apply_set_src<kF16_Linear_DstFormat, kCSM> return apply_set_src<kSrc, kF16_Linear_DstFormat, kCSM>
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr,
srcColorFormat, fSrcGamma); srcColorFormat);
default: default:
return false; return false;
} }
@ -1170,8 +1242,8 @@ bool SkColorSpaceXform::apply(ColorFormat dstColorFormat, void* dst, ColorFormat
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
template <ColorSpaceMatch kCSM> template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
bool SkColorSpaceXform_XYZ<kCSM> bool SkColorSpaceXform_XYZ<kSrc, kDst, kCSM>
::applyPipeline(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, ::applyPipeline(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat,
const void* src, int len, SkAlphaType alphaType) const { const void* src, int len, SkAlphaType alphaType) const {
SkRasterPipeline pipeline; SkRasterPipeline pipeline;
@ -1179,10 +1251,10 @@ bool SkColorSpaceXform_XYZ<kCSM>
LoadTablesContext loadTables; LoadTablesContext loadTables;
switch (srcColorFormat) { switch (srcColorFormat) {
case kRGBA_8888_ColorFormat: case kRGBA_8888_ColorFormat:
if (kLinear_SrcGamma == fSrcGamma) { if (kLinear_SrcGamma == kSrc) {
pipeline.append(SkRasterPipeline::load_8888, &src); pipeline.append(SkRasterPipeline::load_8888, &src);
} else { } else {
loadTables.fSrc = src; loadTables.fSrc = (const uint32_t*) src;
loadTables.fR = fSrcGammaTables[0]; loadTables.fR = fSrcGammaTables[0];
loadTables.fG = fSrcGammaTables[1]; loadTables.fG = fSrcGammaTables[1];
loadTables.fB = fSrcGammaTables[2]; loadTables.fB = fSrcGammaTables[2];
@ -1191,10 +1263,10 @@ bool SkColorSpaceXform_XYZ<kCSM>
break; break;
case kBGRA_8888_ColorFormat: case kBGRA_8888_ColorFormat:
if (kLinear_SrcGamma == fSrcGamma) { if (kLinear_SrcGamma == kSrc) {
pipeline.append(SkRasterPipeline::load_8888, &src); pipeline.append(SkRasterPipeline::load_8888, &src);
} else { } else {
loadTables.fSrc = src; loadTables.fSrc = (const uint32_t*) src;
loadTables.fR = fSrcGammaTables[2]; loadTables.fR = fSrcGammaTables[2];
loadTables.fG = fSrcGammaTables[1]; loadTables.fG = fSrcGammaTables[1];
loadTables.fB = fSrcGammaTables[0]; loadTables.fB = fSrcGammaTables[0];
@ -1203,24 +1275,6 @@ bool SkColorSpaceXform_XYZ<kCSM>
pipeline.append(SkRasterPipeline::swap_rb); pipeline.append(SkRasterPipeline::swap_rb);
break; break;
case kRGBA_U16_BE_ColorFormat:
switch (fSrcGamma) {
case kLinear_SrcGamma:
pipeline.append(SkRasterPipeline::load_u16_be, &src);
break;
case kSRGB_SrcGamma:
pipeline.append(SkRasterPipeline::load_u16_be, &src);
pipeline.append_from_srgb(kUnpremul_SkAlphaType);
break;
case kTable_SrcGamma:
loadTables.fSrc = src;
loadTables.fR = fSrcGammaTables[0];
loadTables.fG = fSrcGammaTables[1];
loadTables.fB = fSrcGammaTables[2];
pipeline.append(SkRasterPipeline::load_tables_u16_be, &loadTables);
break;
}
break;
default: default:
return false; return false;
} }
@ -1242,7 +1296,7 @@ bool SkColorSpaceXform_XYZ<kCSM>
} }
StoreTablesContext storeTables; StoreTablesContext storeTables;
switch (fDstGamma) { switch (kDst) {
case kSRGB_DstGamma: case kSRGB_DstGamma:
pipeline.append(SkRasterPipeline::to_srgb); pipeline.append(SkRasterPipeline::to_srgb);
break; break;
@ -1255,7 +1309,7 @@ bool SkColorSpaceXform_XYZ<kCSM>
switch (dstColorFormat) { switch (dstColorFormat) {
case kRGBA_8888_ColorFormat: case kRGBA_8888_ColorFormat:
if (kTable_DstGamma == fDstGamma) { if (kTable_DstGamma == kDst) {
storeTables.fDst = (uint32_t*) dst; storeTables.fDst = (uint32_t*) dst;
storeTables.fR = fDstGammaTables[0]; storeTables.fR = fDstGammaTables[0];
storeTables.fG = fDstGammaTables[1]; storeTables.fG = fDstGammaTables[1];
@ -1267,7 +1321,7 @@ bool SkColorSpaceXform_XYZ<kCSM>
} }
break; break;
case kBGRA_8888_ColorFormat: case kBGRA_8888_ColorFormat:
if (kTable_DstGamma == fDstGamma) { if (kTable_DstGamma == kDst) {
storeTables.fDst = (uint32_t*) dst; storeTables.fDst = (uint32_t*) dst;
storeTables.fR = fDstGammaTables[2]; storeTables.fR = fDstGammaTables[2];
storeTables.fG = fDstGammaTables[1]; storeTables.fG = fDstGammaTables[1];
@ -1281,19 +1335,17 @@ bool SkColorSpaceXform_XYZ<kCSM>
} }
break; break;
case kRGBA_F16_ColorFormat: case kRGBA_F16_ColorFormat:
if (kLinear_DstGamma != fDstGamma) { if (kLinear_DstGamma != kDst) {
return false; return false;
} }
pipeline.append(SkRasterPipeline::store_f16, &dst); pipeline.append(SkRasterPipeline::store_f16, &dst);
break; break;
case kRGBA_F32_ColorFormat: case kRGBA_F32_ColorFormat:
if (kLinear_DstGamma != fDstGamma) { if (kLinear_DstGamma != kDst) {
return false; return false;
} }
pipeline.append(SkRasterPipeline::store_f32, &dst); pipeline.append(SkRasterPipeline::store_f32, &dst);
break; break;
default:
return false;
} }
pipeline.run(0, 0, len); pipeline.run(0, 0, len);
@ -1304,5 +1356,6 @@ bool SkColorSpaceXform_XYZ<kCSM>
std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space) { std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space) {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kNone_ColorSpaceMatch>(space, SkMatrix::I(), space)); <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
(space, SkMatrix::I(), space));
} }

View File

@ -32,9 +32,6 @@ bool SkColorSpaceXform_A2B::onApply(ColorFormat dstFormat, void* dst, ColorForma
case kRGBA_8888_ColorFormat: case kRGBA_8888_ColorFormat:
pipeline.append(SkRasterPipeline::load_8888, &src); pipeline.append(SkRasterPipeline::load_8888, &src);
break; break;
case kRGBA_U16_BE_ColorFormat:
pipeline.append(SkRasterPipeline::load_u16_be, &src);
break;
default: default:
SkCSXformPrintf("F16/F32 source color format not supported\n"); SkCSXformPrintf("F16/F32 source color format not supported\n");
return false; return false;
@ -66,8 +63,6 @@ bool SkColorSpaceXform_A2B::onApply(ColorFormat dstFormat, void* dst, ColorForma
} }
pipeline.append(SkRasterPipeline::store_f32, &dst); pipeline.append(SkRasterPipeline::store_f32, &dst);
break; break;
default:
return false;
} }
pipeline.run(0,0, count); pipeline.run(0,0, count);

View File

@ -34,7 +34,6 @@ private:
enum SrcGamma { enum SrcGamma {
kLinear_SrcGamma, kLinear_SrcGamma,
kTable_SrcGamma, kTable_SrcGamma,
kSRGB_SrcGamma,
}; };
enum DstGamma { enum DstGamma {
@ -50,7 +49,7 @@ enum ColorSpaceMatch {
kFull_ColorSpaceMatch, kFull_ColorSpaceMatch,
}; };
template <ColorSpaceMatch kCSM> template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
class SkColorSpaceXform_XYZ : public SkColorSpaceXform_Base { class SkColorSpaceXform_XYZ : public SkColorSpaceXform_Base {
protected: protected:
bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src, bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src,
@ -64,26 +63,23 @@ private:
SkColorSpace_XYZ* dstSpace); SkColorSpace_XYZ* dstSpace);
// Contain pointers into storage or pointers into precomputed tables. // Contain pointers into storage or pointers into precomputed tables.
const float* fSrcGammaTables[3]; const float* fSrcGammaTables[3];
SkAutoTMalloc<float> fSrcStorage; SkAutoTMalloc<float> fSrcStorage;
const uint8_t* fDstGammaTables[3]; const uint8_t* fDstGammaTables[3];
sk_sp<SkData> fDstStorage; sk_sp<SkData> fDstStorage;
// Holds a 3x4 matrix. Padding is useful for vector loading. // Holds a 3x4 matrix. Padding is useful for vector loading.
float fSrcToDst[13]; float fSrcToDst[13];
SrcGamma fSrcGamma;
DstGamma fDstGamma;
friend class SkColorSpaceXform; friend class SkColorSpaceXform;
friend std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space); friend std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space);
}; };
struct LoadTablesContext { struct LoadTablesContext {
const void* fSrc; const uint32_t* fSrc;
const float* fR; const float* fR;
const float* fG; const float* fG;
const float* fB; const float* fB;
}; };
struct StoreTablesContext { struct StoreTablesContext {

View File

@ -68,8 +68,7 @@
M(load_565) M(store_565) \ M(load_565) M(store_565) \
M(load_f16) M(store_f16) \ M(load_f16) M(store_f16) \
M(load_8888) M(store_8888) \ M(load_8888) M(store_8888) \
M(load_u16_be) \ M(load_tables) M(store_tables) \
M(load_tables) M(load_tables_u16_be) M(store_tables) \
M(scale_u8) M(scale_1_float) \ M(scale_u8) M(scale_1_float) \
M(lerp_u8) M(lerp_565) M(lerp_1_float) \ M(lerp_u8) M(lerp_565) M(lerp_1_float) \
M(dstatop) M(dstin) M(dstout) M(dstover) \ M(dstatop) M(dstin) M(dstout) M(dstover) \

View File

@ -255,8 +255,6 @@ public:
AI SkNx operator + (const SkNx& o) const { return vadd_u16(fVec, o.fVec); } AI SkNx operator + (const SkNx& o) const { return vadd_u16(fVec, o.fVec); }
AI SkNx operator - (const SkNx& o) const { return vsub_u16(fVec, o.fVec); } AI SkNx operator - (const SkNx& o) const { return vsub_u16(fVec, o.fVec); }
AI SkNx operator * (const SkNx& o) const { return vmul_u16(fVec, o.fVec); } AI SkNx operator * (const SkNx& o) const { return vmul_u16(fVec, o.fVec); }
AI SkNx operator & (const SkNx& o) const { return vand_u16(fVec, o.fVec); }
AI SkNx operator | (const SkNx& o) const { return vorr_u16(fVec, o.fVec); }
AI SkNx operator << (int bits) const { return fVec << SkNx(bits).fVec; } AI SkNx operator << (int bits) const { return fVec << SkNx(bits).fVec; }
AI SkNx operator >> (int bits) const { return fVec >> SkNx(bits).fVec; } AI SkNx operator >> (int bits) const { return fVec >> SkNx(bits).fVec; }
@ -295,8 +293,6 @@ public:
AI SkNx operator + (const SkNx& o) const { return vaddq_u16(fVec, o.fVec); } AI SkNx operator + (const SkNx& o) const { return vaddq_u16(fVec, o.fVec); }
AI SkNx operator - (const SkNx& o) const { return vsubq_u16(fVec, o.fVec); } AI SkNx operator - (const SkNx& o) const { return vsubq_u16(fVec, o.fVec); }
AI SkNx operator * (const SkNx& o) const { return vmulq_u16(fVec, o.fVec); } AI SkNx operator * (const SkNx& o) const { return vmulq_u16(fVec, o.fVec); }
AI SkNx operator & (const SkNx& o) const { return vandq_u16(fVec, o.fVec); }
AI SkNx operator | (const SkNx& o) const { return vorrq_u16(fVec, o.fVec); }
AI SkNx operator << (int bits) const { return fVec << SkNx(bits).fVec; } AI SkNx operator << (int bits) const { return fVec << SkNx(bits).fVec; }
AI SkNx operator >> (int bits) const { return fVec >> SkNx(bits).fVec; } AI SkNx operator >> (int bits) const { return fVec >> SkNx(bits).fVec; }

View File

@ -283,8 +283,6 @@ public:
AI SkNx operator + (const SkNx& o) const { return _mm_add_epi16(fVec, o.fVec); } AI SkNx operator + (const SkNx& o) const { return _mm_add_epi16(fVec, o.fVec); }
AI SkNx operator - (const SkNx& o) const { return _mm_sub_epi16(fVec, o.fVec); } AI SkNx operator - (const SkNx& o) const { return _mm_sub_epi16(fVec, o.fVec); }
AI SkNx operator * (const SkNx& o) const { return _mm_mullo_epi16(fVec, o.fVec); } AI SkNx operator * (const SkNx& o) const { return _mm_mullo_epi16(fVec, o.fVec); }
AI SkNx operator & (const SkNx& o) const { return _mm_and_si128(fVec, o.fVec); }
AI SkNx operator | (const SkNx& o) const { return _mm_or_si128(fVec, o.fVec); }
AI SkNx operator << (int bits) const { return _mm_slli_epi16(fVec, bits); } AI SkNx operator << (int bits) const { return _mm_slli_epi16(fVec, bits); }
AI SkNx operator >> (int bits) const { return _mm_srli_epi16(fVec, bits); } AI SkNx operator >> (int bits) const { return _mm_srli_epi16(fVec, bits); }
@ -350,8 +348,6 @@ public:
AI SkNx operator + (const SkNx& o) const { return _mm_add_epi16(fVec, o.fVec); } AI SkNx operator + (const SkNx& o) const { return _mm_add_epi16(fVec, o.fVec); }
AI SkNx operator - (const SkNx& o) const { return _mm_sub_epi16(fVec, o.fVec); } AI SkNx operator - (const SkNx& o) const { return _mm_sub_epi16(fVec, o.fVec); }
AI SkNx operator * (const SkNx& o) const { return _mm_mullo_epi16(fVec, o.fVec); } AI SkNx operator * (const SkNx& o) const { return _mm_mullo_epi16(fVec, o.fVec); }
AI SkNx operator & (const SkNx& o) const { return _mm_and_si128(fVec, o.fVec); }
AI SkNx operator | (const SkNx& o) const { return _mm_or_si128(fVec, o.fVec); }
AI SkNx operator << (int bits) const { return _mm_slli_epi16(fVec, bits); } AI SkNx operator << (int bits) const { return _mm_slli_epi16(fVec, bits); }
AI SkNx operator >> (int bits) const { return _mm_srli_epi16(fVec, bits); } AI SkNx operator >> (int bits) const { return _mm_srli_epi16(fVec, bits); }
@ -638,14 +634,6 @@ public:
return _mm256_cvtepi32_ps(SkNx_cast<int>(src).fVec); return _mm256_cvtepi32_ps(SkNx_cast<int>(src).fVec);
} }
template<> AI /*static*/ Sk8i SkNx_cast<int>(const Sk8h& src) {
return _mm256_cvtepu16_epi32(src.fVec);
}
template<> AI /*static*/ Sk8f SkNx_cast<float>(const Sk8h& src) {
return _mm256_cvtepi32_ps(SkNx_cast<int>(src).fVec);
}
template<> AI /*static*/ Sk8f SkNx_cast<float>(const Sk8i& src) { template<> AI /*static*/ Sk8f SkNx_cast<float>(const Sk8i& src) {
return _mm256_cvtepi32_ps(src.fVec); return _mm256_cvtepi32_ps(src.fVec);
} }
@ -654,6 +642,9 @@ public:
return _mm256_cvttps_epi32(src.fVec); return _mm256_cvttps_epi32(src.fVec);
} }
template<> AI /*static*/ Sk8i SkNx_cast<int>(const Sk8h& src) {
return _mm256_cvtepu16_epi32(src.fVec);
}
template<> AI /*static*/ Sk8h SkNx_cast<uint16_t>(const Sk8i& src) { template<> AI /*static*/ Sk8h SkNx_cast<uint16_t>(const Sk8i& src) {
__m128i lo = _mm256_extractf128_si256(src.fVec, 0), __m128i lo = _mm256_extractf128_si256(src.fVec, 0),
hi = _mm256_extractf128_si256(src.fVec, 1); hi = _mm256_extractf128_si256(src.fVec, 1);

View File

@ -564,25 +564,8 @@ STAGE_CTX(store_8888, uint32_t**) {
store(tail, byte(r,0)|byte(g,1)|byte(b,2)|byte(a,3), (int*)ptr); store(tail, byte(r,0)|byte(g,1)|byte(b,2)|byte(a,3), (int*)ptr);
} }
STAGE_CTX(load_u16_be, const uint64_t**) {
auto ptr = *ctx + x;
const void* src = ptr;
SkNx<N, uint64_t> px;
if (tail) {
px = load(tail, ptr);
src = &px;
}
SkNh rh, gh, bh, ah;
SkNh::Load4(src, &rh, &gh, &bh, &ah);
r = (1.0f / 65535.0f) * SkNx_cast<float>((rh << 8) | (rh >> 8));
g = (1.0f / 65535.0f) * SkNx_cast<float>((gh << 8) | (gh >> 8));
b = (1.0f / 65535.0f) * SkNx_cast<float>((bh << 8) | (bh >> 8));
a = (1.0f / 65535.0f) * SkNx_cast<float>((ah << 8) | (ah >> 8));
}
STAGE_CTX(load_tables, const LoadTablesContext*) { STAGE_CTX(load_tables, const LoadTablesContext*) {
auto ptr = (const uint32_t*)ctx->fSrc + x; auto ptr = ctx->fSrc + x;
SkNu rgba = load(tail, ptr); SkNu rgba = load(tail, ptr);
auto to_int = [](const SkNu& v) { return SkNi::Load(&v); }; auto to_int = [](const SkNu& v) { return SkNi::Load(&v); };
@ -592,19 +575,6 @@ STAGE_CTX(load_tables, const LoadTablesContext*) {
a = SkNf_from_byte(rgba >> 24); a = SkNf_from_byte(rgba >> 24);
} }
STAGE_CTX(load_tables_u16_be, const LoadTablesContext*) {
auto ptr = (const uint64_t*)ctx->fSrc + x;
SkNh rh, gh, bh, ah;
SkNh::Load4(ptr, &rh, &gh, &bh, &ah);
// ctx->fSrc is big-endian, so "& 0xff" grabs the 8 most significant bits of each component.
r = gather(tail, ctx->fR, SkNx_cast<int>(rh & 0xff));
g = gather(tail, ctx->fG, SkNx_cast<int>(gh & 0xff));
b = gather(tail, ctx->fB, SkNx_cast<int>(bh & 0xff));
a = (1.0f / 65535.0f) * SkNx_cast<float>((ah << 8) | (ah >> 8));
}
STAGE_CTX(store_tables, const StoreTablesContext*) { STAGE_CTX(store_tables, const StoreTablesContext*) {
auto ptr = ctx->fDst + x; auto ptr = ctx->fDst + x;