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