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

Side by Side Diff: Source/core/platform/image-decoders/ImageDecoder.h

Issue 15466004: Make image decoders faster by refactoring hot loops that fills the lines of ImageFrame. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Make image decoders faster by refactoring hot loops that fills the lines of ImageFrame. Created 7 years, 6 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 | « no previous file | Source/core/platform/image-decoders/jpeg/JPEGImageDecoder.cpp » ('j') | 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 (C) 2006 Apple Computer, Inc. All rights reserved. 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 unsigned alphaMult = a * fixPointMult; 171 unsigned alphaMult = a * fixPointMult;
172 r = fixPointUnsignedMultiply(r, alphaMult); 172 r = fixPointUnsignedMultiply(r, alphaMult);
173 g = fixPointUnsignedMultiply(g, alphaMult); 173 g = fixPointUnsignedMultiply(g, alphaMult);
174 b = fixPointUnsignedMultiply(b, alphaMult); 174 b = fixPointUnsignedMultiply(b, alphaMult);
175 } 175 }
176 // Call the "NoCheck" version since we may deliberately pass non-pre multiplied 176 // Call the "NoCheck" version since we may deliberately pass non-pre multiplied
177 // values, and we don't want an assert. 177 // values, and we don't want an assert.
178 *dest = SkPackARGB32NoCheck(a, r, g, b); 178 *dest = SkPackARGB32NoCheck(a, r, g, b);
179 } 179 }
180 180
181 inline void fillRowFromRGBSource(int rowIndex, const unsigned char* src)
Peter Kasting 2013/06/01 01:22:12 I don't think we gain much from having these first
182 {
183 fillRowFromRGBSource(getAddr(0, rowIndex), src, width());
184 }
185
186 inline void fillRowFromRGBASource(int rowIndex, const unsigned char* src )
187 {
188 bool dummy;
189 fillRowFromRGBASource<false>(getAddr(0, rowIndex), src, width(), dum my);
190 }
191
192 inline void fillRowFromRGBASourceWithNonTrivialAlphaDetection(int rowInd ex, const unsigned char *src, bool& hasNonTrivialAlpha)
193 {
194 fillRowFromRGBASource<true>(getAddr(0, rowIndex), src, width(), hasN onTrivialAlpha);
195 }
196
197 inline void fillRowFromInvertedCMYK(int rowIndex, const unsigned char* s rc)
198 {
199 fillRowFromInvertedCMYK(getAddr(0, rowIndex), src, width());
200 }
201
181 private: 202 private:
203 // We have specialized fill functions for each case. This way we avoid b ranches in the loop which gives performace.
204 // Note: we could benefit further from turning on auto vectorization in the compiler.
205
206 ALWAYS_INLINE static void fillRowFromRGBSource(PixelData* dst, const uns igned char* src, int numPixels)
207 {
208 const unsigned char* pixel = src;
209 for (int i = 0; i < numPixels; ++i, pixel += 3)
210 dst[i] = SkPackARGB32NoCheck(255, pixel[0], pixel[1], pixel[2]);
211 }
212
213 template <bool shouldUpdate>
214 inline static void updateAlphaMask(unsigned char alpha, unsigned char& m ask)
Peter Kasting 2013/06/01 01:22:12 Nit: Honestly, I'm not convinced pulling this into
215 {
216 if (shouldUpdate)
217 mask &= alpha;
218 }
219
220 template <bool shouldUpdateAlphaMask>
221 ALWAYS_INLINE static void fillRowFromRGBASourceNoPremultiply(PixelData* dst, const unsigned char* src, int numPixels, unsigned char& alphaMask)
222 {
223 const unsigned char* pixel = src;
224 for (int i = 0; i < numPixels; ++i, pixel += 4) {
225 unsigned char alpha = pixel[3];
226 dst[i] = SkPackARGB32NoCheck(alpha, pixel[0], pixel[1], pixel[2] );
227 updateAlphaMask<shouldUpdateAlphaMask>(alpha, alphaMask);
228 }
229 }
230
231 template <bool shouldUpdateAlphaMask>
232 ALWAYS_INLINE static void fillRowFromRGBASourcePremultiply(PixelData* ds t, const unsigned char* src, int numPixels, unsigned char& alphaMask)
233 {
234 const unsigned char* pixel = src;
235 for (int i = 0; i < numPixels; ++i, pixel += 4) {
236 unsigned char r = pixel[0];
237 unsigned char g = pixel[1];
238 unsigned char b = pixel[2];
239 unsigned char a = pixel[3];
240
241 updateAlphaMask<shouldUpdateAlphaMask>(a, alphaMask);
242
243 // Note: if once we start using auto vectorization we should ree valuate whether the fast paths are
244 // worthwile when alpha is zero or 255. Currently without vector ization they are.
245 if (!a) {
246 dst[i] = 0;
247 continue;
248 }
249 if (a < 255) {
250 unsigned alphaMult = a * fixPointMult;
251 r = fixPointUnsignedMultiply(r, alphaMult);
252 g = fixPointUnsignedMultiply(g, alphaMult);
253 b = fixPointUnsignedMultiply(b, alphaMult);
254 }
255 dst[i] = SkPackARGB32NoCheck(a, r, g, b);
256 }
257 }
258
259 template <bool shouldUpdateHasNonTrivialAlpha>
260 ALWAYS_INLINE void fillRowFromRGBASource(PixelData* dst, const unsigned char* src, int numPixels, bool& hasNonTrivialAlpha)
Peter Kasting 2013/06/01 01:22:12 Nit: If you take a bool* as the last arg, we can p
261 {
262 unsigned char alphaMask = 255;
263 if (m_premultiplyAlpha)
264 fillRowFromRGBASourcePremultiply<shouldUpdateHasNonTrivialAlpha> (dst, src, numPixels, alphaMask);
265 else
266 fillRowFromRGBASourceNoPremultiply<shouldUpdateHasNonTrivialAlph a>(dst, src, numPixels, alphaMask);
267
268 if (shouldUpdateHasNonTrivialAlpha)
269 hasNonTrivialAlpha = alphaMask != 255;
270 }
271
272 ALWAYS_INLINE static void fillRowFromInvertedCMYK(PixelData* dst, const unsigned char* src, int numPixels)
273 {
274 // Source is 'Inverted CMYK', output is RGB.
275 // See: http://www.easyrgb.com/math.php?MATH=M12#text12
276 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
277 // From CMYK to CMY:
278 // X = X * (1 - K ) + K [for X = C, M, or Y]
279 // Thus, from Inverted CMYK to CMY is:
280 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK
281 // From CMY (0..1) to RGB (0..1):
282 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar]
283
284 const unsigned char* pixel = src;
285 for (int i = 0; i < numPixels; ++i, pixel += 4) {
286 unsigned char c = pixel[0];
287 unsigned char m = pixel[1];
288 unsigned char y = pixel[2];
289 unsigned char k = pixel[3];
290
291 unsigned kMult = k * fixPointMult;
292 c = fixPointUnsignedMultiply(c, kMult);
293 m = fixPointUnsignedMultiply(m, kMult);
294 y = fixPointUnsignedMultiply(y, kMult);
295
296 dst[i] = SkPackARGB32NoCheck(255, c, m, y);
Peter Kasting 2013/06/01 01:22:12 It strikes me that this function is effectively id
297 }
298 }
299
182 int width() const 300 int width() const
183 { 301 {
184 return m_bitmap->bitmap().width(); 302 return m_bitmap->bitmap().width();
185 } 303 }
186 304
187 int height() const 305 int height() const
188 { 306 {
189 return m_bitmap->bitmap().height(); 307 return m_bitmap->bitmap().height();
190 } 308 }
191 309
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 514
397 IntSize m_size; 515 IntSize m_size;
398 bool m_sizeAvailable; 516 bool m_sizeAvailable;
399 bool m_isAllDataReceived; 517 bool m_isAllDataReceived;
400 bool m_failed; 518 bool m_failed;
401 }; 519 };
402 520
403 } // namespace WebCore 521 } // namespace WebCore
404 522
405 #endif 523 #endif
OLDNEW
« no previous file with comments | « no previous file | Source/core/platform/image-decoders/jpeg/JPEGImageDecoder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698