| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #include "cc/output/render_surface_filters.h" |  | 
| 6 |  | 
| 7 #include <stddef.h> |  | 
| 8 |  | 
| 9 #include <algorithm> |  | 
| 10 |  | 
| 11 #include "cc/output/filter_operation.h" |  | 
| 12 #include "cc/output/filter_operations.h" |  | 
| 13 #include "third_party/skia/include/core/SkImageFilter.h" |  | 
| 14 #include "third_party/skia/include/effects/SkAlphaThresholdFilter.h" |  | 
| 15 #include "third_party/skia/include/effects/SkBlurImageFilter.h" |  | 
| 16 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" |  | 
| 17 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" |  | 
| 18 #include "third_party/skia/include/effects/SkComposeImageFilter.h" |  | 
| 19 #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" |  | 
| 20 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" |  | 
| 21 #include "ui/gfx/geometry/size_f.h" |  | 
| 22 |  | 
| 23 namespace cc { |  | 
| 24 |  | 
| 25 namespace { |  | 
| 26 |  | 
| 27 void GetBrightnessMatrix(float amount, SkScalar matrix[20]) { |  | 
| 28   // Spec implementation |  | 
| 29   // (http://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#brightnessEquiv
     alent) |  | 
| 30   // <feFunc[R|G|B] type="linear" slope="[amount]"> |  | 
| 31   memset(matrix, 0, 20 * sizeof(SkScalar)); |  | 
| 32   matrix[0] = matrix[6] = matrix[12] = amount; |  | 
| 33   matrix[18] = 1.f; |  | 
| 34 } |  | 
| 35 |  | 
| 36 void GetSaturatingBrightnessMatrix(float amount, SkScalar matrix[20]) { |  | 
| 37   // Legacy implementation used by internal clients. |  | 
| 38   // <feFunc[R|G|B] type="linear" intercept="[amount]"/> |  | 
| 39   memset(matrix, 0, 20 * sizeof(SkScalar)); |  | 
| 40   matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f; |  | 
| 41   matrix[4] = matrix[9] = matrix[14] = amount * 255.f; |  | 
| 42 } |  | 
| 43 |  | 
| 44 void GetContrastMatrix(float amount, SkScalar matrix[20]) { |  | 
| 45   memset(matrix, 0, 20 * sizeof(SkScalar)); |  | 
| 46   matrix[0] = matrix[6] = matrix[12] = amount; |  | 
| 47   matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f) * 255.f; |  | 
| 48   matrix[18] = 1.f; |  | 
| 49 } |  | 
| 50 |  | 
| 51 void GetSaturateMatrix(float amount, SkScalar matrix[20]) { |  | 
| 52   // Note, these values are computed to ensure MatrixNeedsClamping is false |  | 
| 53   // for amount in [0..1] |  | 
| 54   matrix[0] = 0.213f + 0.787f * amount; |  | 
| 55   matrix[1] = 0.715f - 0.715f * amount; |  | 
| 56   matrix[2] = 1.f - (matrix[0] + matrix[1]); |  | 
| 57   matrix[3] = matrix[4] = 0.f; |  | 
| 58   matrix[5] = 0.213f - 0.213f * amount; |  | 
| 59   matrix[6] = 0.715f + 0.285f * amount; |  | 
| 60   matrix[7] = 1.f - (matrix[5] + matrix[6]); |  | 
| 61   matrix[8] = matrix[9] = 0.f; |  | 
| 62   matrix[10] = 0.213f - 0.213f * amount; |  | 
| 63   matrix[11] = 0.715f - 0.715f * amount; |  | 
| 64   matrix[12] = 1.f - (matrix[10] + matrix[11]); |  | 
| 65   matrix[13] = matrix[14] = 0.f; |  | 
| 66   matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f; |  | 
| 67   matrix[18] = 1.f; |  | 
| 68 } |  | 
| 69 |  | 
| 70 void GetHueRotateMatrix(float hue, SkScalar matrix[20]) { |  | 
| 71   const float kPi = 3.1415926535897932384626433832795f; |  | 
| 72 |  | 
| 73   float cos_hue = cosf(hue * kPi / 180.f); |  | 
| 74   float sin_hue = sinf(hue * kPi / 180.f); |  | 
| 75   matrix[0] = 0.213f + cos_hue * 0.787f - sin_hue * 0.213f; |  | 
| 76   matrix[1] = 0.715f - cos_hue * 0.715f - sin_hue * 0.715f; |  | 
| 77   matrix[2] = 0.072f - cos_hue * 0.072f + sin_hue * 0.928f; |  | 
| 78   matrix[3] = matrix[4] = 0.f; |  | 
| 79   matrix[5] = 0.213f - cos_hue * 0.213f + sin_hue * 0.143f; |  | 
| 80   matrix[6] = 0.715f + cos_hue * 0.285f + sin_hue * 0.140f; |  | 
| 81   matrix[7] = 0.072f - cos_hue * 0.072f - sin_hue * 0.283f; |  | 
| 82   matrix[8] = matrix[9] = 0.f; |  | 
| 83   matrix[10] = 0.213f - cos_hue * 0.213f - sin_hue * 0.787f; |  | 
| 84   matrix[11] = 0.715f - cos_hue * 0.715f + sin_hue * 0.715f; |  | 
| 85   matrix[12] = 0.072f + cos_hue * 0.928f + sin_hue * 0.072f; |  | 
| 86   matrix[13] = matrix[14] = 0.f; |  | 
| 87   matrix[15] = matrix[16] = matrix[17] = 0.f; |  | 
| 88   matrix[18] = 1.f; |  | 
| 89   matrix[19] = 0.f; |  | 
| 90 } |  | 
| 91 |  | 
| 92 void GetInvertMatrix(float amount, SkScalar matrix[20]) { |  | 
| 93   memset(matrix, 0, 20 * sizeof(SkScalar)); |  | 
| 94   matrix[0] = matrix[6] = matrix[12] = 1.f - 2.f * amount; |  | 
| 95   matrix[4] = matrix[9] = matrix[14] = amount * 255.f; |  | 
| 96   matrix[18] = 1.f; |  | 
| 97 } |  | 
| 98 |  | 
| 99 void GetOpacityMatrix(float amount, SkScalar matrix[20]) { |  | 
| 100   memset(matrix, 0, 20 * sizeof(SkScalar)); |  | 
| 101   matrix[0] = matrix[6] = matrix[12] = 1.f; |  | 
| 102   matrix[18] = amount; |  | 
| 103 } |  | 
| 104 |  | 
| 105 void GetGrayscaleMatrix(float amount, SkScalar matrix[20]) { |  | 
| 106   // Note, these values are computed to ensure MatrixNeedsClamping is false |  | 
| 107   // for amount in [0..1] |  | 
| 108   matrix[0] = 0.2126f + 0.7874f * amount; |  | 
| 109   matrix[1] = 0.7152f - 0.7152f * amount; |  | 
| 110   matrix[2] = 1.f - (matrix[0] + matrix[1]); |  | 
| 111   matrix[3] = matrix[4] = 0.f; |  | 
| 112 |  | 
| 113   matrix[5] = 0.2126f - 0.2126f * amount; |  | 
| 114   matrix[6] = 0.7152f + 0.2848f * amount; |  | 
| 115   matrix[7] = 1.f - (matrix[5] + matrix[6]); |  | 
| 116   matrix[8] = matrix[9] = 0.f; |  | 
| 117 |  | 
| 118   matrix[10] = 0.2126f - 0.2126f * amount; |  | 
| 119   matrix[11] = 0.7152f - 0.7152f * amount; |  | 
| 120   matrix[12] = 1.f - (matrix[10] + matrix[11]); |  | 
| 121   matrix[13] = matrix[14] = 0.f; |  | 
| 122 |  | 
| 123   matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f; |  | 
| 124   matrix[18] = 1.f; |  | 
| 125 } |  | 
| 126 |  | 
| 127 void GetSepiaMatrix(float amount, SkScalar matrix[20]) { |  | 
| 128   matrix[0] = 0.393f + 0.607f * amount; |  | 
| 129   matrix[1] = 0.769f - 0.769f * amount; |  | 
| 130   matrix[2] = 0.189f - 0.189f * amount; |  | 
| 131   matrix[3] = matrix[4] = 0.f; |  | 
| 132 |  | 
| 133   matrix[5] = 0.349f - 0.349f * amount; |  | 
| 134   matrix[6] = 0.686f + 0.314f * amount; |  | 
| 135   matrix[7] = 0.168f - 0.168f * amount; |  | 
| 136   matrix[8] = matrix[9] = 0.f; |  | 
| 137 |  | 
| 138   matrix[10] = 0.272f - 0.272f * amount; |  | 
| 139   matrix[11] = 0.534f - 0.534f * amount; |  | 
| 140   matrix[12] = 0.131f + 0.869f * amount; |  | 
| 141   matrix[13] = matrix[14] = 0.f; |  | 
| 142 |  | 
| 143   matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f; |  | 
| 144   matrix[18] = 1.f; |  | 
| 145 } |  | 
| 146 |  | 
| 147 sk_sp<SkImageFilter> CreateMatrixImageFilter(const SkScalar matrix[20], |  | 
| 148                                              sk_sp<SkImageFilter> input) { |  | 
| 149   return SkColorFilterImageFilter::Make( |  | 
| 150       SkColorFilter::MakeMatrixFilterRowMajor255(matrix), std::move(input)); |  | 
| 151 } |  | 
| 152 |  | 
| 153 }  // namespace |  | 
| 154 |  | 
| 155 sk_sp<SkImageFilter> RenderSurfaceFilters::BuildImageFilter( |  | 
| 156     const FilterOperations& filters, |  | 
| 157     const gfx::SizeF& size, |  | 
| 158     const gfx::Vector2dF& offset) { |  | 
| 159   sk_sp<SkImageFilter> image_filter; |  | 
| 160   SkScalar matrix[20]; |  | 
| 161   for (size_t i = 0; i < filters.size(); ++i) { |  | 
| 162     const FilterOperation& op = filters.at(i); |  | 
| 163     switch (op.type()) { |  | 
| 164       case FilterOperation::GRAYSCALE: |  | 
| 165         GetGrayscaleMatrix(1.f - op.amount(), matrix); |  | 
| 166         image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); |  | 
| 167         break; |  | 
| 168       case FilterOperation::SEPIA: |  | 
| 169         GetSepiaMatrix(1.f - op.amount(), matrix); |  | 
| 170         image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); |  | 
| 171         break; |  | 
| 172       case FilterOperation::SATURATE: |  | 
| 173         GetSaturateMatrix(op.amount(), matrix); |  | 
| 174         image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); |  | 
| 175         break; |  | 
| 176       case FilterOperation::HUE_ROTATE: |  | 
| 177         GetHueRotateMatrix(op.amount(), matrix); |  | 
| 178         image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); |  | 
| 179         break; |  | 
| 180       case FilterOperation::INVERT: |  | 
| 181         GetInvertMatrix(op.amount(), matrix); |  | 
| 182         image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); |  | 
| 183         break; |  | 
| 184       case FilterOperation::OPACITY: |  | 
| 185         GetOpacityMatrix(op.amount(), matrix); |  | 
| 186         image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); |  | 
| 187         break; |  | 
| 188       case FilterOperation::BRIGHTNESS: |  | 
| 189         GetBrightnessMatrix(op.amount(), matrix); |  | 
| 190         image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); |  | 
| 191         break; |  | 
| 192       case FilterOperation::CONTRAST: |  | 
| 193         GetContrastMatrix(op.amount(), matrix); |  | 
| 194         image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); |  | 
| 195         break; |  | 
| 196       case FilterOperation::BLUR: |  | 
| 197         image_filter = SkBlurImageFilter::Make(op.amount(), op.amount(), |  | 
| 198                                                std::move(image_filter)); |  | 
| 199         break; |  | 
| 200       case FilterOperation::DROP_SHADOW: |  | 
| 201         image_filter = SkDropShadowImageFilter::Make( |  | 
| 202             SkIntToScalar(op.drop_shadow_offset().x()), |  | 
| 203             SkIntToScalar(op.drop_shadow_offset().y()), |  | 
| 204             SkIntToScalar(op.amount()), SkIntToScalar(op.amount()), |  | 
| 205             op.drop_shadow_color(), |  | 
| 206             SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, |  | 
| 207             std::move(image_filter)); |  | 
| 208         break; |  | 
| 209       case FilterOperation::COLOR_MATRIX: |  | 
| 210         image_filter = |  | 
| 211             CreateMatrixImageFilter(op.matrix(), std::move(image_filter)); |  | 
| 212         break; |  | 
| 213       case FilterOperation::ZOOM: { |  | 
| 214         // The center point, always the midpoint of the unclipped rectangle. |  | 
| 215         // When we go to either edge of the screen, the width/height will shrink |  | 
| 216         // at the same rate the offset changes. Use abs on the offset since we |  | 
| 217         // do not care about the offset direction. |  | 
| 218         gfx::Vector2dF center = |  | 
| 219             gfx::Vector2dF((size.width() + std::abs(offset.x())) / 2, |  | 
| 220                            (size.height() + std::abs(offset.y())) / 2); |  | 
| 221 |  | 
| 222         // The dimensions of the source content. This shrinks as the texture |  | 
| 223         // rectangle gets clipped. |  | 
| 224         gfx::Vector2d src_dimensions = |  | 
| 225             gfx::Vector2d((size.width() + std::abs(offset.x())) / op.amount(), |  | 
| 226                           (size.height() + std::abs(offset.y())) / op.amount()); |  | 
| 227 |  | 
| 228         // When the magnifier goes to the left/top border of the screen, we need |  | 
| 229         // to adjust the x/y position of the rect. The rate the position gets |  | 
| 230         // updated currently only works properly for a 2x magnification. |  | 
| 231         DCHECK_EQ(op.amount(), 2.f); |  | 
| 232         gfx::Vector2dF center_offset = gfx::Vector2dF(0, 0); |  | 
| 233         if (offset.x() >= 0) |  | 
| 234           center_offset.set_x(-offset.x() / op.amount()); |  | 
| 235         if (offset.y() <= 0) |  | 
| 236           center_offset.set_y(offset.y() / op.amount()); |  | 
| 237 |  | 
| 238         sk_sp<SkImageFilter> zoom_filter(SkMagnifierImageFilter::Make( |  | 
| 239             SkRect::MakeXYWH( |  | 
| 240                 (center.x() - src_dimensions.x() / 2.f) + center_offset.x(), |  | 
| 241                 (center.y() - src_dimensions.y() / 2.f) + center_offset.y(), |  | 
| 242                 size.width() / op.amount(), size.height() / op.amount()), |  | 
| 243             op.zoom_inset(), nullptr)); |  | 
| 244         if (image_filter) { |  | 
| 245           // TODO(ajuma): When there's a 1-input version of |  | 
| 246           // SkMagnifierImageFilter, use that to handle the input filter |  | 
| 247           // instead of using an SkComposeImageFilter. |  | 
| 248           image_filter = SkComposeImageFilter::Make(std::move(zoom_filter), |  | 
| 249                                                     std::move(image_filter)); |  | 
| 250         } else { |  | 
| 251           image_filter = std::move(zoom_filter); |  | 
| 252         } |  | 
| 253         break; |  | 
| 254       } |  | 
| 255       case FilterOperation::SATURATING_BRIGHTNESS: |  | 
| 256         GetSaturatingBrightnessMatrix(op.amount(), matrix); |  | 
| 257         image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); |  | 
| 258         break; |  | 
| 259       case FilterOperation::REFERENCE: { |  | 
| 260         if (!op.image_filter()) |  | 
| 261           break; |  | 
| 262 |  | 
| 263         sk_sp<SkColorFilter> cf; |  | 
| 264 |  | 
| 265         { |  | 
| 266           SkColorFilter* colorfilter_rawptr = NULL; |  | 
| 267           op.image_filter()->asColorFilter(&colorfilter_rawptr); |  | 
| 268           cf.reset(colorfilter_rawptr); |  | 
| 269         } |  | 
| 270 |  | 
| 271         if (cf && cf->asColorMatrix(matrix) && |  | 
| 272             !op.image_filter()->getInput(0)) { |  | 
| 273           image_filter = |  | 
| 274               CreateMatrixImageFilter(matrix, std::move(image_filter)); |  | 
| 275         } else if (image_filter) { |  | 
| 276           image_filter = SkComposeImageFilter::Make(op.image_filter(), |  | 
| 277                                                     std::move(image_filter)); |  | 
| 278         } else { |  | 
| 279           image_filter = op.image_filter(); |  | 
| 280         } |  | 
| 281         break; |  | 
| 282       } |  | 
| 283       case FilterOperation::ALPHA_THRESHOLD: { |  | 
| 284         sk_sp<SkImageFilter> alpha_filter = SkAlphaThresholdFilter::Make( |  | 
| 285             op.region(), op.amount(), op.outer_threshold(), nullptr); |  | 
| 286         if (image_filter) { |  | 
| 287           image_filter = SkComposeImageFilter::Make(std::move(alpha_filter), |  | 
| 288                                                     std::move(image_filter)); |  | 
| 289         } else { |  | 
| 290           image_filter = std::move(alpha_filter); |  | 
| 291         } |  | 
| 292         break; |  | 
| 293       } |  | 
| 294     } |  | 
| 295   } |  | 
| 296   return image_filter; |  | 
| 297 } |  | 
| 298 |  | 
| 299 }  // namespace cc |  | 
| OLD | NEW | 
|---|