1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// Copyright 2012 The Chromium Authors. All rights reserved.
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// Use of this source code is governed by a BSD-style license that can be
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// found in the LICENSE file.
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "cc/output/render_surface_filters.h"
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include <algorithm>
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "cc/output/filter_operation.h"
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "cc/output/filter_operations.h"
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "skia/ext/refptr.h"
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "third_party/skia/include/core/SkImageFilter.h"
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "third_party/skia/include/effects/SkAlphaThresholdFilter.h"
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "third_party/skia/include/effects/SkBlurImageFilter.h"
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "third_party/skia/include/effects/SkComposeImageFilter.h"
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "third_party/skia/include/effects/SkDropShadowImageFilter.h"
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "third_party/skia/include/effects/SkMagnifierImageFilter.h"
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "third_party/skia/include/effects/SkRectShaderImageFilter.h"
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ui/gfx/geometry/size_f.h"
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectnamespace cc {
24a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectnamespace {
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectvoid GetBrightnessMatrix(float amount, SkScalar matrix[20]) {
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Spec implementation
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // (http://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#brightnessEquivalent)
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // <feFunc[R|G|B] type="linear" slope="[amount]">
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  memset(matrix, 0, 20 * sizeof(SkScalar));
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[0] = matrix[6] = matrix[12] = amount;
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[18] = 1.f;
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectvoid GetSaturatingBrightnessMatrix(float amount, SkScalar matrix[20]) {
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Legacy implementation used by internal clients.
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // <feFunc[R|G|B] type="linear" intercept="[amount]"/>
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  memset(matrix, 0, 20 * sizeof(SkScalar));
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f;
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[4] = matrix[9] = matrix[14] = amount * 255.f;
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectvoid GetContrastMatrix(float amount, SkScalar matrix[20]) {
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  memset(matrix, 0, 20 * sizeof(SkScalar));
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[0] = matrix[6] = matrix[12] = amount;
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f) * 255.f;
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[18] = 1.f;
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectvoid GetSaturateMatrix(float amount, SkScalar matrix[20]) {
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Note, these values are computed to ensure MatrixNeedsClamping is false
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // for amount in [0..1]
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[0] = 0.213f + 0.787f * amount;
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[1] = 0.715f - 0.715f * amount;
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[2] = 1.f - (matrix[0] + matrix[1]);
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[3] = matrix[4] = 0.f;
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[5] = 0.213f - 0.213f * amount;
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[6] = 0.715f + 0.285f * amount;
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[7] = 1.f - (matrix[5] + matrix[6]);
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[8] = matrix[9] = 0.f;
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[10] = 0.213f - 0.213f * amount;
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[11] = 0.715f - 0.715f * amount;
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[12] = 1.f - (matrix[10] + matrix[11]);
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[13] = matrix[14] = 0.f;
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[18] = 1.f;
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectvoid GetHueRotateMatrix(float hue, SkScalar matrix[20]) {
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const float kPi = 3.1415926535897932384626433832795f;
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  float cos_hue = cosf(hue * kPi / 180.f);
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  float sin_hue = sinf(hue * kPi / 180.f);
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[0] = 0.213f + cos_hue * 0.787f - sin_hue * 0.213f;
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[1] = 0.715f - cos_hue * 0.715f - sin_hue * 0.715f;
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[2] = 0.072f - cos_hue * 0.072f + sin_hue * 0.928f;
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[3] = matrix[4] = 0.f;
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[5] = 0.213f - cos_hue * 0.213f + sin_hue * 0.143f;
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[6] = 0.715f + cos_hue * 0.285f + sin_hue * 0.140f;
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[7] = 0.072f - cos_hue * 0.072f - sin_hue * 0.283f;
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[8] = matrix[9] = 0.f;
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[10] = 0.213f - cos_hue * 0.213f - sin_hue * 0.787f;
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[11] = 0.715f - cos_hue * 0.715f + sin_hue * 0.715f;
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[12] = 0.072f + cos_hue * 0.928f + sin_hue * 0.072f;
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[13] = matrix[14] = 0.f;
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[15] = matrix[16] = matrix[17] = 0.f;
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[18] = 1.f;
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[19] = 0.f;
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectvoid GetInvertMatrix(float amount, SkScalar matrix[20]) {
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  memset(matrix, 0, 20 * sizeof(SkScalar));
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[0] = matrix[6] = matrix[12] = 1.f - 2.f * amount;
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[4] = matrix[9] = matrix[14] = amount * 255.f;
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[18] = 1.f;
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectvoid GetOpacityMatrix(float amount, SkScalar matrix[20]) {
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  memset(matrix, 0, 20 * sizeof(SkScalar));
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[0] = matrix[6] = matrix[12] = 1.f;
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[18] = amount;
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectvoid GetGrayscaleMatrix(float amount, SkScalar matrix[20]) {
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Note, these values are computed to ensure MatrixNeedsClamping is false
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // for amount in [0..1]
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[0] = 0.2126f + 0.7874f * amount;
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[1] = 0.7152f - 0.7152f * amount;
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[2] = 1.f - (matrix[0] + matrix[1]);
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[3] = matrix[4] = 0.f;
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[5] = 0.2126f - 0.2126f * amount;
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[6] = 0.7152f + 0.2848f * amount;
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[7] = 1.f - (matrix[5] + matrix[6]);
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[8] = matrix[9] = 0.f;
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[10] = 0.2126f - 0.2126f * amount;
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[11] = 0.7152f - 0.7152f * amount;
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[12] = 1.f - (matrix[10] + matrix[11]);
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[13] = matrix[14] = 0.f;
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[18] = 1.f;
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectvoid GetSepiaMatrix(float amount, SkScalar matrix[20]) {
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[0] = 0.393f + 0.607f * amount;
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[1] = 0.769f - 0.769f * amount;
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[2] = 0.189f - 0.189f * amount;
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[3] = matrix[4] = 0.f;
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[5] = 0.349f - 0.349f * amount;
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[6] = 0.686f + 0.314f * amount;
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[7] = 0.168f - 0.168f * amount;
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[8] = matrix[9] = 0.f;
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[10] = 0.272f - 0.272f * amount;
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[11] = 0.534f - 0.534f * amount;
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[12] = 0.131f + 0.869f * amount;
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[13] = matrix[14] = 0.f;
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  matrix[18] = 1.f;
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}
1460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Projectskia::RefPtr<SkImageFilter> CreateMatrixImageFilter(
1480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    const SkScalar matrix[20],
1490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    const skia::RefPtr<SkImageFilter>& input) {
1508583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner  skia::RefPtr<SkColorFilter> color_filter =
1510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      skia::AdoptRef(SkColorMatrixFilter::Create(matrix));
1528583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner  return skia::AdoptRef(
153295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      SkColorFilterImageFilter::Create(color_filter.get(), input.get()));
1548583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner}
1558583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner
1568583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner}  // namespace
1578583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner
1580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Projectskia::RefPtr<SkImageFilter> RenderSurfaceFilters::BuildImageFilter(
1590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    const FilterOperations& filters,
1600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    const gfx::SizeF& size) {
1610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  skia::RefPtr<SkImageFilter> image_filter;
1628583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner  SkScalar matrix[20];
1630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  for (size_t i = 0; i < filters.size(); ++i) {
1640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    const FilterOperation& op = filters.at(i);
1650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    switch (op.type()) {
1660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      case FilterOperation::GRAYSCALE:
1670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        GetGrayscaleMatrix(1.f - op.amount(), matrix);
1680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        image_filter = CreateMatrixImageFilter(matrix, image_filter);
1698583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
1700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      case FilterOperation::SEPIA:
1710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        GetSepiaMatrix(1.f - op.amount(), matrix);
172295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        image_filter = CreateMatrixImageFilter(matrix, image_filter);
1730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        break;
1740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      case FilterOperation::SATURATE:
1750a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        GetSaturateMatrix(op.amount(), matrix);
1760a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        image_filter = CreateMatrixImageFilter(matrix, image_filter);
1770a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        break;
1780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      case FilterOperation::HUE_ROTATE:
1790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        GetHueRotateMatrix(op.amount(), matrix);
1808583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        image_filter = CreateMatrixImageFilter(matrix, image_filter);
1818583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
1828583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::INVERT:
1838583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        GetInvertMatrix(op.amount(), matrix);
1848583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        image_filter = CreateMatrixImageFilter(matrix, image_filter);
1858583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
1868583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::OPACITY:
1878583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        GetOpacityMatrix(op.amount(), matrix);
1888583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        image_filter = CreateMatrixImageFilter(matrix, image_filter);
1898583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
1908583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::BRIGHTNESS:
1918583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        GetBrightnessMatrix(op.amount(), matrix);
1928583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        image_filter = CreateMatrixImageFilter(matrix, image_filter);
1938583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
1948583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::CONTRAST:
1958583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        GetContrastMatrix(op.amount(), matrix);
1968583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        image_filter = CreateMatrixImageFilter(matrix, image_filter);
1978583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
1988583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::BLUR:
1998583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        image_filter = skia::AdoptRef(SkBlurImageFilter::Create(
2008583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner            op.amount(), op.amount(), image_filter.get()));
2018583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
2028583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::DROP_SHADOW:
2038583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        image_filter = skia::AdoptRef(SkDropShadowImageFilter::Create(
2048583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner            SkIntToScalar(op.drop_shadow_offset().x()),
2058583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner            SkIntToScalar(op.drop_shadow_offset().y()),
2068583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner            SkIntToScalar(op.amount()),
2078583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner            SkIntToScalar(op.amount()),
2088583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner            op.drop_shadow_color(),
2098583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner            image_filter.get()));
2108583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
2118583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::COLOR_MATRIX:
2128583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        image_filter = CreateMatrixImageFilter(op.matrix(), image_filter);
2138583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
2148583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::ZOOM: {
2158583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        skia::RefPtr<SkImageFilter> zoom_filter =
2168583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner            skia::AdoptRef(SkMagnifierImageFilter::Create(
217c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner                SkRect::MakeXYWH(
2188583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner                    (size.width() - (size.width() / op.amount())) / 2.f,
2198583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner                    (size.height() - (size.height() / op.amount())) / 2.f,
220c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner                    size.width() / op.amount(),
2218583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner                    size.height() / op.amount()),
222c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner                op.zoom_inset()));
2238583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        if (image_filter.get()) {
2248583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          // TODO(ajuma): When there's a 1-input version of
225c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner          // SkMagnifierImageFilter, use that to handle the input filter
226c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner          // instead of using an SkComposeImageFilter.
227c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner          image_filter = skia::AdoptRef(SkComposeImageFilter::Create(
228c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner              zoom_filter.get(), image_filter.get()));
2298583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        } else {
2308583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          image_filter = zoom_filter;
2318583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        }
2328583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
2338583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      }
2348583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::SATURATING_BRIGHTNESS:
2358583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        GetSaturatingBrightnessMatrix(op.amount(), matrix);
2368583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        image_filter = CreateMatrixImageFilter(matrix, image_filter);
2378583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
2388583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::REFERENCE: {
2398583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        if (!op.image_filter())
2408583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          break;
2418583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner
2428583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        skia::RefPtr<SkColorFilter> cf;
2438583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner
2448583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        {
2458583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          SkColorFilter* colorfilter_rawptr = NULL;
2468583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          op.image_filter()->asColorFilter(&colorfilter_rawptr);
2478583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          cf = skia::AdoptRef(colorfilter_rawptr);
248a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        }
2498583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner
2508583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        if (cf && cf->asColorMatrix(matrix) &&
2518583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner            !op.image_filter()->getInput(0)) {
2528583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          image_filter = CreateMatrixImageFilter(matrix, image_filter);
2538583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        } else if (image_filter) {
2548583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          image_filter = skia::AdoptRef(SkComposeImageFilter::Create(
2558583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner              op.image_filter().get(), image_filter.get()));
2568583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        } else {
2578583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          image_filter = op.image_filter();
2588583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        }
2598583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
2608583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      }
2618583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      case FilterOperation::ALPHA_THRESHOLD: {
2628583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        skia::RefPtr<SkImageFilter> alpha_filter = skia::AdoptRef(
2638583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner            SkAlphaThresholdFilter::Create(
2648583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner                op.region(), op.amount(), op.outer_threshold()));
2658583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        if (image_filter.get()) {
2668583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          image_filter = skia::AdoptRef(SkComposeImageFilter::Create(
2678583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner              alpha_filter.get(), image_filter.get()));
2688583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        } else {
2698583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner          image_filter = alpha_filter;
2708583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        }
2718583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        break;
2728583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      }
2738583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner    }
2748583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner  }
2758583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner  return image_filter;
2768583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner}
2778583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner
2788583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner}  // namespace cc
2798583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner