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 |