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 "base/message_loop.h" | 5 #include "base/message_loop.h" |
6 #include "cc/layers/append_quads_data.h" | 6 #include "cc/layers/append_quads_data.h" |
7 #include "cc/output/gl_renderer.h" | 7 #include "cc/output/gl_renderer.h" |
8 #include "cc/quads/draw_quad.h" | 8 #include "cc/quads/draw_quad.h" |
| 9 #include "cc/quads/picture_draw_quad.h" |
| 10 #include "cc/resources/platform_color.h" |
9 #include "cc/resources/sync_point_helper.h" | 11 #include "cc/resources/sync_point_helper.h" |
| 12 #include "cc/test/fake_picture_pile_impl.h" |
10 #include "cc/test/pixel_test.h" | 13 #include "cc/test/pixel_test.h" |
11 #include "gpu/GLES2/gl2extchromium.h" | 14 #include "gpu/GLES2/gl2extchromium.h" |
12 #include "third_party/skia/include/core/SkImageFilter.h" | 15 #include "third_party/skia/include/core/SkImageFilter.h" |
13 #include "third_party/skia/include/core/SkMatrix.h" | 16 #include "third_party/skia/include/core/SkMatrix.h" |
14 #include "third_party/skia/include/effects/SkColorFilterImageFilter.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 "ui/gfx/rect_conversions.h" |
16 | 20 |
17 namespace cc { | 21 namespace cc { |
18 namespace { | 22 namespace { |
19 | 23 |
20 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPass::Id id, | 24 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPass::Id id, |
21 gfx::Rect rect) { | 25 gfx::Rect rect) { |
22 scoped_ptr<RenderPass> pass = RenderPass::Create(); | 26 scoped_ptr<RenderPass> pass = RenderPass::Create(); |
23 const gfx::Rect output_rect = rect; | 27 const gfx::Rect output_rect = rect; |
24 const gfx::RectF damage_rect = rect; | 28 const gfx::RectF damage_rect = rect; |
25 const gfx::Transform transform_to_root_target; | 29 const gfx::Transform transform_to_root_target; |
(...skipping 22 matching lines...) Expand all Loading... |
48 scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create(); | 52 scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create(); |
49 shared_state->SetAll(content_to_target_transform, | 53 shared_state->SetAll(content_to_target_transform, |
50 content_bounds, | 54 content_bounds, |
51 visible_content_rect, | 55 visible_content_rect, |
52 clip_rect, | 56 clip_rect, |
53 is_clipped, | 57 is_clipped, |
54 opacity); | 58 opacity); |
55 return shared_state.Pass(); | 59 return shared_state.Pass(); |
56 } | 60 } |
57 | 61 |
| 62 scoped_ptr<SharedQuadState> CreateTestSharedQuadStateClipped( |
| 63 gfx::Transform content_to_target_transform, |
| 64 gfx::Rect rect, |
| 65 gfx::Rect clip_rect) { |
| 66 const gfx::Size content_bounds = rect.size(); |
| 67 const gfx::Rect visible_content_rect = clip_rect; |
| 68 const bool is_clipped = true; |
| 69 const float opacity = 1.0f; |
| 70 scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create(); |
| 71 shared_state->SetAll(content_to_target_transform, |
| 72 content_bounds, |
| 73 visible_content_rect, |
| 74 clip_rect, |
| 75 is_clipped, |
| 76 opacity); |
| 77 return shared_state.Pass(); |
| 78 } |
| 79 |
58 scoped_ptr<DrawQuad> CreateTestRenderPassDrawQuad( | 80 scoped_ptr<DrawQuad> CreateTestRenderPassDrawQuad( |
59 SharedQuadState* shared_state, gfx::Rect rect, RenderPass::Id pass_id) { | 81 SharedQuadState* shared_state, gfx::Rect rect, RenderPass::Id pass_id) { |
60 scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create(); | 82 scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create(); |
61 quad->SetNew(shared_state, | 83 quad->SetNew(shared_state, |
62 rect, | 84 rect, |
63 pass_id, | 85 pass_id, |
64 false, // is_replica | 86 false, // is_replica |
65 0, // mask_resource_id | 87 0, // mask_resource_id |
66 rect, // contents_changed_since_last_frame | 88 rect, // contents_changed_since_last_frame |
67 gfx::RectF(), // mask_uv_rect | 89 gfx::RectF(), // mask_uv_rect |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 base::MessageLoop::current()->PostTask( | 695 base::MessageLoop::current()->PostTask( |
674 FROM_HERE, | 696 FROM_HERE, |
675 base::Bind(&OtherCallback, &other_callback_count)); | 697 base::Bind(&OtherCallback, &other_callback_count)); |
676 | 698 |
677 base::MessageLoop::current()->Run(); | 699 base::MessageLoop::current()->Run(); |
678 | 700 |
679 // The sync point should have happened. | 701 // The sync point should have happened. |
680 EXPECT_EQ(1, sync_point_callback_count); | 702 EXPECT_EQ(1, sync_point_callback_count); |
681 EXPECT_EQ(1, other_callback_count); | 703 EXPECT_EQ(1, other_callback_count); |
682 } | 704 } |
683 #endif | 705 |
| 706 TEST_F(GLRendererPixelTest, PictureDrawQuadIdentityScale) { |
| 707 gfx::Size pile_tile_size(1000, 1000); |
| 708 gfx::Rect viewport(this->device_viewport_size_); |
| 709 // TODO(enne): the renderer should figure this out on its own. |
| 710 bool contents_swizzled = !PlatformColor::SameComponentOrder(GL_RGBA); |
| 711 |
| 712 RenderPass::Id id(1, 1); |
| 713 gfx::Transform transform_to_root; |
| 714 scoped_ptr<RenderPass> pass = |
| 715 CreateTestRenderPass(id, viewport, transform_to_root); |
| 716 |
| 717 // One clipped blue quad in the lower right corner. Outside the clip |
| 718 // is red, which should not appear. |
| 719 gfx::Rect blue_rect(gfx::Size(100, 100)); |
| 720 gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50)); |
| 721 scoped_refptr<FakePicturePileImpl> blue_pile = |
| 722 FakePicturePileImpl::CreateFilledPile(pile_tile_size, blue_rect.size()); |
| 723 SkPaint red_paint; |
| 724 red_paint.setColor(SK_ColorRED); |
| 725 blue_pile->add_draw_rect_with_paint(blue_rect, red_paint); |
| 726 SkPaint blue_paint; |
| 727 blue_paint.setColor(SK_ColorBLUE); |
| 728 blue_pile->add_draw_rect_with_paint(blue_clip_rect, blue_paint); |
| 729 blue_pile->RerecordPile(); |
| 730 |
| 731 gfx::Transform blue_content_to_target_transform; |
| 732 gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right()); |
| 733 blue_content_to_target_transform.Translate(offset.x(), offset.y()); |
| 734 gfx::RectF blue_scissor_rect = blue_clip_rect; |
| 735 blue_content_to_target_transform.TransformRect(&blue_scissor_rect); |
| 736 scoped_ptr<SharedQuadState> blue_shared_state = |
| 737 CreateTestSharedQuadStateClipped(blue_content_to_target_transform, |
| 738 blue_rect, |
| 739 gfx::ToEnclosingRect(blue_scissor_rect)); |
| 740 |
| 741 scoped_ptr<PictureDrawQuad> blue_quad = PictureDrawQuad::Create(); |
| 742 |
| 743 blue_quad->SetNew(blue_shared_state.get(), |
| 744 viewport, // Intentionally bigger than clip. |
| 745 gfx::Rect(), |
| 746 viewport, |
| 747 viewport.size(), |
| 748 contents_swizzled, |
| 749 viewport, |
| 750 1.f, |
| 751 blue_pile); |
| 752 pass->quad_list.push_back(blue_quad.PassAs<DrawQuad>()); |
| 753 |
| 754 // One viewport-filling green quad. |
| 755 scoped_refptr<FakePicturePileImpl> green_pile = |
| 756 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); |
| 757 SkPaint green_paint; |
| 758 green_paint.setColor(SK_ColorGREEN); |
| 759 green_pile->add_draw_rect_with_paint(viewport, green_paint); |
| 760 green_pile->RerecordPile(); |
| 761 |
| 762 gfx::Transform green_content_to_target_transform; |
| 763 scoped_ptr<SharedQuadState> green_shared_state = |
| 764 CreateTestSharedQuadState(green_content_to_target_transform, viewport); |
| 765 |
| 766 scoped_ptr<PictureDrawQuad> green_quad = PictureDrawQuad::Create(); |
| 767 green_quad->SetNew(green_shared_state.get(), |
| 768 viewport, |
| 769 gfx::Rect(), |
| 770 gfx::RectF(0.f, 0.f, 1.f, 1.f), |
| 771 viewport.size(), |
| 772 contents_swizzled, |
| 773 viewport, |
| 774 1.f, |
| 775 green_pile); |
| 776 pass->quad_list.push_back(green_quad.PassAs<DrawQuad>()); |
| 777 |
| 778 RenderPassList pass_list; |
| 779 pass_list.push_back(pass.Pass()); |
| 780 |
| 781 EXPECT_TRUE(this->RunPixelTest( |
| 782 &pass_list, |
| 783 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")), |
| 784 ExactPixelComparator(true))); |
| 785 } |
| 786 |
| 787 TEST_F(GLRendererPixelTest, PictureDrawQuadNonIdentityScale) { |
| 788 gfx::Size pile_tile_size(1000, 1000); |
| 789 gfx::Rect viewport(gfx::Size(200, 200)); |
| 790 // TODO(enne): the renderer should figure this out on its own. |
| 791 bool contents_swizzled = !PlatformColor::SameComponentOrder(GL_RGBA); |
| 792 |
| 793 RenderPass::Id id(1, 1); |
| 794 gfx::Transform transform_to_root; |
| 795 scoped_ptr<RenderPass> pass = |
| 796 CreateTestRenderPass(id, viewport, transform_to_root); |
| 797 |
| 798 // As scaling up the blue checkerboards will cause sampling on the GPU, |
| 799 // a few extra "cleanup rects" need to be added to clobber the blending |
| 800 // to make the output image more clean. This will also test subrects |
| 801 // of the layer. |
| 802 gfx::Transform green_content_to_target_transform; |
| 803 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100)); |
| 804 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20)); |
| 805 scoped_refptr<FakePicturePileImpl> green_pile = |
| 806 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); |
| 807 SkPaint red_paint; |
| 808 red_paint.setColor(SK_ColorRED); |
| 809 green_pile->add_draw_rect_with_paint(viewport, red_paint); |
| 810 SkPaint green_paint; |
| 811 green_paint.setColor(SK_ColorGREEN); |
| 812 green_pile->add_draw_rect_with_paint(green_rect1, green_paint); |
| 813 green_pile->add_draw_rect_with_paint(green_rect2, green_paint); |
| 814 green_pile->RerecordPile(); |
| 815 |
| 816 scoped_ptr<SharedQuadState> top_right_green_shared_quad_state = |
| 817 CreateTestSharedQuadState(green_content_to_target_transform, viewport); |
| 818 |
| 819 scoped_ptr<PictureDrawQuad> green_quad1 = PictureDrawQuad::Create(); |
| 820 green_quad1->SetNew(top_right_green_shared_quad_state.get(), |
| 821 green_rect1, |
| 822 gfx::Rect(), |
| 823 green_rect1, |
| 824 green_rect1.size(), |
| 825 contents_swizzled, |
| 826 green_rect1, |
| 827 1.f, |
| 828 green_pile); |
| 829 pass->quad_list.push_back(green_quad1.PassAs<DrawQuad>()); |
| 830 |
| 831 scoped_ptr<PictureDrawQuad> green_quad2 = PictureDrawQuad::Create(); |
| 832 green_quad2->SetNew(top_right_green_shared_quad_state.get(), |
| 833 green_rect2, |
| 834 gfx::Rect(), |
| 835 green_rect2, |
| 836 green_rect2.size(), |
| 837 contents_swizzled, |
| 838 green_rect2, |
| 839 1.f, |
| 840 green_pile); |
| 841 pass->quad_list.push_back(green_quad2.PassAs<DrawQuad>()); |
| 842 |
| 843 // Add a green clipped checkerboard in the bottom right to help test |
| 844 // interleaving picture quad content and solid color content. |
| 845 gfx::Rect bottom_right_rect( |
| 846 gfx::Point(viewport.width() / 2, viewport.height() / 2), |
| 847 gfx::Size(viewport.width() / 2, viewport.height() / 2)); |
| 848 scoped_ptr<SharedQuadState> bottom_right_green_shared_state = |
| 849 CreateTestSharedQuadStateClipped( |
| 850 green_content_to_target_transform, viewport, bottom_right_rect); |
| 851 scoped_ptr<SolidColorDrawQuad> bottom_right_color_quad = |
| 852 SolidColorDrawQuad::Create(); |
| 853 bottom_right_color_quad->SetNew( |
| 854 bottom_right_green_shared_state.get(), viewport, SK_ColorGREEN); |
| 855 pass->quad_list.push_back(bottom_right_color_quad.PassAs<DrawQuad>()); |
| 856 |
| 857 // Add two blue checkerboards taking up the bottom left and top right, |
| 858 // but use content scales as content rects to make this happen. |
| 859 // The content is at a 4x content scale. |
| 860 gfx::Rect layer_rect(gfx::Size(20, 30)); |
| 861 float contents_scale = 4.f; |
| 862 // Two rects that touch at their corners, arbitrarily placed in the layer. |
| 863 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f)); |
| 864 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f)); |
| 865 gfx::RectF union_layer_rect = blue_layer_rect1; |
| 866 union_layer_rect.Union(blue_layer_rect2); |
| 867 |
| 868 // Because scaling up will cause sampling outside the rects, add one extra |
| 869 // pixel of buffer at the final content scale. |
| 870 float inset = -1.f / contents_scale; |
| 871 blue_layer_rect1.Inset(inset, inset, inset, inset); |
| 872 blue_layer_rect2.Inset(inset, inset, inset, inset); |
| 873 |
| 874 scoped_refptr<FakePicturePileImpl> pile = |
| 875 FakePicturePileImpl::CreateFilledPile(pile_tile_size, layer_rect.size()); |
| 876 pile->add_draw_rect_with_paint(layer_rect, red_paint); |
| 877 SkPaint transparent_paint; |
| 878 transparent_paint.setXfermodeMode(SkXfermode::kClear_Mode); |
| 879 pile->add_draw_rect_with_paint(union_layer_rect, transparent_paint); |
| 880 SkPaint blue_paint; |
| 881 blue_paint.setColor(SK_ColorBLUE); |
| 882 pile->add_draw_rect_with_paint(blue_layer_rect1, blue_paint); |
| 883 pile->add_draw_rect_with_paint(blue_layer_rect2, blue_paint); |
| 884 pile->RerecordPile(); |
| 885 |
| 886 gfx::Rect content_rect( |
| 887 gfx::ToEnclosingRect(gfx::ScaleRect(layer_rect, contents_scale))); |
| 888 gfx::Rect content_union_rect( |
| 889 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale))); |
| 890 |
| 891 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels, |
| 892 // so scale an additional 10x to make them 100x100. |
| 893 gfx::Transform content_to_target_transform; |
| 894 content_to_target_transform.Scale(10.0, 10.0); |
| 895 gfx::Rect quad_content_rect(gfx::Size(20, 20)); |
| 896 scoped_ptr<SharedQuadState> blue_shared_state = |
| 897 CreateTestSharedQuadState(content_to_target_transform, quad_content_rect); |
| 898 |
| 899 scoped_ptr<PictureDrawQuad> blue_quad = PictureDrawQuad::Create(); |
| 900 blue_quad->SetNew(blue_shared_state.get(), |
| 901 quad_content_rect, |
| 902 gfx::Rect(), |
| 903 quad_content_rect, |
| 904 content_union_rect.size(), |
| 905 contents_swizzled, |
| 906 content_union_rect, |
| 907 contents_scale, |
| 908 pile); |
| 909 pass->quad_list.push_back(blue_quad.PassAs<DrawQuad>()); |
| 910 |
| 911 // Fill left half of viewport with green. |
| 912 gfx::Transform half_green_content_to_target_transform; |
| 913 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height())); |
| 914 scoped_ptr<SharedQuadState> half_green_shared_state = |
| 915 CreateTestSharedQuadState(half_green_content_to_target_transform, |
| 916 half_green_rect); |
| 917 scoped_ptr<SolidColorDrawQuad> half_color_quad = SolidColorDrawQuad::Create(); |
| 918 half_color_quad->SetNew( |
| 919 half_green_shared_state.get(), half_green_rect, SK_ColorGREEN); |
| 920 pass->quad_list.push_back(half_color_quad.PassAs<DrawQuad>()); |
| 921 |
| 922 RenderPassList pass_list; |
| 923 pass_list.push_back(pass.Pass()); |
| 924 |
| 925 EXPECT_TRUE(this->RunPixelTest( |
| 926 &pass_list, |
| 927 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), |
| 928 ExactPixelComparator(true))); |
| 929 } |
| 930 |
| 931 #endif // !defined(OS_ANDROID) |
684 | 932 |
685 } // namespace | 933 } // namespace |
686 } // namespace cc | 934 } // namespace cc |
OLD | NEW |