Disable flaky AnimatedContentSamplerParameterizedTest.FrameTimestampsConvergeTowardsE...
[chromium-blink-merge.git] / cc / layers / tiled_layer_impl.cc
blob92a34265fe2f028cd981dece73be66bf1108207c
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.
5 #include "cc/layers/tiled_layer_impl.h"
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/tiles/layer_tiling_data.h"
19 #include "cc/trees/layer_tree_impl.h"
20 #include "cc/trees/occlusion.h"
21 #include "third_party/skia/include/core/SkColor.h"
22 #include "ui/gfx/geometry/quad_f.h"
24 namespace cc {
26 class DrawableTile : public LayerTilingData::Tile {
27 public:
28 static scoped_ptr<DrawableTile> Create() {
29 return make_scoped_ptr(new DrawableTile());
32 ResourceId resource_id() const { return resource_id_; }
33 void set_resource_id(ResourceId resource_id) { resource_id_ = resource_id; }
34 bool contents_swizzled() { return contents_swizzled_; }
35 void set_contents_swizzled(bool contents_swizzled) {
36 contents_swizzled_ = contents_swizzled;
39 private:
40 DrawableTile() : resource_id_(0), contents_swizzled_(false) {}
42 ResourceId resource_id_;
43 bool contents_swizzled_;
45 DISALLOW_COPY_AND_ASSIGN(DrawableTile);
48 TiledLayerImpl::TiledLayerImpl(LayerTreeImpl* tree_impl, int id)
49 : TiledLayerImpl(tree_impl, id, new LayerImpl::SyncedScrollOffset) {
52 TiledLayerImpl::TiledLayerImpl(
53 LayerTreeImpl* tree_impl,
54 int id,
55 scoped_refptr<LayerImpl::SyncedScrollOffset> synced_scroll_offset)
56 : LayerImpl(tree_impl, id, synced_scroll_offset), skips_draw_(true) {
59 TiledLayerImpl::~TiledLayerImpl() {
62 void TiledLayerImpl::GetContentsResourceId(ResourceId* resource_id,
63 gfx::Size* resource_size) const {
64 // This function is only valid for single texture layers, e.g. masks.
65 DCHECK(tiler_);
66 // It's possible the mask layer is created but has no size or otherwise
67 // can't draw.
68 if (tiler_->num_tiles_x() == 0 || tiler_->num_tiles_y() == 0) {
69 *resource_id = 0;
70 return;
73 // Any other number of tiles other than 0 or 1 is incorrect for masks.
74 DCHECK_EQ(tiler_->num_tiles_x(), 1);
75 DCHECK_EQ(tiler_->num_tiles_y(), 1);
77 DrawableTile* tile = TileAt(0, 0);
78 *resource_id = tile ? tile->resource_id() : 0;
79 *resource_size = tiler_->tile_size();
82 bool TiledLayerImpl::HasTileAt(int i, int j) const {
83 return !!tiler_->TileAt(i, j);
86 bool TiledLayerImpl::HasResourceIdForTileAt(int i, int j) const {
87 return HasTileAt(i, j) && TileAt(i, j)->resource_id();
90 DrawableTile* TiledLayerImpl::TileAt(int i, int j) const {
91 return static_cast<DrawableTile*>(tiler_->TileAt(i, j));
94 DrawableTile* TiledLayerImpl::CreateTile(int i, int j) {
95 scoped_ptr<DrawableTile> tile(DrawableTile::Create());
96 DrawableTile* added_tile = tile.get();
97 tiler_->AddTile(tile.Pass(), i, j);
99 return added_tile;
102 void TiledLayerImpl::GetDebugBorderProperties(SkColor* color,
103 float* width) const {
104 *color = DebugColors::TiledContentLayerBorderColor();
105 *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
108 scoped_ptr<LayerImpl> TiledLayerImpl::CreateLayerImpl(
109 LayerTreeImpl* tree_impl) {
110 return TiledLayerImpl::Create(tree_impl, id(), synced_scroll_offset());
113 void TiledLayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
114 LayerImpl::AsValueInto(state);
115 MathUtil::AddToTracedValue("invalidation", update_rect(), state);
118 size_t TiledLayerImpl::GPUMemoryUsageInBytes() const {
119 size_t amount = 0;
120 const size_t kMemoryUsagePerTileInBytes =
121 4 * tiler_->tile_size().width() * tiler_->tile_size().height();
122 for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
123 iter != tiler_->tiles().end();
124 ++iter) {
125 const DrawableTile* tile = static_cast<DrawableTile*>(iter->second);
126 DCHECK(tile);
127 if (!tile->resource_id())
128 continue;
129 amount += kMemoryUsagePerTileInBytes;
131 return amount;
134 void TiledLayerImpl::PushPropertiesTo(LayerImpl* layer) {
135 LayerImpl::PushPropertiesTo(layer);
137 TiledLayerImpl* tiled_layer = static_cast<TiledLayerImpl*>(layer);
139 tiled_layer->set_skips_draw(skips_draw_);
140 tiled_layer->SetTilingData(*tiler_);
142 for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
143 iter != tiler_->tiles().end();
144 ++iter) {
145 int i = iter->first.first;
146 int j = iter->first.second;
147 DrawableTile* tile = static_cast<DrawableTile*>(iter->second);
148 DCHECK(tile);
149 tiled_layer->PushTileProperties(i,
151 tile->resource_id(),
152 tile->contents_swizzled());
156 bool TiledLayerImpl::WillDraw(DrawMode draw_mode,
157 ResourceProvider* resource_provider) {
158 if (!tiler_ || tiler_->has_empty_bounds() ||
159 visible_content_rect().IsEmpty() ||
160 draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
161 return false;
162 return LayerImpl::WillDraw(draw_mode, resource_provider);
165 void TiledLayerImpl::AppendQuads(RenderPass* render_pass,
166 AppendQuadsData* append_quads_data) {
167 DCHECK(tiler_);
168 DCHECK(!tiler_->has_empty_bounds());
169 DCHECK(!visible_content_rect().IsEmpty());
171 gfx::Rect content_rect = visible_content_rect();
172 SharedQuadState* shared_quad_state =
173 render_pass->CreateAndAppendSharedQuadState();
174 PopulateSharedQuadState(shared_quad_state);
176 AppendDebugBorderQuad(
177 render_pass, content_bounds(), shared_quad_state, append_quads_data);
179 int left, top, right, bottom;
180 tiler_->ContentRectToTileIndices(content_rect, &left, &top, &right, &bottom);
182 if (ShowDebugBorders()) {
183 for (int j = top; j <= bottom; ++j) {
184 for (int i = left; i <= right; ++i) {
185 DrawableTile* tile = TileAt(i, j);
186 gfx::Rect tile_rect = tiler_->tile_bounds(i, j);
187 gfx::Rect visible_tile_rect = tile_rect;
188 SkColor border_color;
189 float border_width;
191 if (skips_draw_ || !tile || !tile->resource_id()) {
192 border_color = DebugColors::MissingTileBorderColor();
193 border_width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
194 } else {
195 border_color = DebugColors::HighResTileBorderColor();
196 border_width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
198 DebugBorderDrawQuad* debug_border_quad =
199 render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
200 debug_border_quad->SetNew(shared_quad_state,
201 tile_rect,
202 visible_tile_rect,
203 border_color,
204 border_width);
209 if (skips_draw_)
210 return;
212 for (int j = top; j <= bottom; ++j) {
213 for (int i = left; i <= right; ++i) {
214 DrawableTile* tile = TileAt(i, j);
215 gfx::Rect tile_rect = tiler_->tile_bounds(i, j);
216 gfx::Rect display_rect = tile_rect;
217 tile_rect.Intersect(content_rect);
219 // Skip empty tiles.
220 if (tile_rect.IsEmpty())
221 continue;
223 gfx::Rect visible_tile_rect =
224 draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
225 tile_rect);
226 if (visible_tile_rect.IsEmpty())
227 continue;
229 if (!tile || !tile->resource_id()) {
230 SkColor checker_color;
231 if (ShowDebugBorders()) {
232 checker_color =
233 tile ? DebugColors::InvalidatedTileCheckerboardColor()
234 : DebugColors::EvictedTileCheckerboardColor();
235 } else {
236 checker_color = DebugColors::DefaultCheckerboardColor();
239 CheckerboardDrawQuad* checkerboard_quad =
240 render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
241 checkerboard_quad->SetNew(shared_quad_state, tile_rect,
242 visible_tile_rect, checker_color, 1.f);
243 append_quads_data->num_missing_tiles++;
244 continue;
247 gfx::Rect tile_opaque_rect = contents_opaque() ? tile_rect : gfx::Rect();
249 // Keep track of how the top left has moved, so the texture can be
250 // offset the same amount.
251 gfx::Vector2d display_offset = tile_rect.origin() - display_rect.origin();
252 gfx::Vector2d texture_offset =
253 tiler_->texture_offset(i, j) + display_offset;
254 gfx::RectF tex_coord_rect = gfx::RectF(tile_rect.size()) + texture_offset;
256 float tile_width = static_cast<float>(tiler_->tile_size().width());
257 float tile_height = static_cast<float>(tiler_->tile_size().height());
258 gfx::Size texture_size(tile_width, tile_height);
260 TileDrawQuad* quad = render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
261 quad->SetNew(shared_quad_state,
262 tile_rect,
263 tile_opaque_rect,
264 visible_tile_rect,
265 tile->resource_id(),
266 tex_coord_rect,
267 texture_size,
268 tile->contents_swizzled(),
269 false);
270 ValidateQuadResources(quad);
275 void TiledLayerImpl::SetTilingData(const LayerTilingData& tiler) {
276 if (tiler_) {
277 tiler_->reset();
278 } else {
279 tiler_ = LayerTilingData::Create(tiler.tile_size(),
280 tiler.has_border_texels()
281 ? LayerTilingData::HAS_BORDER_TEXELS
282 : LayerTilingData::NO_BORDER_TEXELS);
284 *tiler_ = tiler;
287 void TiledLayerImpl::PushTileProperties(int i,
288 int j,
289 ResourceId resource_id,
290 bool contents_swizzled) {
291 DrawableTile* tile = TileAt(i, j);
292 if (!tile)
293 tile = CreateTile(i, j);
294 tile->set_resource_id(resource_id);
295 tile->set_contents_swizzled(contents_swizzled);
298 void TiledLayerImpl::PushInvalidTile(int i, int j) {
299 DrawableTile* tile = TileAt(i, j);
300 if (!tile)
301 tile = CreateTile(i, j);
302 tile->set_resource_id(0);
303 tile->set_contents_swizzled(false);
306 SimpleEnclosedRegion TiledLayerImpl::VisibleContentOpaqueRegion() const {
307 if (skips_draw_)
308 return SimpleEnclosedRegion();
309 return LayerImpl::VisibleContentOpaqueRegion();
312 void TiledLayerImpl::ReleaseResources() {
313 tiler_->reset();
316 const char* TiledLayerImpl::LayerTypeAsString() const {
317 return "cc::TiledLayerImpl";
320 } // namespace cc