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" | 10 #include "cc/output/filter_operation.h" |
11 #include "cc/output/filter_operations.h" | 11 #include "cc/output/filter_operations.h" |
12 #include "skia/ext/refptr.h" | 12 #include "skia/ext/refptr.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/core/SkFlattenableBuffers.h" |
| 15 #include "third_party/skia/include/core/SkImageFilter.h" |
14 #include "third_party/skia/include/effects/SkBlurImageFilter.h" | 16 #include "third_party/skia/include/effects/SkBlurImageFilter.h" |
| 17 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" |
15 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | 18 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" |
| 19 #include "third_party/skia/include/effects/SkComposeImageFilter.h" |
| 20 #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" |
16 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" | 21 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" |
17 #include "third_party/skia/include/gpu/SkGpuDevice.h" | 22 #include "third_party/skia/include/gpu/SkGpuDevice.h" |
18 #include "third_party/skia/include/gpu/SkGrPixelRef.h" | 23 #include "third_party/skia/include/gpu/SkGrPixelRef.h" |
19 #include "ui/gfx/size_f.h" | 24 #include "ui/gfx/size_f.h" |
20 | 25 |
21 namespace cc { | 26 namespace cc { |
22 | 27 |
23 namespace { | 28 namespace { |
24 | 29 |
25 void GetBrightnessMatrix(float amount, SkScalar matrix[20]) { | 30 void GetBrightnessMatrix(float amount, SkScalar matrix[20]) { |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 GetOpacityMatrix(op.amount(), matrix); | 227 GetOpacityMatrix(op.amount(), matrix); |
223 return true; | 228 return true; |
224 } | 229 } |
225 case FilterOperation::COLOR_MATRIX: { | 230 case FilterOperation::COLOR_MATRIX: { |
226 memcpy(matrix, op.matrix(), sizeof(SkScalar[20])); | 231 memcpy(matrix, op.matrix(), sizeof(SkScalar[20])); |
227 return true; | 232 return true; |
228 } | 233 } |
229 case FilterOperation::BLUR: | 234 case FilterOperation::BLUR: |
230 case FilterOperation::DROP_SHADOW: | 235 case FilterOperation::DROP_SHADOW: |
231 case FilterOperation::ZOOM: | 236 case FilterOperation::ZOOM: |
| 237 case FilterOperation::REFERENCE: |
232 return false; | 238 return false; |
233 } | 239 } |
234 NOTREACHED(); | 240 NOTREACHED(); |
235 return false; | 241 return false; |
236 } | 242 } |
237 | 243 |
| 244 skia::RefPtr<SkImageFilter> CreateMatrixImageFilter( |
| 245 const SkScalar matrix[20], |
| 246 const skia::RefPtr<SkImageFilter>& input) { |
| 247 skia::RefPtr<SkColorFilter> color_filter = |
| 248 skia::AdoptRef(new SkColorMatrixFilter(matrix)); |
| 249 return skia::AdoptRef( |
| 250 SkColorFilterImageFilter::Create(color_filter.get(), input.get())); |
| 251 } |
| 252 |
238 class FilterBufferState { | 253 class FilterBufferState { |
239 public: | 254 public: |
240 FilterBufferState(GrContext* gr_context, | 255 FilterBufferState(GrContext* gr_context, |
241 gfx::SizeF size, | 256 gfx::SizeF size, |
242 unsigned texture_id) | 257 unsigned texture_id) |
243 : gr_context_(gr_context), | 258 : gr_context_(gr_context), |
244 current_texture_(0) { | 259 current_texture_(0) { |
245 // Wrap the source texture in a Ganesh platform texture. | 260 // Wrap the source texture in a Ganesh platform texture. |
246 GrBackendTextureDesc backend_texture_description; | 261 GrBackendTextureDesc backend_texture_description; |
247 backend_texture_description.fWidth = size.width(); | 262 backend_texture_description.fWidth = size.width(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 accumulated_color_matrix)); | 367 accumulated_color_matrix)); |
353 } | 368 } |
354 have_accumulated_color_matrix = false; | 369 have_accumulated_color_matrix = false; |
355 | 370 |
356 switch (op.type()) { | 371 switch (op.type()) { |
357 case FilterOperation::BLUR: | 372 case FilterOperation::BLUR: |
358 case FilterOperation::DROP_SHADOW: | 373 case FilterOperation::DROP_SHADOW: |
359 case FilterOperation::ZOOM: | 374 case FilterOperation::ZOOM: |
360 new_list.Append(op); | 375 new_list.Append(op); |
361 break; | 376 break; |
| 377 case FilterOperation::REFERENCE: |
| 378 // Not supported on this code path. |
| 379 NOTREACHED(); |
362 case FilterOperation::BRIGHTNESS: | 380 case FilterOperation::BRIGHTNESS: |
363 case FilterOperation::SATURATING_BRIGHTNESS: | 381 case FilterOperation::SATURATING_BRIGHTNESS: |
364 case FilterOperation::CONTRAST: | 382 case FilterOperation::CONTRAST: |
365 case FilterOperation::GRAYSCALE: | 383 case FilterOperation::GRAYSCALE: |
366 case FilterOperation::SEPIA: | 384 case FilterOperation::SEPIA: |
367 case FilterOperation::SATURATE: | 385 case FilterOperation::SATURATE: |
368 case FilterOperation::HUE_ROTATE: | 386 case FilterOperation::HUE_ROTATE: |
369 case FilterOperation::INVERT: | 387 case FilterOperation::INVERT: |
370 case FilterOperation::OPACITY: | 388 case FilterOperation::OPACITY: |
371 case FilterOperation::COLOR_MATRIX: | 389 case FilterOperation::COLOR_MATRIX: |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 (height - (height / op.amount())) / 2.f, | 457 (height - (height / op.amount())) / 2.f, |
440 width / op.amount(), | 458 width / op.amount(), |
441 height / op.amount()), | 459 height / op.amount()), |
442 op.zoom_inset())); | 460 op.zoom_inset())); |
443 paint.setImageFilter(zoom_filter.get()); | 461 paint.setImageFilter(zoom_filter.get()); |
444 canvas->saveLayer(NULL, &paint); | 462 canvas->saveLayer(NULL, &paint); |
445 canvas->drawBitmap(state.Source(), 0, 0); | 463 canvas->drawBitmap(state.Source(), 0, 0); |
446 canvas->restore(); | 464 canvas->restore(); |
447 break; | 465 break; |
448 } | 466 } |
| 467 case FilterOperation::REFERENCE: |
449 case FilterOperation::BRIGHTNESS: | 468 case FilterOperation::BRIGHTNESS: |
450 case FilterOperation::SATURATING_BRIGHTNESS: | 469 case FilterOperation::SATURATING_BRIGHTNESS: |
451 case FilterOperation::CONTRAST: | 470 case FilterOperation::CONTRAST: |
452 case FilterOperation::GRAYSCALE: | 471 case FilterOperation::GRAYSCALE: |
453 case FilterOperation::SEPIA: | 472 case FilterOperation::SEPIA: |
454 case FilterOperation::SATURATE: | 473 case FilterOperation::SATURATE: |
455 case FilterOperation::HUE_ROTATE: | 474 case FilterOperation::HUE_ROTATE: |
456 case FilterOperation::INVERT: | 475 case FilterOperation::INVERT: |
457 case FilterOperation::OPACITY: | 476 case FilterOperation::OPACITY: |
458 NOTREACHED(); | 477 NOTREACHED(); |
459 break; | 478 break; |
460 } | 479 } |
461 state.Swap(); | 480 state.Swap(); |
462 } | 481 } |
463 return state.Source(); | 482 return state.Source(); |
464 } | 483 } |
465 | 484 |
| 485 skia::RefPtr<SkImageFilter> RenderSurfaceFilters::BuildImageFilter( |
| 486 const FilterOperations& filters, |
| 487 gfx::SizeF size) { |
| 488 skia::RefPtr<SkImageFilter> image_filter; |
| 489 SkScalar matrix[20]; |
| 490 for (size_t i = 0; i < filters.size(); ++i) { |
| 491 const FilterOperation& op = filters.at(i); |
| 492 switch (op.type()) { |
| 493 case FilterOperation::GRAYSCALE: |
| 494 GetGrayscaleMatrix(1.f - op.amount(), matrix); |
| 495 image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| 496 break; |
| 497 case FilterOperation::SEPIA: |
| 498 GetSepiaMatrix(1.f - op.amount(), matrix); |
| 499 image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| 500 break; |
| 501 case FilterOperation::SATURATE: |
| 502 GetSaturateMatrix(op.amount(), matrix); |
| 503 image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| 504 break; |
| 505 case FilterOperation::HUE_ROTATE: |
| 506 GetHueRotateMatrix(op.amount(), matrix); |
| 507 image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| 508 break; |
| 509 case FilterOperation::INVERT: |
| 510 GetInvertMatrix(op.amount(), matrix); |
| 511 image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| 512 break; |
| 513 case FilterOperation::OPACITY: |
| 514 GetOpacityMatrix(op.amount(), matrix); |
| 515 image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| 516 break; |
| 517 case FilterOperation::BRIGHTNESS: |
| 518 GetBrightnessMatrix(op.amount(), matrix); |
| 519 image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| 520 break; |
| 521 case FilterOperation::CONTRAST: |
| 522 GetContrastMatrix(op.amount(), matrix); |
| 523 image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| 524 break; |
| 525 case FilterOperation::BLUR: |
| 526 image_filter = skia::AdoptRef(new SkBlurImageFilter( |
| 527 op.amount(), op.amount(), image_filter.get())); |
| 528 break; |
| 529 case FilterOperation::DROP_SHADOW: |
| 530 image_filter = skia::AdoptRef(new SkDropShadowImageFilter( |
| 531 SkIntToScalar(op.drop_shadow_offset().x()), |
| 532 SkIntToScalar(op.drop_shadow_offset().y()), |
| 533 SkIntToScalar(op.amount()), |
| 534 op.drop_shadow_color(), |
| 535 image_filter.get())); |
| 536 break; |
| 537 case FilterOperation::COLOR_MATRIX: |
| 538 image_filter = CreateMatrixImageFilter(op.matrix(), image_filter); |
| 539 break; |
| 540 case FilterOperation::ZOOM: { |
| 541 skia::RefPtr<SkImageFilter> zoom_filter = skia::AdoptRef( |
| 542 new SkMagnifierImageFilter( |
| 543 SkRect::MakeXYWH( |
| 544 (size.width() - (size.width() / op.amount())) / 2.f, |
| 545 (size.height() - (size.height() / op.amount())) / 2.f, |
| 546 size.width() / op.amount(), |
| 547 size.height() / op.amount()), |
| 548 op.zoom_inset())); |
| 549 if (image_filter.get()) { |
| 550 // TODO(ajuma): When there's a 1-input version of |
| 551 // SkMagnifierImageFilter, use that to handle the input filter |
| 552 // instead of using an SkComposeImageFilter. |
| 553 image_filter = skia::AdoptRef(new SkComposeImageFilter( |
| 554 zoom_filter.get(), image_filter.get())); |
| 555 } else { |
| 556 image_filter = zoom_filter; |
| 557 } |
| 558 break; |
| 559 } |
| 560 case FilterOperation::SATURATING_BRIGHTNESS: |
| 561 GetSaturatingBrightnessMatrix(op.amount(), matrix); |
| 562 image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| 563 break; |
| 564 case FilterOperation::REFERENCE: { |
| 565 if (!op.image_filter()) |
| 566 break; |
| 567 |
| 568 skia::RefPtr<SkColorFilter> cf; |
| 569 |
| 570 { |
| 571 SkColorFilter* colorfilter_rawptr = NULL; |
| 572 op.image_filter()->asColorFilter(&colorfilter_rawptr); |
| 573 cf = skia::AdoptRef(colorfilter_rawptr); |
| 574 } |
| 575 |
| 576 if (cf && cf->asColorMatrix(matrix) && |
| 577 !op.image_filter()->getInput(0)) { |
| 578 image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| 579 } else if (image_filter) { |
| 580 image_filter = skia::AdoptRef(new SkComposeImageFilter( |
| 581 op.image_filter().get(), image_filter.get())); |
| 582 } else { |
| 583 image_filter = op.image_filter(); |
| 584 } |
| 585 break; |
| 586 } |
| 587 } |
| 588 } |
| 589 return image_filter; |
| 590 } |
| 591 |
466 } // namespace cc | 592 } // namespace cc |
OLD | NEW |