Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Unified Diff: src/core/SkColorSpaceXform.cpp

Issue 2336913005: Store SkColorSpaceXform gamma LUTs in a malloced field (Closed)
Patch Set: Fixes Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkColorSpaceXform.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkColorSpaceXform.cpp
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp
index 5a6f015bff4670570907bfd4ae4908760ecd4940..29528db98324a0d205b8e30684a6030c7b5a063d 100644
--- a/src/core/SkColorSpaceXform.cpp
+++ b/src/core/SkColorSpaceXform.cpp
@@ -256,7 +256,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,
- const sk_sp<SkColorSpace>& space, const GammaFns<T>& fns) {
+ const sk_sp<SkColorSpace>& space, const GammaFns<T>& fns,
+ bool gammasAreMatching) {
switch (as_CSB(space)->gammaNamed()) {
case kSRGB_SkGammaNamed:
outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.fSRGBTable;
@@ -271,18 +272,7 @@ static void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage,
const SkGammas* gammas = as_CSB(space)->gammas();
SkASSERT(gammas);
- for (int i = 0; i < 3; i++) {
- if (i > 0) {
- // Check if this curve matches the first curve. In this case, we can
- // share the same table pointer. This should almost always be true.
- // I've never seen a profile where all three gamma curves didn't match.
- // But it is possible that they won't.
- if (gammas->type(0) == gammas->type(i) && gammas->data(0) == gammas->data(i)) {
- outGammaTables[i] = outGammaTables[0];
- continue;
- }
- }
-
+ auto build_table = [=](int i) {
if (gammas->isNamed(i)) {
switch (gammas->data(i).fNamed) {
case kSRGB_SkGammaNamed:
@@ -319,7 +309,19 @@ static void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage,
params.fF);
outGammaTables[i] = &gammaTableStorage[i * gammaTableSize];
}
+ };
+
+ if (gammasAreMatching) {
+ build_table(0);
+ outGammaTables[1] = outGammaTables[0];
+ outGammaTables[2] = outGammaTables[0];
+ } else {
+ build_table(0);
+ build_table(1);
+ build_table(2);
}
+
+ break;
}
}
}
@@ -1159,6 +1161,28 @@ static void color_xform_RGBA(void* dst, const uint32_t* src, int len,
///////////////////////////////////////////////////////////////////////////////////////////////////
+static inline int num_tables(SkColorSpace* space) {
+ switch (as_CSB(space)->gammaNamed()) {
+ case kSRGB_SkGammaNamed:
+ case k2Dot2Curve_SkGammaNamed:
+ case kLinear_SkGammaNamed:
+ return 0;
+ default: {
+ const SkGammas* gammas = as_CSB(space)->gammas();
+ SkASSERT(gammas);
+
+ bool gammasAreMatching = (gammas->type(0) == gammas->type(1)) &&
+ (gammas->data(0) == gammas->data(1)) &&
+ (gammas->type(0) == gammas->type(2)) &&
+ (gammas->data(0) == gammas->data(2));
+
+ // It's likely that each component will have the same gamma. In this case,
+ // we only need to build one table.
+ return gammasAreMatching ? 1 : 3;
+ }
+ }
+}
+
template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
SkColorSpaceXform_Base<kSrc, kDst, kCSM>
::SkColorSpaceXform_Base(const sk_sp<SkColorSpace>& srcSpace, const SkMatrix44& srcToDst,
@@ -1166,11 +1190,24 @@ SkColorSpaceXform_Base<kSrc, kDst, kCSM>
: fColorLUT(sk_ref_sp((SkColorLookUpTable*) as_CSB(srcSpace)->colorLUT()))
{
srcToDst.asColMajorf(fSrcToDst);
- build_gamma_tables(fSrcGammaTables, fSrcGammaTableStorage, 256, srcSpace, kToLinear);
- build_gamma_tables(fDstGammaTables, fDstGammaTableStorage, kDstGammaTableSize, dstSpace,
- kFromLinear);
+
+ const int numSrcTables = num_tables(srcSpace.get());
+ const int numDstTables = num_tables(dstSpace.get());
+ 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 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);
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
template <SrcFormat kSrc, DstFormat kDst, ColorSpaceMatch kCSM, SwapRB kSwap>
static inline void apply_set_alpha(void* dst, const uint32_t* src, int len, SkAlphaType alphaType,
const float* const srcTables[3], const float matrix[16],
@@ -1291,6 +1328,8 @@ const
}
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(const sk_sp<SkColorSpace>& space) {
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
<kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
« no previous file with comments | « src/core/SkColorSpaceXform.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698