1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "cc/layers/append_quads_data.h" 6 #include "cc/layers/ui_resource_layer_impl.h" 7 #include "cc/resources/ui_resource_bitmap.h" 8 #include "cc/resources/ui_resource_client.h" 9 #include "cc/test/fake_impl_proxy.h" 10 #include "cc/test/fake_layer_tree_host_impl.h" 11 #include "cc/test/fake_ui_resource_layer_tree_host_impl.h" 12 #include "cc/test/layer_test_common.h" 13 #include "cc/test/mock_quad_culler.h" 14 #include "cc/test/test_shared_bitmap_manager.h" 15 #include "cc/trees/single_thread_proxy.h" 16 #include "testing/gmock/include/gmock/gmock.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 #include "ui/gfx/transform.h" 19 20 namespace cc { 21 namespace { 22 23 scoped_ptr<UIResourceLayerImpl> GenerateUIResourceLayer( 24 FakeUIResourceLayerTreeHostImpl* host_impl, 25 const gfx::Size& bitmap_size, 26 const gfx::Size& layer_size, 27 bool opaque, 28 UIResourceId uid) { 29 gfx::Rect visible_content_rect(layer_size); 30 scoped_ptr<UIResourceLayerImpl> layer = 31 UIResourceLayerImpl::Create(host_impl->active_tree(), 1); 32 layer->draw_properties().visible_content_rect = visible_content_rect; 33 layer->SetBounds(layer_size); 34 layer->SetContentBounds(layer_size); 35 layer->CreateRenderSurface(); 36 layer->draw_properties().render_target = layer.get(); 37 38 UIResourceBitmap bitmap(bitmap_size, opaque); 39 40 host_impl->CreateUIResource(uid, bitmap); 41 layer->SetUIResourceId(uid); 42 43 return layer.Pass(); 44 } 45 46 void QuadSizeTest(scoped_ptr<UIResourceLayerImpl> layer, 47 size_t expected_quad_size) { 48 MockOcclusionTracker<LayerImpl> occlusion_tracker; 49 scoped_ptr<RenderPass> render_pass = RenderPass::Create(); 50 MockQuadCuller quad_culler(render_pass.get(), &occlusion_tracker); 51 52 AppendQuadsData data; 53 layer->AppendQuads(&quad_culler, &data); 54 55 // Verify quad rects 56 const QuadList& quads = quad_culler.quad_list(); 57 EXPECT_EQ(expected_quad_size, quads.size()); 58 } 59 60 TEST(UIResourceLayerImplTest, VerifyDrawQuads) { 61 FakeImplProxy proxy; 62 TestSharedBitmapManager shared_bitmap_manager; 63 FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager); 64 // Make sure we're appending quads when there are valid values. 65 gfx::Size bitmap_size(100, 100); 66 gfx::Size layer_size(100, 100);; 67 size_t expected_quad_size = 1; 68 bool opaque = true; 69 UIResourceId uid = 1; 70 scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer(&host_impl, 71 bitmap_size, 72 layer_size, 73 opaque, 74 uid); 75 QuadSizeTest(layer.Pass(), expected_quad_size); 76 77 // Make sure we're not appending quads when there are invalid values. 78 expected_quad_size = 0; 79 uid = 0; 80 layer = GenerateUIResourceLayer(&host_impl, 81 bitmap_size, 82 layer_size, 83 opaque, 84 uid); 85 QuadSizeTest(layer.Pass(), expected_quad_size); 86 } 87 88 void OpaqueBoundsTest(scoped_ptr<UIResourceLayerImpl> layer, 89 const gfx::Rect& expected_opaque_bounds) { 90 MockOcclusionTracker<LayerImpl> occlusion_tracker; 91 scoped_ptr<RenderPass> render_pass = RenderPass::Create(); 92 MockQuadCuller quad_culler(render_pass.get(), &occlusion_tracker); 93 94 AppendQuadsData data; 95 layer->AppendQuads(&quad_culler, &data); 96 97 // Verify quad rects 98 const QuadList& quads = quad_culler.quad_list(); 99 EXPECT_GE(quads.size(), (size_t)0); 100 gfx::Rect opaque_rect = quads.at(0)->opaque_rect; 101 EXPECT_EQ(expected_opaque_bounds, opaque_rect); 102 } 103 104 TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) { 105 FakeImplProxy proxy; 106 TestSharedBitmapManager shared_bitmap_manager; 107 FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager); 108 109 gfx::Size bitmap_size(100, 100); 110 gfx::Size layer_size(100, 100);; 111 bool opaque = false; 112 UIResourceId uid = 1; 113 scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer(&host_impl, 114 bitmap_size, 115 layer_size, 116 opaque, 117 uid); 118 gfx::Rect expected_opaque_bounds; 119 OpaqueBoundsTest(layer.Pass(), expected_opaque_bounds); 120 121 opaque = true; 122 layer = GenerateUIResourceLayer(&host_impl, 123 bitmap_size, 124 layer_size, 125 opaque, 126 uid); 127 expected_opaque_bounds = gfx::Rect(layer->bounds()); 128 OpaqueBoundsTest(layer.Pass(), expected_opaque_bounds); 129 } 130 131 TEST(UIResourceLayerImplTest, VerifySetOpaqueOnLayer) { 132 FakeImplProxy proxy; 133 TestSharedBitmapManager shared_bitmap_manager; 134 FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager); 135 136 gfx::Size bitmap_size(100, 100); 137 gfx::Size layer_size(100, 100); 138 bool skbitmap_opaque = false; 139 UIResourceId uid = 1; 140 scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer( 141 &host_impl, bitmap_size, layer_size, skbitmap_opaque, uid); 142 layer->SetContentsOpaque(false); 143 gfx::Rect expected_opaque_bounds; 144 OpaqueBoundsTest(layer.Pass(), expected_opaque_bounds); 145 146 layer = GenerateUIResourceLayer( 147 &host_impl, bitmap_size, layer_size, skbitmap_opaque, uid); 148 layer->SetContentsOpaque(true); 149 expected_opaque_bounds = gfx::Rect(layer->bounds()); 150 OpaqueBoundsTest(layer.Pass(), expected_opaque_bounds); 151 } 152 153 TEST(UIResourceLayerImplTest, Occlusion) { 154 gfx::Size layer_size(1000, 1000); 155 gfx::Size viewport_size(1000, 1000); 156 157 LayerTestCommon::LayerImplTest impl; 158 159 SkBitmap sk_bitmap; 160 sk_bitmap.allocN32Pixels(10, 10); 161 sk_bitmap.setImmutable(); 162 UIResourceId uid = 5; 163 UIResourceBitmap bitmap(sk_bitmap); 164 impl.host_impl()->CreateUIResource(uid, bitmap); 165 166 UIResourceLayerImpl* ui_resource_layer_impl = 167 impl.AddChildToRoot<UIResourceLayerImpl>(); 168 ui_resource_layer_impl->SetBounds(layer_size); 169 ui_resource_layer_impl->SetContentBounds(layer_size); 170 ui_resource_layer_impl->SetDrawsContent(true); 171 ui_resource_layer_impl->SetUIResourceId(uid); 172 173 impl.CalcDrawProps(viewport_size); 174 175 { 176 SCOPED_TRACE("No occlusion"); 177 gfx::Rect occluded; 178 impl.AppendQuadsWithOcclusion(ui_resource_layer_impl, occluded); 179 180 LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), 181 gfx::Rect(layer_size)); 182 EXPECT_EQ(1u, impl.quad_list().size()); 183 } 184 185 { 186 SCOPED_TRACE("Full occlusion"); 187 gfx::Rect occluded(ui_resource_layer_impl->visible_content_rect()); 188 impl.AppendQuadsWithOcclusion(ui_resource_layer_impl, occluded); 189 190 LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); 191 EXPECT_EQ(impl.quad_list().size(), 0u); 192 } 193 194 { 195 SCOPED_TRACE("Partial occlusion"); 196 gfx::Rect occluded(200, 0, 800, 1000); 197 impl.AppendQuadsWithOcclusion(ui_resource_layer_impl, occluded); 198 199 size_t partially_occluded_count = 0; 200 LayerTestCommon::VerifyQuadsCoverRectWithOcclusion( 201 impl.quad_list(), 202 gfx::Rect(layer_size), 203 occluded, 204 &partially_occluded_count); 205 // The layer outputs one quad, which is partially occluded. 206 EXPECT_EQ(1u, impl.quad_list().size()); 207 EXPECT_EQ(1u, partially_occluded_count); 208 } 209 } 210 211 } // namespace 212 } // namespace cc 213