Chromium Code Reviews| 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 skia::RefPtr<SkImageFilter> input) { | |
|
danakj
2013/09/09 22:04:50
const&?
ajuma
2013/09/10 21:17:58
Done.
| |
| 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 - op.amount(), matrix); | |
|
danakj
2013/09/09 22:04:50
1.f here and below
ajuma
2013/09/10 21:17:58
Done.
| |
| 495 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
| 496 break; | |
| 497 case FilterOperation::SEPIA: | |
| 498 GetSepiaMatrix(1 - 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 skia::RefPtr<SkColorFilter> cf; | |
| 566 | |
| 567 { | |
| 568 SkColorFilter* colorfilter_rawptr = NULL; | |
| 569 op.image_filter()->asColorFilter(&colorfilter_rawptr); | |
| 570 cf = skia::AdoptRef(colorfilter_rawptr); | |
| 571 } | |
| 572 | |
| 573 if (cf && cf->asColorMatrix(matrix) && | |
| 574 !op.image_filter()->getInput(0)) { | |
| 575 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
| 576 } else if (image_filter.get()) { | |
|
danakj
2013/09/09 22:04:50
do you mean else if (op.image_filter())? if so, m
ajuma
2013/09/10 21:17:58
No, this is checking if we've already build up a p
| |
| 577 image_filter = skia::AdoptRef(new SkComposeImageFilter( | |
| 578 op.image_filter().get(), image_filter.get())); | |
| 579 } else { | |
| 580 image_filter = op.image_filter(); | |
| 581 } | |
| 582 break; | |
| 583 } | |
| 584 } | |
| 585 } | |
| 586 return image_filter; | |
| 587 } | |
| 588 | |
| 466 } // namespace cc | 589 } // namespace cc |
| OLD | NEW |