aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2016-10-16 10:20:41 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-10-16 14:51:57 +0000
commitf489886915034093278353d06c6f1973b2e8b7d2 (patch)
tree284181b7f901cd0ac47ed0e52df17cc64a86fb49 /src
parent24a865c2c048faa615fcdde3b209a9c10a9be923 (diff)
Cache dst LUTs in SkColorSpaceXform
This is only useful in the rare case that the dst does not fall into one of our main paths. But it's a good optimization, since this does happen, and typically, the dst won't change. ColorCodecBench z620 --nonstd --xform_only Without Patch 511us With Patch 348us BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3400 Change-Id: Ibf68d9ce7072680465662922f4aa15630545e3d6 Reviewed-on: https://skia-review.googlesource.com/3400 Reviewed-by: Mike Klein <mtklein@chromium.org> Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Matt Sarett <msarett@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/SkColorSpace.cpp18
-rw-r--r--src/core/SkColorSpaceXform.cpp86
-rw-r--r--src/core/SkColorSpaceXform_Base.h29
-rw-r--r--src/core/SkColorSpace_Base.h20
4 files changed, 100 insertions, 53 deletions
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
index bdef5b3b75..b956c7fe3e 100644
--- a/src/core/SkColorSpace.cpp
+++ b/src/core/SkColorSpace.cpp
@@ -8,6 +8,7 @@
#include "SkColorSpace.h"
#include "SkColorSpace_Base.h"
#include "SkColorSpacePriv.h"
+#include "SkColorSpaceXform_Base.h"
#include "SkOnce.h"
#include "SkPoint3.h"
@@ -319,6 +320,23 @@ const SkMatrix44& SkColorSpace_Base::fromXYZD50() const {
return fFromXYZD50;
}
+void SkColorSpace_Base::toDstGammaTables(const uint8_t* tables[3], sk_sp<SkData>* storage,
+ int numTables) const {
+ fToDstGammaOnce([this, numTables] {
+ const bool gammasAreMatching = numTables <= 1;
+ fDstStorage =
+ SkData::MakeUninitialized(numTables * SkColorSpaceXform_Base::kDstGammaTableSize);
+ SkColorSpaceXform_Base::BuildDstGammaTables(fToDstGammaTables,
+ (uint8_t*) fDstStorage->writable_data(), this,
+ gammasAreMatching);
+ });
+
+ *storage = fDstStorage;
+ tables[0] = fToDstGammaTables[0];
+ tables[1] = fToDstGammaTables[1];
+ tables[2] = fToDstGammaTables[2];
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////
enum Version {
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp
index 50cd9c11e5..5e362464b4 100644
--- a/src/core/SkColorSpaceXform.cpp
+++ b/src/core/SkColorSpaceXform.cpp
@@ -138,9 +138,7 @@ static uint8_t clamp_normalized_float_to_byte(float v) {
}
}
-static const int kDstGammaTableSize =
- SkColorSpaceXform_Base<kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
- ::kDstGammaTableSize;
+static const int kDstGammaTableSize = SkColorSpaceXform_Base::kDstGammaTableSize;
static void build_table_linear_to_gamma(uint8_t* outTable, float exponent) {
float toGammaExp = 1.0f / exponent;
@@ -256,7 +254,8 @@ static const GammaFns<uint8_t> kFromLinear {
// Build tables to transform src gamma to linear.
template <typename T>
static void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage, int gammaTableSize,
- SkColorSpace* space, const GammaFns<T>& fns, bool gammasAreMatching)
+ const SkColorSpace* space, const GammaFns<T>& fns,
+ bool gammasAreMatching)
{
switch (as_CSB(space)->gammaNamed()) {
case kSRGB_SkGammaNamed:
@@ -326,6 +325,13 @@ static void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage,
}
}
+void SkColorSpaceXform_Base::BuildDstGammaTables(const uint8_t* dstGammaTables[3],
+ uint8_t* dstStorage, const SkColorSpace* space,
+ bool gammasAreMatching) {
+ build_gamma_tables(dstGammaTables, dstStorage, kDstGammaTableSize, space, kFromLinear,
+ gammasAreMatching);
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////
static inline bool is_almost_identity(const SkMatrix44& srcToDst) {
@@ -368,41 +374,41 @@ std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace
switch (as_CSB(dstSpace)->gammaNamed()) {
case kSRGB_SkGammaNamed:
if (srcSpace->gammaIsLinear()) {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
} else {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
}
case k2Dot2Curve_SkGammaNamed:
if (srcSpace->gammaIsLinear()) {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
} else {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
}
case kLinear_SkGammaNamed:
if (srcSpace->gammaIsLinear()) {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
} else {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
}
default:
if (srcSpace->gammaIsLinear()) {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
} else {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
}
@@ -411,41 +417,41 @@ std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace
switch (as_CSB(dstSpace)->gammaNamed()) {
case kSRGB_SkGammaNamed:
if (srcSpace->gammaIsLinear()) {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
} else {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
}
case k2Dot2Curve_SkGammaNamed:
if (srcSpace->gammaIsLinear()) {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
} else {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
}
case kLinear_SkGammaNamed:
if (srcSpace->gammaIsLinear()) {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
} else {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
}
default:
if (srcSpace->gammaIsLinear()) {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
} else {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
}
@@ -453,19 +459,19 @@ std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace
case kFull_ColorSpaceMatch:
switch (as_CSB(dstSpace)->gammaNamed()) {
case kSRGB_SkGammaNamed:
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kSRGB_DstGamma, kFull_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
case k2Dot2Curve_SkGammaNamed:
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, k2Dot2_DstGamma, kFull_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
case kLinear_SkGammaNamed:
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kLinear_SrcGamma, kLinear_DstGamma, kFull_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
default:
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kTable_DstGamma, kFull_ColorSpaceMatch>
(srcSpace, srcToDst, dstSpace));
}
@@ -1243,25 +1249,21 @@ static inline int num_tables(SkColorSpace* space) {
}
template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
-SkColorSpaceXform_Base<kSrc, kDst, kCSM>
-::SkColorSpaceXform_Base(SkColorSpace* srcSpace, const SkMatrix44& srcToDst, SkColorSpace* dstSpace)
+SkColorSpaceXform_XYZ<kSrc, kDst, kCSM>
+::SkColorSpaceXform_XYZ(SkColorSpace* srcSpace, const SkMatrix44& srcToDst, SkColorSpace* dstSpace)
: fColorLUT(sk_ref_sp((SkColorLookUpTable*) as_CSB(srcSpace)->colorLUT()))
{
srcToDst.asColMajorf(fSrcToDst);
const int numSrcTables = num_tables(srcSpace);
- const int numDstTables = num_tables(dstSpace);
- const size_t srcTableBytes = numSrcTables * 256 * sizeof(float);
- const size_t dstTableBytes = numDstTables * kDstGammaTableSize * sizeof(uint8_t);
- fStorage.reset(srcTableBytes + dstTableBytes);
- float* srcStorage = (float*) fStorage.get();
- uint8_t* dstStorage = SkTAddOffset<uint8_t>(fStorage.get(), srcTableBytes);
-
+ const size_t srcEntries = numSrcTables * 256;
const bool srcGammasAreMatching = (1 >= numSrcTables);
- const bool dstGammasAreMatching = (1 >= numDstTables);
- build_gamma_tables(fSrcGammaTables, srcStorage, 256, srcSpace, kToLinear, srcGammasAreMatching);
- build_gamma_tables(fDstGammaTables, dstStorage, kDstGammaTableSize, dstSpace, kFromLinear,
- dstGammasAreMatching);
+ fSrcStorage.reset(srcEntries);
+ build_gamma_tables(fSrcGammaTables, fSrcStorage.get(), 256, srcSpace, kToLinear,
+ srcGammasAreMatching);
+
+ const int numDstTables = num_tables(dstSpace);
+ as_CSB(dstSpace)->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1318,7 +1320,7 @@ static inline bool apply_set_src(void* dst, const void* src, int len, SkAlphaTyp
}
template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
-bool SkColorSpaceXform_Base<kSrc, kDst, kCSM>
+bool SkColorSpaceXform_XYZ<kSrc, kDst, kCSM>
::onApply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, const void* src,
int len, SkAlphaType alphaType) const
{
@@ -1421,10 +1423,16 @@ bool SkColorSpaceXform_Base<kSrc, kDst, kCSM>
}
}
+bool SkColorSpaceXform::apply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat,
+ const void* src, int len, SkAlphaType alphaType) const {
+ return ((SkColorSpaceXform_Base*) this)->onApply(dstColorFormat, dst, srcColorFormat, src, len,
+ alphaType);
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace* space) {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
<kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
(space, SkMatrix::I(), space));
}
diff --git a/src/core/SkColorSpaceXform_Base.h b/src/core/SkColorSpaceXform_Base.h
index 02714ad59e..c1b9785424 100644
--- a/src/core/SkColorSpaceXform_Base.h
+++ b/src/core/SkColorSpaceXform_Base.h
@@ -11,6 +11,23 @@
#include "SkColorSpace.h"
#include "SkColorSpace_Base.h"
#include "SkColorSpaceXform.h"
+#include "SkResourceCache.h"
+
+class SkColorSpaceXform_Base : public SkColorSpaceXform {
+public:
+ static constexpr int kDstGammaTableSize = 1024;
+
+protected:
+ virtual bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src,
+ int count, SkAlphaType alphaType) const = 0;
+
+private:
+ static void BuildDstGammaTables(const uint8_t* outGammaTables[3], uint8_t* gammaTableStorage,
+ const SkColorSpace* space, bool gammasAreMatching);
+
+ friend class SkColorSpaceXform;
+ friend class SkColorSpace_Base;
+};
enum SrcGamma {
kLinear_SrcGamma,
@@ -31,24 +48,22 @@ enum ColorSpaceMatch {
};
template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
-class SkColorSpaceXform_Base : public SkColorSpaceXform {
-public:
- static constexpr int kDstGammaTableSize = 1024;
-
+class SkColorSpaceXform_XYZ : public SkColorSpaceXform_Base {
protected:
bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src,
int count, SkAlphaType alphaType) const override;
private:
- SkColorSpaceXform_Base(SkColorSpace* srcSpace, const SkMatrix44& srcToDst,
- SkColorSpace* dstSpace);
+ SkColorSpaceXform_XYZ(SkColorSpace* srcSpace, const SkMatrix44& srcToDst,
+ SkColorSpace* dstSpace);
sk_sp<SkColorLookUpTable> fColorLUT;
// Contain pointers into storage or pointers into precomputed tables.
const float* fSrcGammaTables[3];
+ SkAutoTMalloc<float> fSrcStorage;
const uint8_t* fDstGammaTables[3];
- SkAutoMalloc fStorage;
+ sk_sp<SkData> fDstStorage;
float fSrcToDst[16];
diff --git a/src/core/SkColorSpace_Base.h b/src/core/SkColorSpace_Base.h
index 36cc47779a..a188a11dd1 100644
--- a/src/core/SkColorSpace_Base.h
+++ b/src/core/SkColorSpace_Base.h
@@ -177,6 +177,8 @@ public:
const SkMatrix44& toXYZD50() const { return fToXYZD50; }
const SkMatrix44& fromXYZD50() const;
+ void toDstGammaTables(const uint8_t* tables[3], sk_sp<SkData>* storage, int numTables) const;
+
/**
* Create an SkColorSpace with the same gamut as this color space, but with linear gamma.
*/
@@ -200,14 +202,18 @@ private:
SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, SkGammaNamed gammaNamed,
sk_sp<SkGammas> gammas, const SkMatrix44& toXYZ, sk_sp<SkData> profileData);
- sk_sp<SkColorLookUpTable> fColorLUT;
- const SkGammaNamed fGammaNamed;
- sk_sp<SkGammas> fGammas;
- sk_sp<SkData> fProfileData;
+ sk_sp<SkColorLookUpTable> fColorLUT;
+ const SkGammaNamed fGammaNamed;
+ sk_sp<SkGammas> fGammas;
+ sk_sp<SkData> fProfileData;
+
+ const SkMatrix44 fToXYZD50;
+ mutable SkMatrix44 fFromXYZD50;
+ mutable SkOnce fFromXYZOnce;
- const SkMatrix44 fToXYZD50;
- mutable SkMatrix44 fFromXYZD50;
- mutable SkOnce fFromXYZOnce;
+ mutable sk_sp<SkData> fDstStorage;
+ mutable const uint8_t* fToDstGammaTables[3];
+ mutable SkOnce fToDstGammaOnce;
friend class SkColorSpace;
friend class ColorSpaceXformTest;