| OLD | NEW | 
|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "cc/output/render_surface_filters.h" | 5 #include "cc/output/render_surface_filters.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 | 8 | 
| 9 #include "base/logging.h" | 9 #include "base/logging.h" | 
|  | 10 #include "cc/output/filter_operation.h" | 
|  | 11 #include "cc/output/filter_operations.h" | 
| 10 #include "skia/ext/refptr.h" | 12 #include "skia/ext/refptr.h" | 
| 11 #include "third_party/WebKit/public/platform/WebFilterOperation.h" |  | 
| 12 #include "third_party/WebKit/public/platform/WebFilterOperations.h" |  | 
| 13 #include "third_party/skia/include/core/SkCanvas.h" | 13 #include "third_party/skia/include/core/SkCanvas.h" | 
| 14 #include "third_party/skia/include/effects/SkBlurImageFilter.h" | 14 #include "third_party/skia/include/effects/SkBlurImageFilter.h" | 
| 15 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | 15 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | 
| 16 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" | 16 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" | 
| 17 #include "third_party/skia/include/gpu/SkGpuDevice.h" | 17 #include "third_party/skia/include/gpu/SkGpuDevice.h" | 
| 18 #include "third_party/skia/include/gpu/SkGrPixelRef.h" | 18 #include "third_party/skia/include/gpu/SkGrPixelRef.h" | 
| 19 #include "ui/gfx/size_f.h" | 19 #include "ui/gfx/size_f.h" | 
| 20 | 20 | 
| 21 namespace cc { | 21 namespace cc { | 
| 22 | 22 | 
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 177   return (max_value > 1.f) || (min_value < 0.f); | 177   return (max_value > 1.f) || (min_value < 0.f); | 
| 178 } | 178 } | 
| 179 | 179 | 
| 180 bool MatrixNeedsClamping(SkScalar matrix[20]) { | 180 bool MatrixNeedsClamping(SkScalar matrix[20]) { | 
| 181   return ComponentNeedsClamping(matrix) | 181   return ComponentNeedsClamping(matrix) | 
| 182       || ComponentNeedsClamping(matrix+5) | 182       || ComponentNeedsClamping(matrix+5) | 
| 183       || ComponentNeedsClamping(matrix+10) | 183       || ComponentNeedsClamping(matrix+10) | 
| 184       || ComponentNeedsClamping(matrix+15); | 184       || ComponentNeedsClamping(matrix+15); | 
| 185 } | 185 } | 
| 186 | 186 | 
| 187 bool GetColorMatrix(const WebKit::WebFilterOperation& op, SkScalar matrix[20]) { | 187 bool GetColorMatrix(const FilterOperation& op, SkScalar matrix[20]) { | 
| 188   switch (op.type()) { | 188   switch (op.type()) { | 
| 189     case WebKit::WebFilterOperation::FilterTypeBrightness: { | 189     case FilterOperation::BRIGHTNESS: { | 
| 190       GetBrightnessMatrix(op.amount(), matrix); | 190       GetBrightnessMatrix(op.amount(), matrix); | 
| 191       return true; | 191       return true; | 
| 192     } | 192     } | 
| 193     case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness: { | 193     case FilterOperation::SATURATING_BRIGHTNESS: { | 
| 194       GetSaturatingBrightnessMatrix(op.amount(), matrix); | 194       GetSaturatingBrightnessMatrix(op.amount(), matrix); | 
| 195       return true; | 195       return true; | 
| 196     } | 196     } | 
| 197     case WebKit::WebFilterOperation::FilterTypeContrast: { | 197     case FilterOperation::CONTRAST: { | 
| 198       GetContrastMatrix(op.amount(), matrix); | 198       GetContrastMatrix(op.amount(), matrix); | 
| 199       return true; | 199       return true; | 
| 200     } | 200     } | 
| 201     case WebKit::WebFilterOperation::FilterTypeGrayscale: { | 201     case FilterOperation::GRAYSCALE: { | 
| 202       GetGrayscaleMatrix(1.f - op.amount(), matrix); | 202       GetGrayscaleMatrix(1.f - op.amount(), matrix); | 
| 203       return true; | 203       return true; | 
| 204     } | 204     } | 
| 205     case WebKit::WebFilterOperation::FilterTypeSepia: { | 205     case FilterOperation::SEPIA: { | 
| 206       GetSepiaMatrix(1.f - op.amount(), matrix); | 206       GetSepiaMatrix(1.f - op.amount(), matrix); | 
| 207       return true; | 207       return true; | 
| 208     } | 208     } | 
| 209     case WebKit::WebFilterOperation::FilterTypeSaturate: { | 209     case FilterOperation::SATURATE: { | 
| 210       GetSaturateMatrix(op.amount(), matrix); | 210       GetSaturateMatrix(op.amount(), matrix); | 
| 211       return true; | 211       return true; | 
| 212     } | 212     } | 
| 213     case WebKit::WebFilterOperation::FilterTypeHueRotate: { | 213     case FilterOperation::HUE_ROTATE: { | 
| 214       GetHueRotateMatrix(op.amount(), matrix); | 214       GetHueRotateMatrix(op.amount(), matrix); | 
| 215       return true; | 215       return true; | 
| 216     } | 216     } | 
| 217     case WebKit::WebFilterOperation::FilterTypeInvert: { | 217     case FilterOperation::INVERT: { | 
| 218       GetInvertMatrix(op.amount(), matrix); | 218       GetInvertMatrix(op.amount(), matrix); | 
| 219       return true; | 219       return true; | 
| 220     } | 220     } | 
| 221     case WebKit::WebFilterOperation::FilterTypeOpacity: { | 221     case FilterOperation::OPACITY: { | 
| 222       GetOpacityMatrix(op.amount(), matrix); | 222       GetOpacityMatrix(op.amount(), matrix); | 
| 223       return true; | 223       return true; | 
| 224     } | 224     } | 
| 225     case WebKit::WebFilterOperation::FilterTypeColorMatrix: { | 225     case FilterOperation::COLOR_MATRIX: { | 
| 226       memcpy(matrix, op.matrix(), sizeof(SkScalar[20])); | 226       memcpy(matrix, op.matrix(), sizeof(SkScalar[20])); | 
| 227       return true; | 227       return true; | 
| 228     } | 228     } | 
| 229     default: | 229     default: | 
| 230       return false; | 230       return false; | 
| 231   } | 231   } | 
| 232 } | 232 } | 
| 233 | 233 | 
| 234 class FilterBufferState { | 234 class FilterBufferState { | 
| 235  public: | 235  public: | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 304   GrContext* gr_context_; | 304   GrContext* gr_context_; | 
| 305   SkBitmap source_; | 305   SkBitmap source_; | 
| 306   skia::RefPtr<GrTexture> scratch_textures_[2]; | 306   skia::RefPtr<GrTexture> scratch_textures_[2]; | 
| 307   int current_texture_; | 307   int current_texture_; | 
| 308   skia::RefPtr<SkGpuDevice> device_; | 308   skia::RefPtr<SkGpuDevice> device_; | 
| 309   skia::RefPtr<SkCanvas> canvas_; | 309   skia::RefPtr<SkCanvas> canvas_; | 
| 310 }; | 310 }; | 
| 311 | 311 | 
| 312 }  // namespace | 312 }  // namespace | 
| 313 | 313 | 
| 314 WebKit::WebFilterOperations RenderSurfaceFilters::Optimize( | 314 FilterOperations RenderSurfaceFilters::Optimize( | 
| 315     const WebKit::WebFilterOperations& filters) { | 315     const FilterOperations& filters) { | 
| 316   WebKit::WebFilterOperations new_list; | 316   FilterOperations new_list; | 
| 317 | 317 | 
| 318   SkScalar accumulated_color_matrix[20]; | 318   SkScalar accumulated_color_matrix[20]; | 
| 319   bool have_accumulated_color_matrix = false; | 319   bool have_accumulated_color_matrix = false; | 
| 320   for (unsigned i = 0; i < filters.size(); ++i) { | 320   for (unsigned i = 0; i < filters.size(); ++i) { | 
| 321     const WebKit::WebFilterOperation& op = filters.at(i); | 321     const FilterOperation& op = filters.at(i); | 
| 322 | 322 | 
| 323     // If the filter is a color matrix, we may be able to combine it with | 323     // If the filter is a color matrix, we may be able to combine it with | 
| 324     // following Filter(s) that also are color matrices. | 324     // following Filter(s) that also are color matrices. | 
| 325     SkScalar matrix[20]; | 325     SkScalar matrix[20]; | 
| 326     if (GetColorMatrix(op, matrix)) { | 326     if (GetColorMatrix(op, matrix)) { | 
| 327       if (have_accumulated_color_matrix) { | 327       if (have_accumulated_color_matrix) { | 
| 328         SkScalar new_matrix[20]; | 328         SkScalar new_matrix[20]; | 
| 329         MultColorMatrix(matrix, accumulated_color_matrix, new_matrix); | 329         MultColorMatrix(matrix, accumulated_color_matrix, new_matrix); | 
| 330         memcpy(accumulated_color_matrix, | 330         memcpy(accumulated_color_matrix, | 
| 331                new_matrix, | 331                new_matrix, | 
| 332                sizeof(accumulated_color_matrix)); | 332                sizeof(accumulated_color_matrix)); | 
| 333       } else { | 333       } else { | 
| 334         memcpy(accumulated_color_matrix, | 334         memcpy(accumulated_color_matrix, | 
| 335                matrix, | 335                matrix, | 
| 336                sizeof(accumulated_color_matrix)); | 336                sizeof(accumulated_color_matrix)); | 
| 337         have_accumulated_color_matrix = true; | 337         have_accumulated_color_matrix = true; | 
| 338       } | 338       } | 
| 339 | 339 | 
| 340       // We can only combine matrices if clamping of color components | 340       // We can only combine matrices if clamping of color components | 
| 341       // would have no effect. | 341       // would have no effect. | 
| 342       if (!MatrixNeedsClamping(accumulated_color_matrix)) | 342       if (!MatrixNeedsClamping(accumulated_color_matrix)) | 
| 343         continue; | 343         continue; | 
| 344     } | 344     } | 
| 345 | 345 | 
| 346     if (have_accumulated_color_matrix) { | 346     if (have_accumulated_color_matrix) { | 
| 347       new_list.append(WebKit::WebFilterOperation::createColorMatrixFilter( | 347       new_list.Append(FilterOperation::CreateColorMatrixFilter( | 
| 348           accumulated_color_matrix)); | 348           accumulated_color_matrix)); | 
| 349     } | 349     } | 
| 350     have_accumulated_color_matrix = false; | 350     have_accumulated_color_matrix = false; | 
| 351 | 351 | 
| 352     switch (op.type()) { | 352     switch (op.type()) { | 
| 353       case WebKit::WebFilterOperation::FilterTypeBlur: | 353       case FilterOperation::BLUR: | 
| 354       case WebKit::WebFilterOperation::FilterTypeDropShadow: | 354       case FilterOperation::DROP_SHADOW: | 
| 355       case WebKit::WebFilterOperation::FilterTypeZoom: | 355       case FilterOperation::ZOOM: | 
| 356         new_list.append(op); | 356         new_list.Append(op); | 
| 357         break; | 357         break; | 
| 358       case WebKit::WebFilterOperation::FilterTypeBrightness: | 358       case FilterOperation::BRIGHTNESS: | 
| 359       case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness: | 359       case FilterOperation::SATURATING_BRIGHTNESS: | 
| 360       case WebKit::WebFilterOperation::FilterTypeContrast: | 360       case FilterOperation::CONTRAST: | 
| 361       case WebKit::WebFilterOperation::FilterTypeGrayscale: | 361       case FilterOperation::GRAYSCALE: | 
| 362       case WebKit::WebFilterOperation::FilterTypeSepia: | 362       case FilterOperation::SEPIA: | 
| 363       case WebKit::WebFilterOperation::FilterTypeSaturate: | 363       case FilterOperation::SATURATE: | 
| 364       case WebKit::WebFilterOperation::FilterTypeHueRotate: | 364       case FilterOperation::HUE_ROTATE: | 
| 365       case WebKit::WebFilterOperation::FilterTypeInvert: | 365       case FilterOperation::INVERT: | 
| 366       case WebKit::WebFilterOperation::FilterTypeOpacity: | 366       case FilterOperation::OPACITY: | 
| 367       case WebKit::WebFilterOperation::FilterTypeColorMatrix: | 367       case FilterOperation::COLOR_MATRIX: | 
| 368         break; | 368         break; | 
| 369     } | 369     } | 
| 370   } | 370   } | 
| 371   if (have_accumulated_color_matrix) { | 371   if (have_accumulated_color_matrix) { | 
| 372     new_list.append(WebKit::WebFilterOperation::createColorMatrixFilter( | 372     new_list.Append(FilterOperation::CreateColorMatrixFilter( | 
| 373         accumulated_color_matrix)); | 373         accumulated_color_matrix)); | 
| 374   } | 374   } | 
| 375   return new_list; | 375   return new_list; | 
| 376 } | 376 } | 
| 377 | 377 | 
| 378 SkBitmap RenderSurfaceFilters::Apply(const WebKit::WebFilterOperations& filters, | 378 SkBitmap RenderSurfaceFilters::Apply(const FilterOperations& filters, | 
| 379                                      unsigned texture_id, | 379                                      unsigned texture_id, | 
| 380                                      gfx::SizeF size, | 380                                      gfx::SizeF size, | 
| 381                                      GrContext* gr_context) { | 381                                      GrContext* gr_context) { | 
| 382   DCHECK(gr_context); | 382   DCHECK(gr_context); | 
| 383 | 383 | 
| 384   WebKit::WebFilterOperations optimized_filters = Optimize(filters); | 384   FilterOperations optimized_filters = Optimize(filters); | 
| 385   FilterBufferState state(gr_context, size, texture_id); | 385   FilterBufferState state(gr_context, size, texture_id); | 
| 386   if (!state.Init(optimized_filters.size())) | 386   if (!state.Init(optimized_filters.size())) | 
| 387     return SkBitmap(); | 387     return SkBitmap(); | 
| 388 | 388 | 
| 389   for (unsigned i = 0; i < optimized_filters.size(); ++i) { | 389   for (unsigned i = 0; i < optimized_filters.size(); ++i) { | 
| 390     const WebKit::WebFilterOperation& op = optimized_filters.at(i); | 390     const FilterOperation& op = optimized_filters.at(i); | 
| 391     SkCanvas* canvas = state.Canvas(); | 391     SkCanvas* canvas = state.Canvas(); | 
| 392     switch (op.type()) { | 392     switch (op.type()) { | 
| 393       case WebKit::WebFilterOperation::FilterTypeColorMatrix: { | 393       case FilterOperation::COLOR_MATRIX: { | 
| 394         SkPaint paint; | 394         SkPaint paint; | 
| 395         skia::RefPtr<SkColorMatrixFilter> filter = | 395         skia::RefPtr<SkColorMatrixFilter> filter = | 
| 396             skia::AdoptRef(new SkColorMatrixFilter(op.matrix())); | 396             skia::AdoptRef(new SkColorMatrixFilter(op.matrix())); | 
| 397         paint.setColorFilter(filter.get()); | 397         paint.setColorFilter(filter.get()); | 
| 398         canvas->drawBitmap(state.Source(), 0, 0, &paint); | 398         canvas->drawBitmap(state.Source(), 0, 0, &paint); | 
| 399         break; | 399         break; | 
| 400       } | 400       } | 
| 401       case WebKit::WebFilterOperation::FilterTypeBlur: { | 401       case FilterOperation::BLUR: { | 
| 402         float std_deviation = op.amount(); | 402         float std_deviation = op.amount(); | 
| 403         skia::RefPtr<SkImageFilter> filter = | 403         skia::RefPtr<SkImageFilter> filter = | 
| 404             skia::AdoptRef(new SkBlurImageFilter(std_deviation, std_deviation)); | 404             skia::AdoptRef(new SkBlurImageFilter(std_deviation, std_deviation)); | 
| 405         SkPaint paint; | 405         SkPaint paint; | 
| 406         paint.setImageFilter(filter.get()); | 406         paint.setImageFilter(filter.get()); | 
| 407         canvas->drawSprite(state.Source(), 0, 0, &paint); | 407         canvas->drawSprite(state.Source(), 0, 0, &paint); | 
| 408         break; | 408         break; | 
| 409       } | 409       } | 
| 410       case WebKit::WebFilterOperation::FilterTypeDropShadow: { | 410       case FilterOperation::DROP_SHADOW: { | 
| 411         skia::RefPtr<SkImageFilter> blur_filter = | 411         skia::RefPtr<SkImageFilter> blur_filter = | 
| 412             skia::AdoptRef(new SkBlurImageFilter(op.amount(), op.amount())); | 412             skia::AdoptRef(new SkBlurImageFilter(op.amount(), op.amount())); | 
| 413         skia::RefPtr<SkColorFilter> color_filter = | 413         skia::RefPtr<SkColorFilter> color_filter = | 
| 414             skia::AdoptRef(SkColorFilter::CreateModeFilter( | 414             skia::AdoptRef(SkColorFilter::CreateModeFilter( | 
| 415                 op.dropShadowColor(), SkXfermode::kSrcIn_Mode)); | 415                 op.drop_shadow_color(), SkXfermode::kSrcIn_Mode)); | 
| 416         SkPaint paint; | 416         SkPaint paint; | 
| 417         paint.setImageFilter(blur_filter.get()); | 417         paint.setImageFilter(blur_filter.get()); | 
| 418         paint.setColorFilter(color_filter.get()); | 418         paint.setColorFilter(color_filter.get()); | 
| 419         paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | 419         paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | 
| 420         canvas->saveLayer(NULL, &paint); | 420         canvas->saveLayer(NULL, &paint); | 
| 421         canvas->drawBitmap(state.Source(), | 421         canvas->drawBitmap(state.Source(), | 
| 422                            op.dropShadowOffset().x, | 422                            op.drop_shadow_offset().x(), | 
| 423                            op.dropShadowOffset().y); | 423                            op.drop_shadow_offset().y()); | 
| 424         canvas->restore(); | 424         canvas->restore(); | 
| 425         canvas->drawBitmap(state.Source(), 0, 0); | 425         canvas->drawBitmap(state.Source(), 0, 0); | 
| 426         break; | 426         break; | 
| 427       } | 427       } | 
| 428       case WebKit::WebFilterOperation::FilterTypeZoom: { | 428       case FilterOperation::ZOOM: { | 
| 429         SkPaint paint; | 429         SkPaint paint; | 
| 430         int width = state.Source().width(); | 430         int width = state.Source().width(); | 
| 431         int height = state.Source().height(); | 431         int height = state.Source().height(); | 
| 432         skia::RefPtr<SkImageFilter> zoom_filter = skia::AdoptRef( | 432         skia::RefPtr<SkImageFilter> zoom_filter = skia::AdoptRef( | 
| 433             new SkMagnifierImageFilter( | 433             new SkMagnifierImageFilter( | 
| 434                 SkRect::MakeXYWH( | 434                 SkRect::MakeXYWH( | 
| 435                     (width - (width / op.amount())) / 2.f, | 435                     (width - (width / op.amount())) / 2.f, | 
| 436                     (height - (height / op.amount())) / 2.f, | 436                     (height - (height / op.amount())) / 2.f, | 
| 437                     width / op.amount(), | 437                     width / op.amount(), | 
| 438                     height / op.amount()), | 438                     height / op.amount()), | 
| 439                 op.zoomInset())); | 439                 op.zoom_inset())); | 
| 440         paint.setImageFilter(zoom_filter.get()); | 440         paint.setImageFilter(zoom_filter.get()); | 
| 441         canvas->saveLayer(NULL, &paint); | 441         canvas->saveLayer(NULL, &paint); | 
| 442         canvas->drawBitmap(state.Source(), 0, 0); | 442         canvas->drawBitmap(state.Source(), 0, 0); | 
| 443         canvas->restore(); | 443         canvas->restore(); | 
| 444         break; | 444         break; | 
| 445       } | 445       } | 
| 446       case WebKit::WebFilterOperation::FilterTypeBrightness: | 446       case FilterOperation::BRIGHTNESS: | 
| 447       case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness: | 447       case FilterOperation::SATURATING_BRIGHTNESS: | 
| 448       case WebKit::WebFilterOperation::FilterTypeContrast: | 448       case FilterOperation::CONTRAST: | 
| 449       case WebKit::WebFilterOperation::FilterTypeGrayscale: | 449       case FilterOperation::GRAYSCALE: | 
| 450       case WebKit::WebFilterOperation::FilterTypeSepia: | 450       case FilterOperation::SEPIA: | 
| 451       case WebKit::WebFilterOperation::FilterTypeSaturate: | 451       case FilterOperation::SATURATE: | 
| 452       case WebKit::WebFilterOperation::FilterTypeHueRotate: | 452       case FilterOperation::HUE_ROTATE: | 
| 453       case WebKit::WebFilterOperation::FilterTypeInvert: | 453       case FilterOperation::INVERT: | 
| 454       case WebKit::WebFilterOperation::FilterTypeOpacity: | 454       case FilterOperation::OPACITY: | 
| 455         NOTREACHED(); | 455         NOTREACHED(); | 
| 456         break; | 456         break; | 
| 457     } | 457     } | 
| 458     state.Swap(); | 458     state.Swap(); | 
| 459   } | 459   } | 
| 460   return state.Source(); | 460   return state.Source(); | 
| 461 } | 461 } | 
| 462 | 462 | 
| 463 }  // namespace cc | 463 }  // namespace cc | 
| OLD | NEW | 
|---|