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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/core/SkColorSpaceXform.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkColorPriv.h" 8 #include "SkColorPriv.h"
9 #include "SkColorSpace_Base.h" 9 #include "SkColorSpace_Base.h"
10 #include "SkColorSpacePriv.h" 10 #include "SkColorSpacePriv.h"
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 nullptr, 249 nullptr,
250 nullptr, 250 nullptr,
251 &build_table_linear_to_gamma, 251 &build_table_linear_to_gamma,
252 &build_table_linear_to_gamma, 252 &build_table_linear_to_gamma,
253 &build_table_linear_to_gamma, 253 &build_table_linear_to_gamma,
254 }; 254 };
255 255
256 // Build tables to transform src gamma to linear. 256 // Build tables to transform src gamma to linear.
257 template <typename T> 257 template <typename T>
258 static void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage, int gammaTableSize, 258 static void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage, int gammaTableSize,
259 const sk_sp<SkColorSpace>& space, const GammaFns< T>& fns) { 259 const sk_sp<SkColorSpace>& space, const GammaFns< T>& fns,
260 bool gammasAreMatching) {
260 switch (as_CSB(space)->gammaNamed()) { 261 switch (as_CSB(space)->gammaNamed()) {
261 case kSRGB_SkGammaNamed: 262 case kSRGB_SkGammaNamed:
262 outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.fSRG BTable; 263 outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.fSRG BTable;
263 break; 264 break;
264 case k2Dot2Curve_SkGammaNamed: 265 case k2Dot2Curve_SkGammaNamed:
265 outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.f2Do t2Table; 266 outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.f2Do t2Table;
266 break; 267 break;
267 case kLinear_SkGammaNamed: 268 case kLinear_SkGammaNamed:
268 outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = nullptr; 269 outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = nullptr;
269 break; 270 break;
270 default: { 271 default: {
271 const SkGammas* gammas = as_CSB(space)->gammas(); 272 const SkGammas* gammas = as_CSB(space)->gammas();
272 SkASSERT(gammas); 273 SkASSERT(gammas);
273 274
274 for (int i = 0; i < 3; i++) { 275 auto build_table = [=](int i) {
275 if (i > 0) {
276 // Check if this curve matches the first curve. In this cas e, we can
277 // share the same table pointer. This should almost always be true.
278 // I've never seen a profile where all three gamma curves di dn't match.
279 // But it is possible that they won't.
280 if (gammas->type(0) == gammas->type(i) && gammas->data(0) == gammas->data(i)) {
281 outGammaTables[i] = outGammaTables[0];
282 continue;
283 }
284 }
285
286 if (gammas->isNamed(i)) { 276 if (gammas->isNamed(i)) {
287 switch (gammas->data(i).fNamed) { 277 switch (gammas->data(i).fNamed) {
288 case kSRGB_SkGammaNamed: 278 case kSRGB_SkGammaNamed:
289 (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaT ableSize], 2.4f, 279 (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaT ableSize], 2.4f,
290 (1.0f / 1.055f), (0.055f / 1. 055f), 0.0f, 280 (1.0f / 1.055f), (0.055f / 1. 055f), 0.0f,
291 0.04045f, (1.0f / 12.92f), 0. 0f); 281 0.04045f, (1.0f / 12.92f), 0. 0f);
292 outGammaTables[i] = &gammaTableStorage[i * gammaTabl eSize]; 282 outGammaTables[i] = &gammaTableStorage[i * gammaTabl eSize];
293 break; 283 break;
294 case k2Dot2Curve_SkGammaNamed: 284 case k2Dot2Curve_SkGammaNamed:
295 (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaT ableSize], 2.2f); 285 (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaT ableSize], 2.2f);
(...skipping 16 matching lines...) Expand all
312 gammas->data(i).fTable.fSize); 302 gammas->data(i).fTable.fSize);
313 outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 303 outGammaTables[i] = &gammaTableStorage[i * gammaTableSize];
314 } else { 304 } else {
315 SkASSERT(gammas->isParametric(i)); 305 SkASSERT(gammas->isParametric(i));
316 const SkGammas::Params& params = gammas->params(i); 306 const SkGammas::Params& params = gammas->params(i);
317 (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize ], params.fG, 307 (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize ], params.fG,
318 params.fA, params.fB, params.fC, para ms.fD, params.fE, 308 params.fA, params.fB, params.fC, para ms.fD, params.fE,
319 params.fF); 309 params.fF);
320 outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 310 outGammaTables[i] = &gammaTableStorage[i * gammaTableSize];
321 } 311 }
312 };
313
314 if (gammasAreMatching) {
315 build_table(0);
316 outGammaTables[1] = outGammaTables[0];
317 outGammaTables[2] = outGammaTables[0];
318 } else {
319 build_table(0);
320 build_table(1);
321 build_table(2);
322 } 322 }
323
324 break;
323 } 325 }
324 } 326 }
325 } 327 }
326 328
327 //////////////////////////////////////////////////////////////////////////////// /////////////////// 329 //////////////////////////////////////////////////////////////////////////////// ///////////////////
328 330
329 static inline bool is_almost_identity(const SkMatrix44& srcToDst) { 331 static inline bool is_almost_identity(const SkMatrix44& srcToDst) {
330 for (int i = 0; i < 4; i++) { 332 for (int i = 0; i < 4; i++) {
331 for (int j = 0; j < 4; j++) { 333 for (int j = 0; j < 4; j++) {
332 float expected = (i == j) ? 1.0f : 0.0f; 334 float expected = (i == j) ? 1.0f : 0.0f;
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 break; 1154 break;
1153 } 1155 }
1154 1156
1155 do_color_xform<kAlphaType, kCSM> 1157 do_color_xform<kAlphaType, kCSM>
1156 (dst, src, len, srcTables, matrix, dstTables, load, load_1, store, s tore_1, 1158 (dst, src, len, srcTables, matrix, dstTables, load, load_1, store, s tore_1,
1157 sizeOfDstPixel); 1159 sizeOfDstPixel);
1158 } 1160 }
1159 1161
1160 //////////////////////////////////////////////////////////////////////////////// /////////////////// 1162 //////////////////////////////////////////////////////////////////////////////// ///////////////////
1161 1163
1164 static inline int num_tables(SkColorSpace* space) {
1165 switch (as_CSB(space)->gammaNamed()) {
1166 case kSRGB_SkGammaNamed:
1167 case k2Dot2Curve_SkGammaNamed:
1168 case kLinear_SkGammaNamed:
1169 return 0;
1170 default: {
1171 const SkGammas* gammas = as_CSB(space)->gammas();
1172 SkASSERT(gammas);
1173
1174 bool gammasAreMatching = (gammas->type(0) == gammas->type(1)) &&
1175 (gammas->data(0) == gammas->data(1)) &&
1176 (gammas->type(0) == gammas->type(2)) &&
1177 (gammas->data(0) == gammas->data(2));
1178
1179 // It's likely that each component will have the same gamma. In thi s case,
1180 // we only need to build one table.
1181 return gammasAreMatching ? 1 : 3;
1182 }
1183 }
1184 }
1185
1162 template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM> 1186 template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
1163 SkColorSpaceXform_Base<kSrc, kDst, kCSM> 1187 SkColorSpaceXform_Base<kSrc, kDst, kCSM>
1164 ::SkColorSpaceXform_Base(const sk_sp<SkColorSpace>& srcSpace, const SkMatrix44& srcToDst, 1188 ::SkColorSpaceXform_Base(const sk_sp<SkColorSpace>& srcSpace, const SkMatrix44& srcToDst,
1165 const sk_sp<SkColorSpace>& dstSpace) 1189 const sk_sp<SkColorSpace>& dstSpace)
1166 : fColorLUT(sk_ref_sp((SkColorLookUpTable*) as_CSB(srcSpace)->colorLUT())) 1190 : fColorLUT(sk_ref_sp((SkColorLookUpTable*) as_CSB(srcSpace)->colorLUT()))
1167 { 1191 {
1168 srcToDst.asColMajorf(fSrcToDst); 1192 srcToDst.asColMajorf(fSrcToDst);
1169 build_gamma_tables(fSrcGammaTables, fSrcGammaTableStorage, 256, srcSpace, kT oLinear); 1193
1170 build_gamma_tables(fDstGammaTables, fDstGammaTableStorage, kDstGammaTableSiz e, dstSpace, 1194 const int numSrcTables = num_tables(srcSpace.get());
1171 kFromLinear); 1195 const int numDstTables = num_tables(dstSpace.get());
1196 const size_t srcTableBytes = numSrcTables * 256 * sizeof(float);
1197 const size_t dstTableBytes = numDstTables * kDstGammaTableSize * sizeof(uint 8_t);
1198 fStorage.reset(srcTableBytes + dstTableBytes);
1199 float* srcStorage = (float*) fStorage.get();
1200 uint8_t* dstStorage = SkTAddOffset<uint8_t>(fStorage.get(), srcTableBytes);
1201
1202 const bool srcGammasAreMatching = (1 >= numSrcTables);
1203 const bool dstGammasAreMatching = (1 >= numDstTables);
1204 build_gamma_tables(fSrcGammaTables, srcStorage, 256, srcSpace, kToLinear, sr cGammasAreMatching);
1205 build_gamma_tables(fDstGammaTables, dstStorage, kDstGammaTableSize, dstSpace , kFromLinear,
1206 dstGammasAreMatching);
1172 } 1207 }
1173 1208
1209 //////////////////////////////////////////////////////////////////////////////// ///////////////////
1210
1174 template <SrcFormat kSrc, DstFormat kDst, ColorSpaceMatch kCSM, SwapRB kSwap> 1211 template <SrcFormat kSrc, DstFormat kDst, ColorSpaceMatch kCSM, SwapRB kSwap>
1175 static inline void apply_set_alpha(void* dst, const uint32_t* src, int len, SkAl phaType alphaType, 1212 static inline void apply_set_alpha(void* dst, const uint32_t* src, int len, SkAl phaType alphaType,
1176 const float* const srcTables[3], const float matrix[16], 1213 const float* const srcTables[3], const float matrix[16],
1177 const uint8_t* const dstTables[3]) { 1214 const uint8_t* const dstTables[3]) {
1178 switch (alphaType) { 1215 switch (alphaType) {
1179 case kOpaque_SkAlphaType: 1216 case kOpaque_SkAlphaType:
1180 return color_xform_RGBA<kSrc, kDst, kOpaque_SkAlphaType, kCSM, kSwap > 1217 return color_xform_RGBA<kSrc, kDst, kOpaque_SkAlphaType, kCSM, kSwap >
1181 (dst, src, len, srcTables, matrix, dstTables); 1218 (dst, src, len, srcTables, matrix, dstTables);
1182 case kPremul_SkAlphaType: 1219 case kPremul_SkAlphaType:
1183 return color_xform_RGBA<kSrc, kDst, kPremul_SkAlphaType, kCSM, kSwap > 1220 return color_xform_RGBA<kSrc, kDst, kPremul_SkAlphaType, kCSM, kSwap >
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 default: 1321 default:
1285 SkASSERT(false); 1322 SkASSERT(false);
1286 return; 1323 return;
1287 } 1324 }
1288 default: 1325 default:
1289 SkASSERT(false); 1326 SkASSERT(false);
1290 return; 1327 return;
1291 } 1328 }
1292 } 1329 }
1293 1330
1331 //////////////////////////////////////////////////////////////////////////////// ///////////////////
1332
1294 std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(const sk_sp<SkColorSpace>& space) { 1333 std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(const sk_sp<SkColorSpace>& space) {
1295 return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 1334 return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
1296 <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 1335 <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
1297 (space, SkMatrix::I(), space)); 1336 (space, SkMatrix::I(), space));
1298 } 1337 }
OLDNEW
« 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