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 "base/containers/hash_tables.h" 6#include "cc/layers/append_quads_data.h" 7#include "cc/layers/nine_patch_layer_impl.h" 8#include "cc/quads/texture_draw_quad.h" 9#include "cc/resources/ui_resource_bitmap.h" 10#include "cc/resources/ui_resource_client.h" 11#include "cc/test/fake_impl_proxy.h" 12#include "cc/test/fake_ui_resource_layer_tree_host_impl.h" 13#include "cc/test/geometry_test_utils.h" 14#include "cc/test/layer_test_common.h" 15#include "cc/test/mock_quad_culler.h" 16#include "cc/trees/single_thread_proxy.h" 17#include "testing/gmock/include/gmock/gmock.h" 18#include "testing/gtest/include/gtest/gtest.h" 19#include "ui/gfx/rect_conversions.h" 20#include "ui/gfx/safe_integer_conversions.h" 21#include "ui/gfx/transform.h" 22 23namespace cc { 24namespace { 25 26gfx::Rect ToRoundedIntRect(gfx::RectF rect_f) { 27 return gfx::Rect(gfx::ToRoundedInt(rect_f.x()), 28 gfx::ToRoundedInt(rect_f.y()), 29 gfx::ToRoundedInt(rect_f.width()), 30 gfx::ToRoundedInt(rect_f.height())); 31} 32 33void NinePatchLayerLayoutTest(gfx::Size bitmap_size, 34 gfx::Rect aperture_rect, 35 gfx::Size layer_size, 36 gfx::Rect border, 37 bool fill_center, 38 size_t expected_quad_size) { 39 MockQuadCuller quad_culler; 40 gfx::Rect visible_content_rect(layer_size); 41 gfx::Rect expected_remaining(border.x(), 42 border.y(), 43 layer_size.width() - border.width(), 44 layer_size.height() - border.height()); 45 46 FakeImplProxy proxy; 47 FakeUIResourceLayerTreeHostImpl host_impl(&proxy); 48 scoped_ptr<NinePatchLayerImpl> layer = 49 NinePatchLayerImpl::Create(host_impl.active_tree(), 1); 50 layer->draw_properties().visible_content_rect = visible_content_rect; 51 layer->SetBounds(layer_size); 52 layer->SetContentBounds(layer_size); 53 layer->CreateRenderSurface(); 54 layer->draw_properties().render_target = layer.get(); 55 56 UIResourceId uid = 1; 57 SkBitmap skbitmap; 58 skbitmap.setConfig( 59 SkBitmap::kARGB_8888_Config, bitmap_size.width(), bitmap_size.height()); 60 skbitmap.allocPixels(); 61 skbitmap.setImmutable(); 62 UIResourceBitmap bitmap(skbitmap); 63 64 host_impl.CreateUIResource(uid, bitmap); 65 layer->SetUIResourceId(uid); 66 layer->SetImageBounds(bitmap_size); 67 layer->SetLayout(aperture_rect, border, fill_center); 68 AppendQuadsData data; 69 layer->AppendQuads(&quad_culler, &data); 70 71 // Verify quad rects 72 const QuadList& quads = quad_culler.quad_list(); 73 EXPECT_EQ(expected_quad_size, quads.size()); 74 75 Region remaining(visible_content_rect); 76 for (size_t i = 0; i < quads.size(); ++i) { 77 DrawQuad* quad = quads[i]; 78 gfx::Rect quad_rect = quad->rect; 79 80 EXPECT_TRUE(visible_content_rect.Contains(quad_rect)) << i; 81 EXPECT_TRUE(remaining.Contains(quad_rect)) << i; 82 remaining.Subtract(Region(quad_rect)); 83 } 84 85 // Check if the left-over quad is the same size as the mapped aperture quad in 86 // layer space. 87 if (!fill_center) { 88 EXPECT_RECT_EQ(expected_remaining, gfx::ToEnclosedRect(remaining.bounds())); 89 } else { 90 EXPECT_TRUE(remaining.bounds().IsEmpty()); 91 } 92 93 // Verify UV rects 94 gfx::Rect bitmap_rect(bitmap_size); 95 Region tex_remaining(bitmap_rect); 96 for (size_t i = 0; i < quads.size(); ++i) { 97 DrawQuad* quad = quads[i]; 98 const TextureDrawQuad* tex_quad = TextureDrawQuad::MaterialCast(quad); 99 gfx::RectF tex_rect = 100 gfx::BoundingRect(tex_quad->uv_top_left, tex_quad->uv_bottom_right); 101 tex_rect.Scale(bitmap_size.width(), bitmap_size.height()); 102 tex_remaining.Subtract(Region(ToRoundedIntRect(tex_rect))); 103 } 104 105 if (!fill_center) { 106 EXPECT_RECT_EQ(aperture_rect, tex_remaining.bounds()); 107 Region aperture_region(aperture_rect); 108 EXPECT_EQ(aperture_region, tex_remaining); 109 } else { 110 EXPECT_TRUE(remaining.bounds().IsEmpty()); 111 } 112} 113 114TEST(NinePatchLayerImplTest, VerifyDrawQuads) { 115 // Input is a 100x100 bitmap with a 40x50 aperture at x=20, y=30. 116 // The bounds of the layer are set to 400x400. 117 gfx::Size bitmap_size(100, 100); 118 gfx::Size layer_size(400, 500); 119 gfx::Rect aperture_rect(20, 30, 40, 50); 120 gfx::Rect border(40, 40, 80, 80); 121 bool fill_center = false; 122 size_t expected_quad_size = 8; 123 NinePatchLayerLayoutTest(bitmap_size, 124 aperture_rect, 125 layer_size, 126 border, 127 fill_center, 128 expected_quad_size); 129 130 // The bounds of the layer are set to less than the bitmap size. 131 bitmap_size = gfx::Size(100, 100); 132 layer_size = gfx::Size(40, 50); 133 aperture_rect = gfx::Rect(20, 30, 40, 50); 134 border = gfx::Rect(10, 10, 25, 15); 135 fill_center = true; 136 expected_quad_size = 9; 137 NinePatchLayerLayoutTest(bitmap_size, 138 aperture_rect, 139 layer_size, 140 border, 141 fill_center, 142 expected_quad_size); 143 144 // Layer and image sizes are equal. 145 bitmap_size = gfx::Size(100, 100); 146 layer_size = gfx::Size(100, 100); 147 aperture_rect = gfx::Rect(20, 30, 40, 50); 148 border = gfx::Rect(20, 30, 40, 50); 149 fill_center = true; 150 expected_quad_size = 9; 151 NinePatchLayerLayoutTest(bitmap_size, 152 aperture_rect, 153 layer_size, 154 border, 155 fill_center, 156 expected_quad_size); 157} 158 159} // namespace 160} // namespace cc 161