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

Side by Side Diff: src/effects/SkColorFilterImageFilter.cpp

Issue 968993004: add virtuals to optimize composing colorfilters (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix param warning Created 5 years, 9 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/SkColorFilter.cpp ('k') | src/effects/SkColorMatrix.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 2012 The Android Open Source Project 2 * Copyright 2012 The Android Open Source Project
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 "SkColorFilterImageFilter.h" 8 #include "SkColorFilterImageFilter.h"
9 #include "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkCanvas.h" 10 #include "SkCanvas.h"
11 #include "SkColorMatrixFilter.h" 11 #include "SkColorMatrixFilter.h"
12 #include "SkDevice.h" 12 #include "SkDevice.h"
13 #include "SkColorFilter.h" 13 #include "SkColorFilter.h"
14 #include "SkReadBuffer.h" 14 #include "SkReadBuffer.h"
15 #include "SkTableColorFilter.h" 15 #include "SkTableColorFilter.h"
16 #include "SkWriteBuffer.h" 16 #include "SkWriteBuffer.h"
17 17
18 namespace {
19
20 void mult_color_matrix(SkScalar a[20], SkScalar b[20], SkScalar out[20]) {
21 for (int j = 0; j < 4; ++j) {
22 for (int i = 0; i < 5; ++i) {
23 out[i+j*5] = 4 == i ? a[4+j*5] : 0;
24 for (int k = 0; k < 4; ++k)
25 out[i+j*5] += a[k+j*5] * b[i+k*5];
26 }
27 }
28 }
29
30 // Combines the two lookup tables so that making a lookup using OUT has
31 // the same effect as making a lookup through B then A.
32 void combine_color_tables(const uint8_t a[4 * 256],
33 const uint8_t b[4 * 256],
34 uint8_t out[4 * 256]) {
35 for (int i = 0; i < 4; i++) {
36 for (int j = 0; j < 256; j++) {
37 out[i * 256 + j] = a[i * 256 + b[i * 256 + j]];
38 }
39 }
40 }
41
42 // To detect if we need to apply clamping after applying a matrix, we check if
43 // any output component might go outside of [0, 255] for any combination of
44 // input components in [0..255].
45 // Each output component is an affine transformation of the input component, so
46 // the minimum and maximum values are for any combination of minimum or maximum
47 // values of input components (i.e. 0 or 255).
48 // E.g. if R' = x*R + y*G + z*B + w*A + t
49 // Then the maximum value will be for R=255 if x>0 or R=0 if x<0, and the
50 // minimum value will be for R=0 if x>0 or R=255 if x<0.
51 // Same goes for all components.
52 bool component_needs_clamping(SkScalar row[5]) {
53 SkScalar maxValue = row[4] / 255;
54 SkScalar minValue = row[4] / 255;
55 for (int i = 0; i < 4; ++i) {
56 if (row[i] > 0)
57 maxValue += row[i];
58 else
59 minValue += row[i];
60 }
61 return (maxValue > 1) || (minValue < 0);
62 }
63
64 bool matrix_needs_clamping(SkScalar matrix[20]) {
65 return component_needs_clamping(matrix)
66 || component_needs_clamping(matrix+5)
67 || component_needs_clamping(matrix+10)
68 || component_needs_clamping(matrix+15);
69 }
70
71 };
72
73 SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf, 18 SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf,
74 SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) { 19 SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) {
75 if (NULL == cf) { 20 if (NULL == cf) {
76 return NULL; 21 return NULL;
77 } 22 }
78 23
79 SkColorFilter* inputColorFilter; 24 SkColorFilter* inputColorFilter;
80 if (input && input->asColorFilter(&inputColorFilter) && inputColorFilter) { 25 if (input && input->asColorFilter(&inputColorFilter)) {
81 SkAutoUnref autoUnref(inputColorFilter); 26 SkAutoUnref autoUnref(inputColorFilter);
82 27 SkAutoTUnref<SkColorFilter> newCF(cf->newComposed(inputColorFilter));
83 // Try to collapse two consecutive matrix filters 28 if (newCF) {
84 SkScalar colorMatrix[20], inputMatrix[20];
85 if (cf->asColorMatrix(colorMatrix) && inputColorFilter->asColorMatrix(in putMatrix)
86 && !matrix_needs_clamping(inputMatrix )) {
87 SkScalar combinedMatrix[20];
88 mult_color_matrix(colorMatrix, inputMatrix, combinedMatrix);
89 SkAutoTUnref<SkColorFilter> newCF(SkColorMatrixFilter::Create(combin edMatrix));
90 return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput( 0), cropRect, 0));
91 }
92
93 // Try to collapse two consecutive table filters
94 SkBitmap colorTable, inputTable;
95 if (cf->asComponentTable(&colorTable) && inputColorFilter->asComponentTa ble(&inputTable)) {
96 uint8_t combinedTable[4 * 256];
97 SkAutoLockPixels colorLock(colorTable);
98 SkAutoLockPixels inputLock(inputTable);
99
100 combine_color_tables(colorTable.getAddr8(0, 0), inputTable.getAddr8( 0, 0),
101 combinedTable);
102 SkAutoTUnref<SkColorFilter> newCF(SkTableColorFilter::CreateARGB(
103 &combinedTable[256 * 0],
104 &combinedTable[256 * 1],
105 &combinedTable[256 * 2],
106 &combinedTable[256 * 3])
107 );
108
109 return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput( 0), cropRect, 0)); 29 return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput( 0), cropRect, 0));
110 } 30 }
111 } 31 }
112 32
113 return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input, cropRect, uniqueID)) ; 33 return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input, cropRect, uniqueID)) ;
114 } 34 }
115 35
116 SkColorFilterImageFilter::SkColorFilterImageFilter(SkColorFilter* cf, 36 SkColorFilterImageFilter::SkColorFilterImageFilter(SkColorFilter* cf,
117 SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) 37 SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
118 : INHERITED(1, &input, cropRect, uniqueID), fColorFilter(SkRef(cf)) { 38 : INHERITED(1, &input, cropRect, uniqueID), fColorFilter(SkRef(cf)) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 if (this->getInput(0)) { 105 if (this->getInput(0)) {
186 this->getInput(0)->toString(str); 106 this->getInput(0)->toString(str);
187 } 107 }
188 108
189 str->appendf(") color filter: "); 109 str->appendf(") color filter: ");
190 fColorFilter->toString(str); 110 fColorFilter->toString(str);
191 111
192 str->append(")"); 112 str->append(")");
193 } 113 }
194 #endif 114 #endif
OLDNEW
« no previous file with comments | « src/core/SkColorFilter.cpp ('k') | src/effects/SkColorMatrix.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698