| 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/software_renderer.h" | 5 #include "cc/output/software_renderer.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/trace_event/trace_event.h" | 8 #include "base/trace_event/trace_event.h" |
| 9 #include "cc/base/math_util.h" | 9 #include "cc/base/math_util.h" |
| 10 #include "cc/output/copy_output_request.h" | 10 #include "cc/output/copy_output_request.h" |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 | 463 |
| 464 SkRect dest_rect = gfx::RectFToSkRect(QuadVertexRect()); | 464 SkRect dest_rect = gfx::RectFToSkRect(QuadVertexRect()); |
| 465 SkRect dest_visible_rect = gfx::RectFToSkRect( | 465 SkRect dest_visible_rect = gfx::RectFToSkRect( |
| 466 MathUtil::ScaleRectProportional(QuadVertexRect(), gfx::RectF(quad->rect), | 466 MathUtil::ScaleRectProportional(QuadVertexRect(), gfx::RectF(quad->rect), |
| 467 gfx::RectF(quad->visible_rect))); | 467 gfx::RectF(quad->visible_rect))); |
| 468 SkRect content_rect = SkRect::MakeWH(quad->rect.width(), quad->rect.height()); | 468 SkRect content_rect = SkRect::MakeWH(quad->rect.width(), quad->rect.height()); |
| 469 | 469 |
| 470 const SkBitmap* content = lock.sk_bitmap(); | 470 const SkBitmap* content = lock.sk_bitmap(); |
| 471 | 471 |
| 472 sk_sp<SkImage> filter_image; | 472 sk_sp<SkImage> filter_image; |
| 473 if (!quad->filters.IsEmpty()) { | 473 const FilterOperations* filters = FiltersForPass(quad->render_pass_id); |
| 474 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( | 474 if (filters) { |
| 475 quad->filters, gfx::SizeF(content_texture->size())); | 475 DCHECK(!filters->IsEmpty()); |
| 476 if (filter) { | 476 sk_sp<SkImageFilter> image_filter = RenderSurfaceFilters::BuildImageFilter( |
| 477 *filters, gfx::SizeF(content_texture->size())); |
| 478 if (image_filter) { |
| 477 SkIRect result_rect; | 479 SkIRect result_rect; |
| 478 // TODO(ajuma): Apply the filter in the same pass as the content where | 480 // TODO(ajuma): Apply the filter in the same pass as the content where |
| 479 // possible (e.g. when there's no origin offset). See crbug.com/308201. | 481 // possible (e.g. when there's no origin offset). See crbug.com/308201. |
| 480 filter_image = | 482 filter_image = |
| 481 ApplyImageFilter(filter.get(), quad, *content, &result_rect); | 483 ApplyImageFilter(image_filter.get(), quad, *content, &result_rect); |
| 482 if (result_rect.isEmpty()) { | 484 if (result_rect.isEmpty()) { |
| 483 return; | 485 return; |
| 484 } | 486 } |
| 485 if (filter_image) { | 487 if (filter_image) { |
| 486 gfx::RectF rect = gfx::SkRectToRectF(SkRect::Make(result_rect)); | 488 gfx::RectF rect = gfx::SkRectToRectF(SkRect::Make(result_rect)); |
| 487 dest_rect = dest_visible_rect = | 489 dest_rect = dest_visible_rect = |
| 488 gfx::RectFToSkRect(MathUtil::ScaleRectProportional( | 490 gfx::RectFToSkRect(MathUtil::ScaleRectProportional( |
| 489 QuadVertexRect(), gfx::RectF(quad->rect), rect)); | 491 QuadVertexRect(), gfx::RectF(quad->rect), rect)); |
| 490 content_rect = | 492 content_rect = |
| 491 SkRect::MakeWH(result_rect.width(), result_rect.height()); | 493 SkRect::MakeWH(result_rect.width(), result_rect.height()); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 } | 583 } |
| 582 | 584 |
| 583 void SoftwareRenderer::DidChangeVisibility() { | 585 void SoftwareRenderer::DidChangeVisibility() { |
| 584 if (visible_) | 586 if (visible_) |
| 585 output_surface_->EnsureBackbuffer(); | 587 output_surface_->EnsureBackbuffer(); |
| 586 else | 588 else |
| 587 output_surface_->DiscardBackbuffer(); | 589 output_surface_->DiscardBackbuffer(); |
| 588 } | 590 } |
| 589 | 591 |
| 590 bool SoftwareRenderer::ShouldApplyBackgroundFilters( | 592 bool SoftwareRenderer::ShouldApplyBackgroundFilters( |
| 591 const RenderPassDrawQuad* quad) const { | 593 const RenderPassDrawQuad* quad, |
| 592 if (quad->background_filters.IsEmpty()) | 594 const FilterOperations* background_filters) const { |
| 595 if (!background_filters) |
| 593 return false; | 596 return false; |
| 597 DCHECK(!background_filters->IsEmpty()); |
| 594 | 598 |
| 595 // TODO(hendrikw): Look into allowing background filters to see pixels from | 599 // TODO(hendrikw): Look into allowing background filters to see pixels from |
| 596 // other render targets. See crbug.com/314867. | 600 // other render targets. See crbug.com/314867. |
| 597 | 601 |
| 598 return true; | 602 return true; |
| 599 } | 603 } |
| 600 | 604 |
| 601 // If non-null, auto_bounds will be filled with the automatically-computed | 605 // If non-null, auto_bounds will be filled with the automatically-computed |
| 602 // destination bounds. If null, the output will be the same size as the | 606 // destination bounds. If null, the output will be the same size as the |
| 603 // input bitmap. | 607 // input bitmap. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 bitmap.setInfo(SkImageInfo::MakeN32Premul(bounding_rect.width(), | 651 bitmap.setInfo(SkImageInfo::MakeN32Premul(bounding_rect.width(), |
| 648 bounding_rect.height())); | 652 bounding_rect.height())); |
| 649 current_canvas_->readPixels(&bitmap, bounding_rect.x(), bounding_rect.y()); | 653 current_canvas_->readPixels(&bitmap, bounding_rect.x(), bounding_rect.y()); |
| 650 return bitmap; | 654 return bitmap; |
| 651 } | 655 } |
| 652 | 656 |
| 653 gfx::Rect SoftwareRenderer::GetBackdropBoundingBoxForRenderPassQuad( | 657 gfx::Rect SoftwareRenderer::GetBackdropBoundingBoxForRenderPassQuad( |
| 654 const DrawingFrame* frame, | 658 const DrawingFrame* frame, |
| 655 const RenderPassDrawQuad* quad, | 659 const RenderPassDrawQuad* quad, |
| 656 const gfx::Transform& contents_device_transform, | 660 const gfx::Transform& contents_device_transform, |
| 661 const FilterOperations* background_filters, |
| 657 gfx::Rect* unclipped_rect) const { | 662 gfx::Rect* unclipped_rect) const { |
| 658 DCHECK(ShouldApplyBackgroundFilters(quad)); | 663 DCHECK(ShouldApplyBackgroundFilters(quad, background_filters)); |
| 659 gfx::Rect backdrop_rect = gfx::ToEnclosingRect( | 664 gfx::Rect backdrop_rect = gfx::ToEnclosingRect( |
| 660 MathUtil::MapClippedRect(contents_device_transform, QuadVertexRect())); | 665 MathUtil::MapClippedRect(contents_device_transform, QuadVertexRect())); |
| 661 | 666 |
| 662 SkMatrix matrix; | 667 SkMatrix matrix; |
| 663 matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); | 668 matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); |
| 664 backdrop_rect = | 669 backdrop_rect = background_filters->MapRectReverse(backdrop_rect, matrix); |
| 665 quad->background_filters.MapRectReverse(backdrop_rect, matrix); | |
| 666 | 670 |
| 667 *unclipped_rect = backdrop_rect; | 671 *unclipped_rect = backdrop_rect; |
| 668 backdrop_rect.Intersect(MoveFromDrawToWindowSpace( | 672 backdrop_rect.Intersect(MoveFromDrawToWindowSpace( |
| 669 frame, frame->current_render_pass->output_rect)); | 673 frame, frame->current_render_pass->output_rect)); |
| 670 | 674 |
| 671 return backdrop_rect; | 675 return backdrop_rect; |
| 672 } | 676 } |
| 673 | 677 |
| 674 sk_sp<SkShader> SoftwareRenderer::GetBackgroundFilterShader( | 678 sk_sp<SkShader> SoftwareRenderer::GetBackgroundFilterShader( |
| 675 const DrawingFrame* frame, | 679 const DrawingFrame* frame, |
| 676 const RenderPassDrawQuad* quad, | 680 const RenderPassDrawQuad* quad, |
| 677 SkShader::TileMode content_tile_mode) const { | 681 SkShader::TileMode content_tile_mode) const { |
| 678 if (!ShouldApplyBackgroundFilters(quad)) | 682 const FilterOperations* background_filters = |
| 683 BackgroundFiltersForPass(quad->render_pass_id); |
| 684 if (!ShouldApplyBackgroundFilters(quad, background_filters)) |
| 679 return nullptr; | 685 return nullptr; |
| 680 | 686 |
| 681 gfx::Transform quad_rect_matrix; | 687 gfx::Transform quad_rect_matrix; |
| 682 QuadRectTransform(&quad_rect_matrix, | 688 QuadRectTransform(&quad_rect_matrix, |
| 683 quad->shared_quad_state->quad_to_target_transform, | 689 quad->shared_quad_state->quad_to_target_transform, |
| 684 gfx::RectF(quad->rect)); | 690 gfx::RectF(quad->rect)); |
| 685 gfx::Transform contents_device_transform = | 691 gfx::Transform contents_device_transform = |
| 686 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; | 692 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; |
| 687 contents_device_transform.FlattenTo2d(); | 693 contents_device_transform.FlattenTo2d(); |
| 688 | 694 |
| 689 gfx::Rect unclipped_rect; | 695 gfx::Rect unclipped_rect; |
| 690 gfx::Rect backdrop_rect = GetBackdropBoundingBoxForRenderPassQuad( | 696 gfx::Rect backdrop_rect = GetBackdropBoundingBoxForRenderPassQuad( |
| 691 frame, quad, contents_device_transform, &unclipped_rect); | 697 frame, quad, contents_device_transform, background_filters, |
| 698 &unclipped_rect); |
| 692 | 699 |
| 693 // Figure out the transformations to move it back to pixel space. | 700 // Figure out the transformations to move it back to pixel space. |
| 694 gfx::Transform contents_device_transform_inverse; | 701 gfx::Transform contents_device_transform_inverse; |
| 695 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) | 702 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) |
| 696 return nullptr; | 703 return nullptr; |
| 697 | 704 |
| 698 SkMatrix filter_backdrop_transform = | 705 SkMatrix filter_backdrop_transform = |
| 699 contents_device_transform_inverse.matrix(); | 706 contents_device_transform_inverse.matrix(); |
| 700 filter_backdrop_transform.preTranslate(backdrop_rect.x(), backdrop_rect.y()); | 707 filter_backdrop_transform.preTranslate(backdrop_rect.x(), backdrop_rect.y()); |
| 701 | 708 |
| 702 // Draw what's behind, and apply the filter to it. | 709 // Draw what's behind, and apply the filter to it. |
| 703 SkBitmap backdrop_bitmap = GetBackdropBitmap(backdrop_rect); | 710 SkBitmap backdrop_bitmap = GetBackdropBitmap(backdrop_rect); |
| 704 | 711 |
| 705 gfx::Vector2dF clipping_offset = | 712 gfx::Vector2dF clipping_offset = |
| 706 (unclipped_rect.top_right() - backdrop_rect.top_right()) + | 713 (unclipped_rect.top_right() - backdrop_rect.top_right()) + |
| 707 (backdrop_rect.bottom_left() - unclipped_rect.bottom_left()); | 714 (backdrop_rect.bottom_left() - unclipped_rect.bottom_left()); |
| 708 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( | 715 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( |
| 709 quad->background_filters, | 716 *background_filters, |
| 710 gfx::SizeF(backdrop_bitmap.width(), backdrop_bitmap.height()), | 717 gfx::SizeF(backdrop_bitmap.width(), backdrop_bitmap.height()), |
| 711 clipping_offset); | 718 clipping_offset); |
| 712 sk_sp<SkImage> filter_backdrop_image = | 719 sk_sp<SkImage> filter_backdrop_image = |
| 713 ApplyImageFilter(filter.get(), quad, backdrop_bitmap, nullptr); | 720 ApplyImageFilter(filter.get(), quad, backdrop_bitmap, nullptr); |
| 714 | 721 |
| 715 if (!filter_backdrop_image) | 722 if (!filter_backdrop_image) |
| 716 return nullptr; | 723 return nullptr; |
| 717 | 724 |
| 718 return filter_backdrop_image->makeShader(content_tile_mode, content_tile_mode, | 725 return filter_backdrop_image->makeShader(content_tile_mode, content_tile_mode, |
| 719 &filter_backdrop_transform); | 726 &filter_backdrop_transform); |
| 720 } | 727 } |
| 721 | 728 |
| 722 } // namespace cc | 729 } // namespace cc |
| OLD | NEW |