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 3 // found in the LICENSE file. 4 5 #include <stdio.h> 6 7 #include "cc/layers/append_quads_data.h" 8 #include "cc/layers/nine_patch_layer_impl.h" 9 #include "cc/quads/texture_draw_quad.h" 10 #include "cc/test/fake_impl_proxy.h" 11 #include "cc/test/fake_layer_tree_host_impl.h" 12 #include "cc/test/geometry_test_utils.h" 13 #include "cc/test/layer_test_common.h" 14 #include "cc/test/mock_quad_culler.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/rect_conversions.h" 19 #include "ui/gfx/safe_integer_conversions.h" 20 #include "ui/gfx/transform.h" 21 22 namespace cc { 23 namespace { 24 25 gfx::Rect ToRoundedIntRect(gfx::RectF rect_f) { 26 return gfx::Rect(gfx::ToRoundedInt(rect_f.x()), 27 gfx::ToRoundedInt(rect_f.y()), 28 gfx::ToRoundedInt(rect_f.width()), 29 gfx::ToRoundedInt(rect_f.height())); 30 } 31 32 TEST(NinePatchLayerImplTest, VerifyDrawQuads) { 33 // Input is a 100x100 bitmap with a 40x50 aperture at x=20, y=30. 34 // The bounds of the layer are set to 400x400, so the draw quads 35 // generated should leave the border width (40) intact. 36 MockQuadCuller quad_culler; 37 gfx::Size bitmap_size(100, 100); 38 gfx::Size layer_size(400, 400); 39 gfx::Rect visible_content_rect(layer_size); 40 gfx::Rect aperture_rect(20, 30, 40, 50); 41 gfx::Rect scaled_aperture_non_uniform(20, 30, 340, 350); 42 43 FakeImplProxy proxy; 44 FakeLayerTreeHostImpl host_impl(&proxy); 45 scoped_ptr<NinePatchLayerImpl> layer = 46 NinePatchLayerImpl::Create(host_impl.active_tree(), 1); 47 layer->draw_properties().visible_content_rect = visible_content_rect; 48 layer->SetBounds(layer_size); 49 layer->SetContentBounds(layer_size); 50 layer->CreateRenderSurface(); 51 layer->draw_properties().render_target = layer.get(); 52 layer->SetLayout(bitmap_size, aperture_rect); 53 layer->SetResourceId(1); 54 55 // This scale should not affect the generated quad geometry, but only 56 // the shared draw transform. 57 gfx::Transform transform; 58 transform.Scale(10, 10); 59 layer->draw_properties().target_space_transform = transform; 60 61 AppendQuadsData data; 62 layer->AppendQuads(&quad_culler, &data); 63 64 // Verify quad rects 65 const QuadList& quads = quad_culler.quad_list(); 66 EXPECT_EQ(8u, quads.size()); 67 Region remaining(visible_content_rect); 68 for (size_t i = 0; i < quads.size(); ++i) { 69 DrawQuad* quad = quads[i]; 70 gfx::Rect quad_rect = quad->rect; 71 72 EXPECT_TRUE(visible_content_rect.Contains(quad_rect)) << i; 73 EXPECT_TRUE(remaining.Contains(quad_rect)) << i; 74 EXPECT_EQ(transform, quad->quadTransform()); 75 remaining.Subtract(Region(quad_rect)); 76 } 77 EXPECT_RECT_EQ(scaled_aperture_non_uniform, remaining.bounds()); 78 Region scaled_aperture_region(scaled_aperture_non_uniform); 79 EXPECT_EQ(scaled_aperture_region, remaining); 80 81 // Verify UV rects 82 gfx::Rect bitmap_rect(bitmap_size); 83 Region tex_remaining(bitmap_rect); 84 for (size_t i = 0; i < quads.size(); ++i) { 85 DrawQuad* quad = quads[i]; 86 const TextureDrawQuad* tex_quad = TextureDrawQuad::MaterialCast(quad); 87 gfx::RectF tex_rect = 88 gfx::BoundingRect(tex_quad->uv_top_left, tex_quad->uv_bottom_right); 89 tex_rect.Scale(bitmap_size.width(), bitmap_size.height()); 90 tex_remaining.Subtract(Region(ToRoundedIntRect(tex_rect))); 91 } 92 EXPECT_RECT_EQ(aperture_rect, tex_remaining.bounds()); 93 Region aperture_region(aperture_rect); 94 EXPECT_EQ(aperture_region, tex_remaining); 95 } 96 97 TEST(NinePatchLayerImplTest, VerifyDrawQuadsForSqueezedLayer) { 98 // Test with a layer much smaller than the bitmap. 99 MockQuadCuller quad_culler; 100 gfx::Size bitmap_size(101, 101); 101 gfx::Size layer_size(51, 51); 102 gfx::Rect visible_content_rect(layer_size); 103 gfx::Rect aperture_rect(20, 30, 40, 45); // rightWidth: 40, botHeight: 25 104 105 FakeImplProxy proxy; 106 FakeLayerTreeHostImpl host_impl(&proxy); 107 scoped_ptr<NinePatchLayerImpl> layer = 108 NinePatchLayerImpl::Create(host_impl.active_tree(), 1); 109 layer->draw_properties().visible_content_rect = visible_content_rect; 110 layer->SetBounds(layer_size); 111 layer->SetContentBounds(layer_size); 112 layer->CreateRenderSurface(); 113 layer->draw_properties().render_target = layer.get(); 114 layer->SetLayout(bitmap_size, aperture_rect); 115 layer->SetResourceId(1); 116 117 AppendQuadsData data; 118 layer->AppendQuads(&quad_culler, &data); 119 120 // Verify corner rects fill the layer and don't overlap 121 const QuadList& quads = quad_culler.quad_list(); 122 EXPECT_EQ(4u, quads.size()); 123 Region filled; 124 for (size_t i = 0; i < quads.size(); ++i) { 125 DrawQuad* quad = quads[i]; 126 gfx::Rect quad_rect = quad->rect; 127 128 EXPECT_FALSE(filled.Intersects(quad_rect)); 129 filled.Union(quad_rect); 130 } 131 Region expected_full(visible_content_rect); 132 EXPECT_EQ(expected_full, filled); 133 134 // Verify UV rects cover the corners of the bitmap and the crop is weighted 135 // proportionately to the relative corner sizes (for uneven apertures). 136 gfx::Rect bitmap_rect(bitmap_size); 137 Region tex_remaining(bitmap_rect); 138 for (size_t i = 0; i < quads.size(); ++i) { 139 DrawQuad* quad = quads[i]; 140 const TextureDrawQuad* tex_quad = TextureDrawQuad::MaterialCast(quad); 141 gfx::RectF tex_rect = 142 gfx::BoundingRect(tex_quad->uv_top_left, tex_quad->uv_bottom_right); 143 tex_rect.Scale(bitmap_size.width(), bitmap_size.height()); 144 tex_remaining.Subtract(Region(ToRoundedIntRect(tex_rect))); 145 } 146 Region expected_remaining_region = Region(gfx::Rect(bitmap_size)); 147 expected_remaining_region.Subtract(gfx::Rect(0, 0, 17, 28)); 148 expected_remaining_region.Subtract(gfx::Rect(67, 0, 34, 28)); 149 expected_remaining_region.Subtract(gfx::Rect(0, 78, 17, 23)); 150 expected_remaining_region.Subtract(gfx::Rect(67, 78, 34, 23)); 151 EXPECT_EQ(expected_remaining_region, tex_remaining); 152 } 153 154 } // namespace 155 } // namespace cc 156