aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar cwallez <cwallez@google.com>2015-01-26 07:45:53 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-01-26 07:45:53 -0800
commitc12b74dc413ef024b13e0ed478491c4b1bafe6b1 (patch)
tree706b76c6b014f84ca982a58686720bb47f8cdeb2 /src
parent9ec0ffb77dfb2c7337daadd4d88736c3e1ebe28b (diff)
Collapse consecutive SkTableColorFilters
BUG=skia:1366 For the added bench, the collapsing makes the bench take: - 70% of the time for CPU rendering of 3 consecutive matrix filters - almost no change in the GPU rendering of the matrix filters - 50% of the time for CPU and GPU rendering of 3 consecutive table filters Review URL: https://codereview.chromium.org/776673002
Diffstat (limited to 'src')
-rwxr-xr-xsrc/effects/SkColorFilterImageFilter.cpp48
1 files changed, 41 insertions, 7 deletions
diff --git a/src/effects/SkColorFilterImageFilter.cpp b/src/effects/SkColorFilterImageFilter.cpp
index acd6fac25e..0a4a693ab0 100755
--- a/src/effects/SkColorFilterImageFilter.cpp
+++ b/src/effects/SkColorFilterImageFilter.cpp
@@ -12,6 +12,7 @@
#include "SkDevice.h"
#include "SkColorFilter.h"
#include "SkReadBuffer.h"
+#include "SkTableColorFilter.h"
#include "SkWriteBuffer.h"
namespace {
@@ -21,7 +22,19 @@ void mult_color_matrix(SkScalar a[20], SkScalar b[20], SkScalar out[20]) {
for (int i = 0; i < 5; ++i) {
out[i+j*5] = 4 == i ? a[4+j*5] : 0;
for (int k = 0; k < 4; ++k)
- out[i+j*5] += SkScalarMul(a[k+j*5], b[i+k*5]);
+ out[i+j*5] += a[k+j*5] * b[i+k*5];
+ }
+ }
+}
+
+// Combines the two lookup tables so that making a lookup using OUT has
+// the same effect as making a lookup through B then A.
+void combine_color_tables(const uint8_t a[4 * 256],
+ const uint8_t b[4 * 256],
+ uint8_t out[4 * 256]) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 256; j++) {
+ out[i * 256 + j] = a[i * 256 + b[i * 256 + j]];
}
}
}
@@ -59,23 +72,44 @@ bool matrix_needs_clamping(SkScalar matrix[20]) {
SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf,
SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) {
- SkASSERT(cf);
if (NULL == cf) {
return NULL;
}
- SkScalar colorMatrix[20], inputMatrix[20];
+
SkColorFilter* inputColorFilter;
- if (input && cf->asColorMatrix(colorMatrix)
- && input->asColorFilter(&inputColorFilter)
- && (inputColorFilter)) {
+ if (input && input->asColorFilter(&inputColorFilter) && inputColorFilter) {
SkAutoUnref autoUnref(inputColorFilter);
- if (inputColorFilter->asColorMatrix(inputMatrix) && !matrix_needs_clamping(inputMatrix)) {
+
+ // Try to collapse two consecutive matrix filters
+ SkScalar colorMatrix[20], inputMatrix[20];
+ if (cf->asColorMatrix(colorMatrix) && inputColorFilter->asColorMatrix(inputMatrix)
+ && !matrix_needs_clamping(inputMatrix)) {
SkScalar combinedMatrix[20];
mult_color_matrix(colorMatrix, inputMatrix, combinedMatrix);
SkAutoTUnref<SkColorFilter> newCF(SkColorMatrixFilter::Create(combinedMatrix));
return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect, 0));
}
+
+ // Try to collapse two consecutive table filters
+ SkBitmap colorTable, inputTable;
+ if (cf->asComponentTable(&colorTable) && inputColorFilter->asComponentTable(&inputTable)) {
+ uint8_t combinedTable[4 * 256];
+ SkAutoLockPixels colorLock(colorTable);
+ SkAutoLockPixels inputLock(inputTable);
+
+ combine_color_tables(colorTable.getAddr8(0, 0), inputTable.getAddr8(0, 0),
+ combinedTable);
+ SkAutoTUnref<SkColorFilter> newCF(SkTableColorFilter::CreateARGB(
+ &combinedTable[256 * 0],
+ &combinedTable[256 * 1],
+ &combinedTable[256 * 2],
+ &combinedTable[256 * 3])
+ );
+
+ return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect, 0));
+ }
}
+
return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input, cropRect, uniqueID));
}