1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <algorithm>
67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/debug/trace_event_argument.h"
8ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/values.h"
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "cc/base/math_util.h"
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "cc/output/filter_operation.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/gfx/animation/tween.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace cc {
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool FilterOperation::operator==(const FilterOperation& other) const {
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (type_ != other.type_)
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (type_ == COLOR_MATRIX)
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return !memcmp(matrix_, other.matrix_, sizeof(matrix_));
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (type_ == DROP_SHADOW) {
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return amount_ == other.amount_ &&
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           drop_shadow_offset_ == other.drop_shadow_offset_ &&
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           drop_shadow_color_ == other.drop_shadow_color_;
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (type_ == REFERENCE)
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return image_filter_.get() == other.image_filter_.get();
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (type_ == ALPHA_THRESHOLD) {
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return region_ == other.region_ &&
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        amount_ == other.amount_ &&
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        outer_threshold_ == other.outer_threshold_;
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return amount_ == other.amount_;
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochFilterOperation::FilterOperation(FilterType type, float amount)
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : type_(type),
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      amount_(amount),
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      outer_threshold_(0),
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      drop_shadow_offset_(0, 0),
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      drop_shadow_color_(0),
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      zoom_inset_(0) {
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_NE(type_, DROP_SHADOW);
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_NE(type_, COLOR_MATRIX);
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK_NE(type_, REFERENCE);
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  memset(matrix_, 0, sizeof(matrix_));
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochFilterOperation::FilterOperation(FilterType type,
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 const gfx::Point& offset,
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 float stdDeviation,
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 SkColor color)
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : type_(type),
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      amount_(stdDeviation),
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      outer_threshold_(0),
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      drop_shadow_offset_(offset),
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      drop_shadow_color_(color),
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      zoom_inset_(0) {
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_EQ(type_, DROP_SHADOW);
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  memset(matrix_, 0, sizeof(matrix_));
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochFilterOperation::FilterOperation(FilterType type, SkScalar matrix[20])
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : type_(type),
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      amount_(0),
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      outer_threshold_(0),
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      drop_shadow_offset_(0, 0),
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      drop_shadow_color_(0),
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      zoom_inset_(0) {
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_EQ(type_, COLOR_MATRIX);
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  memcpy(matrix_, matrix, sizeof(matrix_));
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochFilterOperation::FilterOperation(FilterType type, float amount, int inset)
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : type_(type),
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      amount_(amount),
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      outer_threshold_(0),
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      drop_shadow_offset_(0, 0),
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      drop_shadow_color_(0),
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      zoom_inset_(inset) {
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_EQ(type_, ZOOM);
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  memset(matrix_, 0, sizeof(matrix_));
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)FilterOperation::FilterOperation(
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    FilterType type,
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const skia::RefPtr<SkImageFilter>& image_filter)
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : type_(type),
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      amount_(0),
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      outer_threshold_(0),
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      drop_shadow_offset_(0, 0),
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      drop_shadow_color_(0),
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      image_filter_(image_filter),
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      zoom_inset_(0) {
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK_EQ(type_, REFERENCE);
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  memset(matrix_, 0, sizeof(matrix_));
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
980529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochFilterOperation::FilterOperation(FilterType type,
990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                 const SkRegion& region,
1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                 float inner_threshold,
1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                 float outer_threshold)
1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : type_(type),
1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      amount_(inner_threshold),
1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      outer_threshold_(outer_threshold),
1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      drop_shadow_offset_(0, 0),
1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      drop_shadow_color_(0),
1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      zoom_inset_(0),
1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      region_(region) {
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK_EQ(type_, ALPHA_THRESHOLD);
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  memset(matrix_, 0, sizeof(matrix_));
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)FilterOperation::FilterOperation(const FilterOperation& other)
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : type_(other.type_),
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      amount_(other.amount_),
1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      outer_threshold_(other.outer_threshold_),
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      drop_shadow_offset_(other.drop_shadow_offset_),
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      drop_shadow_color_(other.drop_shadow_color_),
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      image_filter_(other.image_filter_),
1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      zoom_inset_(other.zoom_inset_),
1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      region_(other.region_) {
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  memcpy(matrix_, other.matrix_, sizeof(matrix_));
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)FilterOperation::~FilterOperation() {
12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstatic FilterOperation CreateNoOpFilter(FilterOperation::FilterType type) {
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  switch (type) {
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::GRAYSCALE:
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateGrayscaleFilter(0.f);
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::SEPIA:
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateSepiaFilter(0.f);
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::SATURATE:
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateSaturateFilter(1.f);
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::HUE_ROTATE:
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateHueRotateFilter(0.f);
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::INVERT:
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateInvertFilter(0.f);
1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::BRIGHTNESS:
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateBrightnessFilter(1.f);
1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::CONTRAST:
1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateContrastFilter(1.f);
1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::OPACITY:
1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateOpacityFilter(1.f);
1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::BLUR:
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateBlurFilter(0.f);
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::DROP_SHADOW:
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateDropShadowFilter(
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          gfx::Point(0, 0), 0.f, SK_ColorTRANSPARENT);
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::COLOR_MATRIX: {
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      SkScalar matrix[20];
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      memset(matrix, 0, 20 * sizeof(SkScalar));
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f;
1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateColorMatrixFilter(matrix);
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::ZOOM:
1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateZoomFilter(1.f, 0);
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::SATURATING_BRIGHTNESS:
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return FilterOperation::CreateSaturatingBrightnessFilter(0.f);
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case FilterOperation::REFERENCE:
16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return FilterOperation::CreateReferenceFilter(
16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          skia::RefPtr<SkImageFilter>());
1640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    case FilterOperation::ALPHA_THRESHOLD:
1650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return FilterOperation::CreateAlphaThresholdFilter(SkRegion(), 1.f, 0.f);
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  NOTREACHED();
168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return FilterOperation::CreateEmptyFilter();
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstatic float ClampAmountForFilterType(float amount,
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      FilterOperation::FilterType type) {
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  switch (type) {
1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::GRAYSCALE:
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::SEPIA:
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::INVERT:
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::OPACITY:
1780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    case FilterOperation::ALPHA_THRESHOLD:
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return MathUtil::ClampToRange(amount, 0.f, 1.f);
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::SATURATE:
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::BRIGHTNESS:
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::CONTRAST:
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::BLUR:
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::DROP_SHADOW:
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return std::max(amount, 0.f);
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::ZOOM:
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return std::max(amount, 1.f);
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::HUE_ROTATE:
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::SATURATING_BRIGHTNESS:
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return amount;
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case FilterOperation::COLOR_MATRIX:
19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case FilterOperation::REFERENCE:
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NOTREACHED();
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return amount;
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  NOTREACHED();
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return amount;
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochFilterOperation FilterOperation::Blend(const FilterOperation* from,
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const FilterOperation* to,
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       double progress) {
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FilterOperation blended_filter = FilterOperation::CreateEmptyFilter();
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!from && !to)
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return blended_filter;
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const FilterOperation& from_op = from ? *from : CreateNoOpFilter(to->type());
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const FilterOperation& to_op = to ? *to : CreateNoOpFilter(from->type());
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (from_op.type() != to_op.type())
2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return blended_filter;
2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(to_op.type() != FilterOperation::COLOR_MATRIX);
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  blended_filter.set_type(to_op.type());
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (to_op.type() == FilterOperation::REFERENCE) {
21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (progress > 0.5)
22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      blended_filter.set_image_filter(to_op.image_filter());
22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    else
22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      blended_filter.set_image_filter(from_op.image_filter());
22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return blended_filter;
22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  blended_filter.set_amount(ClampAmountForFilterType(
2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      gfx::Tween::FloatValueBetween(progress, from_op.amount(), to_op.amount()),
2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      to_op.type()));
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (to_op.type() == FilterOperation::DROP_SHADOW) {
2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::Point blended_offset(
2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        gfx::Tween::LinearIntValueBetween(progress,
2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                          from_op.drop_shadow_offset().x(),
2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                          to_op.drop_shadow_offset().x()),
2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        gfx::Tween::LinearIntValueBetween(progress,
2361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                          from_op.drop_shadow_offset().y(),
2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                          to_op.drop_shadow_offset().y()));
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    blended_filter.set_drop_shadow_offset(blended_offset);
2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    blended_filter.set_drop_shadow_color(gfx::Tween::ColorValueBetween(
2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        progress, from_op.drop_shadow_color(), to_op.drop_shadow_color()));
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else if (to_op.type() == FilterOperation::ZOOM) {
2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    blended_filter.set_zoom_inset(
2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        std::max(gfx::Tween::LinearIntValueBetween(
2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                     from_op.zoom_inset(), to_op.zoom_inset(), progress),
2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 0));
2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else if (to_op.type() == FilterOperation::ALPHA_THRESHOLD) {
2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    blended_filter.set_outer_threshold(ClampAmountForFilterType(
2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            gfx::Tween::FloatValueBetween(progress,
2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                          from_op.outer_threshold(),
2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                          to_op.outer_threshold()),
2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            to_op.type()));
2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    blended_filter.set_region(to_op.region());
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return blended_filter;
2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void FilterOperation::AsValueInto(base::debug::TracedValue* value) const {
259ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  value->SetInteger("type", type_);
260ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  switch (type_) {
261ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::GRAYSCALE:
262ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::SEPIA:
263ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::SATURATE:
264ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::HUE_ROTATE:
265ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::INVERT:
266ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::BRIGHTNESS:
267ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::CONTRAST:
268ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::OPACITY:
269ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::BLUR:
270ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::SATURATING_BRIGHTNESS:
271ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      value->SetDouble("amount", amount_);
272ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      break;
273ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::DROP_SHADOW:
274ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      value->SetDouble("std_deviation", amount_);
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      value->BeginArray("offset");
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      MathUtil::AddToTracedValue(drop_shadow_offset_, value);
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      value->EndArray();
278ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      value->SetInteger("color", drop_shadow_color_);
279ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      break;
280ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::COLOR_MATRIX: {
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      value->BeginArray("matrix");
282ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      for (size_t i = 0; i < arraysize(matrix_); ++i)
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        value->AppendDouble(matrix_[i]);
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      value->EndArray();
285ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      break;
286ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
287ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FilterOperation::ZOOM:
288ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      value->SetDouble("amount", amount_);
289ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      value->SetDouble("inset", zoom_inset_);
290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      break;
29168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case FilterOperation::REFERENCE: {
29268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      int count_inputs = 0;
29368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      bool can_filter_image_gpu = false;
29468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (image_filter_) {
29568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        count_inputs = image_filter_->countInputs();
29668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        can_filter_image_gpu = image_filter_->canFilterImageGPU();
29768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
29868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      value->SetBoolean("is_null", !image_filter_);
29968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      value->SetInteger("count_inputs", count_inputs);
30068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      value->SetBoolean("can_filter_image_gpu", can_filter_image_gpu);
30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      break;
30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
3030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    case FilterOperation::ALPHA_THRESHOLD: {
3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        value->SetDouble("inner_threshold", amount_);
3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        value->SetDouble("outer_threshold", outer_threshold_);
3060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        scoped_ptr<base::ListValue> region_value(new base::ListValue());
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        value->BeginArray("region");
3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        for (SkRegion::Iterator it(region_); !it.done(); it.next()) {
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          value->AppendInteger(it.rect().x());
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          value->AppendInteger(it.rect().y());
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          value->AppendInteger(it.rect().width());
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          value->AppendInteger(it.rect().height());
3130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        }
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        value->EndArray();
3150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
3160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      break;
317ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
318ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
319ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace cc
321