| OLD | NEW |
| (Empty) |
| 1 // Copyright 2011 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/tiled_layer_impl.h" | |
| 6 | |
| 7 #include "base/basictypes.h" | |
| 8 #include "base/strings/stringprintf.h" | |
| 9 #include "base/trace_event/trace_event_argument.h" | |
| 10 #include "cc/base/math_util.h" | |
| 11 #include "cc/base/simple_enclosed_region.h" | |
| 12 #include "cc/debug/debug_colors.h" | |
| 13 #include "cc/layers/append_quads_data.h" | |
| 14 #include "cc/quads/checkerboard_draw_quad.h" | |
| 15 #include "cc/quads/debug_border_draw_quad.h" | |
| 16 #include "cc/quads/solid_color_draw_quad.h" | |
| 17 #include "cc/quads/tile_draw_quad.h" | |
| 18 #include "cc/resources/layer_tiling_data.h" | |
| 19 #include "cc/trees/occlusion.h" | |
| 20 #include "third_party/skia/include/core/SkColor.h" | |
| 21 #include "ui/gfx/geometry/quad_f.h" | |
| 22 | |
| 23 namespace cc { | |
| 24 | |
| 25 class DrawableTile : public LayerTilingData::Tile { | |
| 26 public: | |
| 27 static scoped_ptr<DrawableTile> Create() { | |
| 28 return make_scoped_ptr(new DrawableTile()); | |
| 29 } | |
| 30 | |
| 31 ResourceProvider::ResourceId resource_id() const { return resource_id_; } | |
| 32 void set_resource_id(ResourceProvider::ResourceId resource_id) { | |
| 33 resource_id_ = resource_id; | |
| 34 } | |
| 35 bool contents_swizzled() { return contents_swizzled_; } | |
| 36 void set_contents_swizzled(bool contents_swizzled) { | |
| 37 contents_swizzled_ = contents_swizzled; | |
| 38 } | |
| 39 | |
| 40 private: | |
| 41 DrawableTile() : resource_id_(0), contents_swizzled_(false) {} | |
| 42 | |
| 43 ResourceProvider::ResourceId resource_id_; | |
| 44 bool contents_swizzled_; | |
| 45 | |
| 46 DISALLOW_COPY_AND_ASSIGN(DrawableTile); | |
| 47 }; | |
| 48 | |
| 49 TiledLayerImpl::TiledLayerImpl(LayerTreeImpl* tree_impl, int id) | |
| 50 : TiledLayerImpl(tree_impl, id, new LayerImpl::SyncedScrollOffset) { | |
| 51 } | |
| 52 | |
| 53 TiledLayerImpl::TiledLayerImpl( | |
| 54 LayerTreeImpl* tree_impl, | |
| 55 int id, | |
| 56 scoped_refptr<LayerImpl::SyncedScrollOffset> synced_scroll_offset) | |
| 57 : LayerImpl(tree_impl, id, synced_scroll_offset), skips_draw_(true) { | |
| 58 } | |
| 59 | |
| 60 TiledLayerImpl::~TiledLayerImpl() { | |
| 61 } | |
| 62 | |
| 63 void TiledLayerImpl::GetContentsResourceId( | |
| 64 ResourceProvider::ResourceId* resource_id, | |
| 65 gfx::Size* resource_size) const { | |
| 66 // This function is only valid for single texture layers, e.g. masks. | |
| 67 DCHECK(tiler_); | |
| 68 // It's possible the mask layer is created but has no size or otherwise | |
| 69 // can't draw. | |
| 70 if (tiler_->num_tiles_x() == 0 || tiler_->num_tiles_y() == 0) { | |
| 71 *resource_id = 0; | |
| 72 return; | |
| 73 } | |
| 74 | |
| 75 // Any other number of tiles other than 0 or 1 is incorrect for masks. | |
| 76 DCHECK_EQ(tiler_->num_tiles_x(), 1); | |
| 77 DCHECK_EQ(tiler_->num_tiles_y(), 1); | |
| 78 | |
| 79 DrawableTile* tile = TileAt(0, 0); | |
| 80 *resource_id = tile ? tile->resource_id() : 0; | |
| 81 *resource_size = tiler_->tile_size(); | |
| 82 } | |
| 83 | |
| 84 bool TiledLayerImpl::HasTileAt(int i, int j) const { | |
| 85 return !!tiler_->TileAt(i, j); | |
| 86 } | |
| 87 | |
| 88 bool TiledLayerImpl::HasResourceIdForTileAt(int i, int j) const { | |
| 89 return HasTileAt(i, j) && TileAt(i, j)->resource_id(); | |
| 90 } | |
| 91 | |
| 92 DrawableTile* TiledLayerImpl::TileAt(int i, int j) const { | |
| 93 return static_cast<DrawableTile*>(tiler_->TileAt(i, j)); | |
| 94 } | |
| 95 | |
| 96 DrawableTile* TiledLayerImpl::CreateTile(int i, int j) { | |
| 97 scoped_ptr<DrawableTile> tile(DrawableTile::Create()); | |
| 98 DrawableTile* added_tile = tile.get(); | |
| 99 tiler_->AddTile(tile.Pass(), i, j); | |
| 100 | |
| 101 return added_tile; | |
| 102 } | |
| 103 | |
| 104 void TiledLayerImpl::GetDebugBorderProperties(SkColor* color, | |
| 105 float* width) const { | |
| 106 *color = DebugColors::TiledContentLayerBorderColor(); | |
| 107 *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl()); | |
| 108 } | |
| 109 | |
| 110 scoped_ptr<LayerImpl> TiledLayerImpl::CreateLayerImpl( | |
| 111 LayerTreeImpl* tree_impl) { | |
| 112 return TiledLayerImpl::Create(tree_impl, id(), synced_scroll_offset()); | |
| 113 } | |
| 114 | |
| 115 void TiledLayerImpl::AsValueInto(base::trace_event::TracedValue* state) const { | |
| 116 LayerImpl::AsValueInto(state); | |
| 117 MathUtil::AddToTracedValue("invalidation", update_rect(), state); | |
| 118 } | |
| 119 | |
| 120 size_t TiledLayerImpl::GPUMemoryUsageInBytes() const { | |
| 121 size_t amount = 0; | |
| 122 const size_t kMemoryUsagePerTileInBytes = | |
| 123 4 * tiler_->tile_size().width() * tiler_->tile_size().height(); | |
| 124 for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin(); | |
| 125 iter != tiler_->tiles().end(); | |
| 126 ++iter) { | |
| 127 const DrawableTile* tile = static_cast<DrawableTile*>(iter->second); | |
| 128 DCHECK(tile); | |
| 129 if (!tile->resource_id()) | |
| 130 continue; | |
| 131 amount += kMemoryUsagePerTileInBytes; | |
| 132 } | |
| 133 return amount; | |
| 134 } | |
| 135 | |
| 136 void TiledLayerImpl::PushPropertiesTo(LayerImpl* layer) { | |
| 137 LayerImpl::PushPropertiesTo(layer); | |
| 138 | |
| 139 TiledLayerImpl* tiled_layer = static_cast<TiledLayerImpl*>(layer); | |
| 140 | |
| 141 tiled_layer->set_skips_draw(skips_draw_); | |
| 142 tiled_layer->SetTilingData(*tiler_); | |
| 143 | |
| 144 for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin(); | |
| 145 iter != tiler_->tiles().end(); | |
| 146 ++iter) { | |
| 147 int i = iter->first.first; | |
| 148 int j = iter->first.second; | |
| 149 DrawableTile* tile = static_cast<DrawableTile*>(iter->second); | |
| 150 DCHECK(tile); | |
| 151 tiled_layer->PushTileProperties(i, | |
| 152 j, | |
| 153 tile->resource_id(), | |
| 154 tile->contents_swizzled()); | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 bool TiledLayerImpl::WillDraw(DrawMode draw_mode, | |
| 159 ResourceProvider* resource_provider) { | |
| 160 if (!tiler_ || tiler_->has_empty_bounds() || | |
| 161 visible_content_rect().IsEmpty() || | |
| 162 draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE) | |
| 163 return false; | |
| 164 return LayerImpl::WillDraw(draw_mode, resource_provider); | |
| 165 } | |
| 166 | |
| 167 void TiledLayerImpl::AppendQuads(RenderPass* render_pass, | |
| 168 AppendQuadsData* append_quads_data) { | |
| 169 DCHECK(tiler_); | |
| 170 DCHECK(!tiler_->has_empty_bounds()); | |
| 171 DCHECK(!visible_content_rect().IsEmpty()); | |
| 172 | |
| 173 gfx::Rect content_rect = visible_content_rect(); | |
| 174 SharedQuadState* shared_quad_state = | |
| 175 render_pass->CreateAndAppendSharedQuadState(); | |
| 176 PopulateSharedQuadState(shared_quad_state); | |
| 177 | |
| 178 AppendDebugBorderQuad( | |
| 179 render_pass, content_bounds(), shared_quad_state, append_quads_data); | |
| 180 | |
| 181 int left, top, right, bottom; | |
| 182 tiler_->ContentRectToTileIndices(content_rect, &left, &top, &right, &bottom); | |
| 183 | |
| 184 if (ShowDebugBorders()) { | |
| 185 for (int j = top; j <= bottom; ++j) { | |
| 186 for (int i = left; i <= right; ++i) { | |
| 187 DrawableTile* tile = TileAt(i, j); | |
| 188 gfx::Rect tile_rect = tiler_->tile_bounds(i, j); | |
| 189 gfx::Rect visible_tile_rect = tile_rect; | |
| 190 SkColor border_color; | |
| 191 float border_width; | |
| 192 | |
| 193 if (skips_draw_ || !tile || !tile->resource_id()) { | |
| 194 border_color = DebugColors::MissingTileBorderColor(); | |
| 195 border_width = DebugColors::MissingTileBorderWidth(layer_tree_impl()); | |
| 196 } else { | |
| 197 border_color = DebugColors::HighResTileBorderColor(); | |
| 198 border_width = DebugColors::HighResTileBorderWidth(layer_tree_impl()); | |
| 199 } | |
| 200 DebugBorderDrawQuad* debug_border_quad = | |
| 201 render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>(); | |
| 202 debug_border_quad->SetNew(shared_quad_state, | |
| 203 tile_rect, | |
| 204 visible_tile_rect, | |
| 205 border_color, | |
| 206 border_width); | |
| 207 } | |
| 208 } | |
| 209 } | |
| 210 | |
| 211 if (skips_draw_) | |
| 212 return; | |
| 213 | |
| 214 for (int j = top; j <= bottom; ++j) { | |
| 215 for (int i = left; i <= right; ++i) { | |
| 216 DrawableTile* tile = TileAt(i, j); | |
| 217 gfx::Rect tile_rect = tiler_->tile_bounds(i, j); | |
| 218 gfx::Rect display_rect = tile_rect; | |
| 219 tile_rect.Intersect(content_rect); | |
| 220 | |
| 221 // Skip empty tiles. | |
| 222 if (tile_rect.IsEmpty()) | |
| 223 continue; | |
| 224 | |
| 225 gfx::Rect visible_tile_rect = | |
| 226 draw_properties().occlusion_in_content_space.GetUnoccludedContentRect( | |
| 227 tile_rect); | |
| 228 if (visible_tile_rect.IsEmpty()) | |
| 229 continue; | |
| 230 | |
| 231 if (!tile || !tile->resource_id()) { | |
| 232 SkColor checker_color; | |
| 233 if (ShowDebugBorders()) { | |
| 234 checker_color = | |
| 235 tile ? DebugColors::InvalidatedTileCheckerboardColor() | |
| 236 : DebugColors::EvictedTileCheckerboardColor(); | |
| 237 } else { | |
| 238 checker_color = DebugColors::DefaultCheckerboardColor(); | |
| 239 } | |
| 240 | |
| 241 CheckerboardDrawQuad* checkerboard_quad = | |
| 242 render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>(); | |
| 243 checkerboard_quad->SetNew(shared_quad_state, tile_rect, | |
| 244 visible_tile_rect, checker_color, 1.f); | |
| 245 append_quads_data->num_missing_tiles++; | |
| 246 continue; | |
| 247 } | |
| 248 | |
| 249 gfx::Rect tile_opaque_rect = contents_opaque() ? tile_rect : gfx::Rect(); | |
| 250 | |
| 251 // Keep track of how the top left has moved, so the texture can be | |
| 252 // offset the same amount. | |
| 253 gfx::Vector2d display_offset = tile_rect.origin() - display_rect.origin(); | |
| 254 gfx::Vector2d texture_offset = | |
| 255 tiler_->texture_offset(i, j) + display_offset; | |
| 256 gfx::RectF tex_coord_rect = gfx::RectF(tile_rect.size()) + texture_offset; | |
| 257 | |
| 258 float tile_width = static_cast<float>(tiler_->tile_size().width()); | |
| 259 float tile_height = static_cast<float>(tiler_->tile_size().height()); | |
| 260 gfx::Size texture_size(tile_width, tile_height); | |
| 261 | |
| 262 TileDrawQuad* quad = render_pass->CreateAndAppendDrawQuad<TileDrawQuad>(); | |
| 263 quad->SetNew(shared_quad_state, | |
| 264 tile_rect, | |
| 265 tile_opaque_rect, | |
| 266 visible_tile_rect, | |
| 267 tile->resource_id(), | |
| 268 tex_coord_rect, | |
| 269 texture_size, | |
| 270 tile->contents_swizzled(), | |
| 271 false); | |
| 272 } | |
| 273 } | |
| 274 } | |
| 275 | |
| 276 void TiledLayerImpl::SetTilingData(const LayerTilingData& tiler) { | |
| 277 if (tiler_) { | |
| 278 tiler_->reset(); | |
| 279 } else { | |
| 280 tiler_ = LayerTilingData::Create(tiler.tile_size(), | |
| 281 tiler.has_border_texels() | |
| 282 ? LayerTilingData::HAS_BORDER_TEXELS | |
| 283 : LayerTilingData::NO_BORDER_TEXELS); | |
| 284 } | |
| 285 *tiler_ = tiler; | |
| 286 } | |
| 287 | |
| 288 void TiledLayerImpl::PushTileProperties( | |
| 289 int i, | |
| 290 int j, | |
| 291 ResourceProvider::ResourceId resource_id, | |
| 292 bool contents_swizzled) { | |
| 293 DrawableTile* tile = TileAt(i, j); | |
| 294 if (!tile) | |
| 295 tile = CreateTile(i, j); | |
| 296 tile->set_resource_id(resource_id); | |
| 297 tile->set_contents_swizzled(contents_swizzled); | |
| 298 } | |
| 299 | |
| 300 void TiledLayerImpl::PushInvalidTile(int i, int j) { | |
| 301 DrawableTile* tile = TileAt(i, j); | |
| 302 if (!tile) | |
| 303 tile = CreateTile(i, j); | |
| 304 tile->set_resource_id(0); | |
| 305 tile->set_contents_swizzled(false); | |
| 306 } | |
| 307 | |
| 308 SimpleEnclosedRegion TiledLayerImpl::VisibleContentOpaqueRegion() const { | |
| 309 if (skips_draw_) | |
| 310 return SimpleEnclosedRegion(); | |
| 311 return LayerImpl::VisibleContentOpaqueRegion(); | |
| 312 } | |
| 313 | |
| 314 void TiledLayerImpl::ReleaseResources() { | |
| 315 tiler_->reset(); | |
| 316 } | |
| 317 | |
| 318 const char* TiledLayerImpl::LayerTypeAsString() const { | |
| 319 return "cc::TiledLayerImpl"; | |
| 320 } | |
| 321 | |
| 322 } // namespace cc | |
| OLD | NEW |