Connect PPAPI IPC channels for non-SFI mode.
[chromium-blink-merge.git] / cc / layers / tiled_layer_impl.cc
blobd2767cf02eff991ada2d1520f78b7e31d63f9fad
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 "cc/base/math_util.h"
10 #include "cc/debug/debug_colors.h"
11 #include "cc/layers/append_quads_data.h"
12 #include "cc/layers/quad_sink.h"
13 #include "cc/quads/checkerboard_draw_quad.h"
14 #include "cc/quads/debug_border_draw_quad.h"
15 #include "cc/quads/solid_color_draw_quad.h"
16 #include "cc/quads/tile_draw_quad.h"
17 #include "cc/resources/layer_tiling_data.h"
18 #include "third_party/khronos/GLES2/gl2.h"
19 #include "third_party/skia/include/core/SkColor.h"
20 #include "ui/gfx/quad_f.h"
22 namespace cc {
24 class DrawableTile : public LayerTilingData::Tile {
25 public:
26 static scoped_ptr<DrawableTile> Create() {
27 return make_scoped_ptr(new DrawableTile());
30 ResourceProvider::ResourceId resource_id() const { return resource_id_; }
31 void set_resource_id(ResourceProvider::ResourceId resource_id) {
32 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 ResourceProvider::ResourceId resource_id_;
43 bool contents_swizzled_;
45 DISALLOW_COPY_AND_ASSIGN(DrawableTile);
48 TiledLayerImpl::TiledLayerImpl(LayerTreeImpl* tree_impl, int id)
49 : LayerImpl(tree_impl, id), skips_draw_(true) {}
51 TiledLayerImpl::~TiledLayerImpl() {
54 ResourceProvider::ResourceId TiledLayerImpl::ContentsResourceId() const {
55 // This function is only valid for single texture layers, e.g. masks.
56 DCHECK(tiler_);
57 // It's possible the mask layer is created but has no size or otherwise
58 // can't draw.
59 if (tiler_->num_tiles_x() == 0 || tiler_->num_tiles_y() == 0)
60 return 0;
62 // Any other number of tiles other than 0 or 1 is incorrect for masks.
63 DCHECK_EQ(tiler_->num_tiles_x(), 1);
64 DCHECK_EQ(tiler_->num_tiles_y(), 1);
66 DrawableTile* tile = TileAt(0, 0);
67 ResourceProvider::ResourceId resource_id = tile ? tile->resource_id() : 0;
68 return resource_id;
71 bool TiledLayerImpl::HasTileAt(int i, int j) const {
72 return !!tiler_->TileAt(i, j);
75 bool TiledLayerImpl::HasResourceIdForTileAt(int i, int j) const {
76 return HasTileAt(i, j) && TileAt(i, j)->resource_id();
79 DrawableTile* TiledLayerImpl::TileAt(int i, int j) const {
80 return static_cast<DrawableTile*>(tiler_->TileAt(i, j));
83 DrawableTile* TiledLayerImpl::CreateTile(int i, int j) {
84 scoped_ptr<DrawableTile> tile(DrawableTile::Create());
85 DrawableTile* added_tile = tile.get();
86 tiler_->AddTile(tile.PassAs<LayerTilingData::Tile>(), i, j);
88 return added_tile;
91 void TiledLayerImpl::GetDebugBorderProperties(SkColor* color,
92 float* width) const {
93 *color = DebugColors::TiledContentLayerBorderColor();
94 *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
97 scoped_ptr<LayerImpl> TiledLayerImpl::CreateLayerImpl(
98 LayerTreeImpl* tree_impl) {
99 return TiledLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
102 void TiledLayerImpl::AsValueInto(base::DictionaryValue* state) const {
103 LayerImpl::AsValueInto(state);
104 state->Set("invalidation", MathUtil::AsValue(update_rect()).release());
107 size_t TiledLayerImpl::GPUMemoryUsageInBytes() const {
108 size_t amount = 0;
109 const size_t kMemoryUsagePerTileInBytes =
110 4 * tiler_->tile_size().width() * tiler_->tile_size().height();
111 for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
112 iter != tiler_->tiles().end();
113 ++iter) {
114 const DrawableTile* tile = static_cast<DrawableTile*>(iter->second);
115 if (!tile || !tile->resource_id())
116 continue;
117 amount += kMemoryUsagePerTileInBytes;
119 return amount;
122 void TiledLayerImpl::PushPropertiesTo(LayerImpl* layer) {
123 LayerImpl::PushPropertiesTo(layer);
125 TiledLayerImpl* tiled_layer = static_cast<TiledLayerImpl*>(layer);
127 tiled_layer->set_skips_draw(skips_draw_);
128 tiled_layer->SetTilingData(*tiler_);
130 for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
131 iter != tiler_->tiles().end();
132 ++iter) {
133 int i = iter->first.first;
134 int j = iter->first.second;
135 DrawableTile* tile = static_cast<DrawableTile*>(iter->second);
137 tiled_layer->PushTileProperties(i,
139 tile->resource_id(),
140 tile->opaque_rect(),
141 tile->contents_swizzled());
145 bool TiledLayerImpl::WillDraw(DrawMode draw_mode,
146 ResourceProvider* resource_provider) {
147 if (!tiler_ || tiler_->has_empty_bounds() ||
148 visible_content_rect().IsEmpty() ||
149 draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
150 return false;
151 return LayerImpl::WillDraw(draw_mode, resource_provider);
154 void TiledLayerImpl::AppendQuads(QuadSink* quad_sink,
155 AppendQuadsData* append_quads_data) {
156 DCHECK(tiler_);
157 DCHECK(!tiler_->has_empty_bounds());
158 DCHECK(!visible_content_rect().IsEmpty());
160 gfx::Rect content_rect = visible_content_rect();
161 SharedQuadState* shared_quad_state =
162 quad_sink->UseSharedQuadState(CreateSharedQuadState());
163 AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
165 int left, top, right, bottom;
166 tiler_->ContentRectToTileIndices(content_rect, &left, &top, &right, &bottom);
168 if (ShowDebugBorders()) {
169 for (int j = top; j <= bottom; ++j) {
170 for (int i = left; i <= right; ++i) {
171 DrawableTile* tile = TileAt(i, j);
172 gfx::Rect tile_rect = tiler_->tile_bounds(i, j);
173 SkColor border_color;
174 float border_width;
176 if (skips_draw_ || !tile || !tile->resource_id()) {
177 border_color = DebugColors::MissingTileBorderColor();
178 border_width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
179 } else {
180 border_color = DebugColors::HighResTileBorderColor();
181 border_width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
183 scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
184 DebugBorderDrawQuad::Create();
185 debug_border_quad->SetNew(
186 shared_quad_state, tile_rect, border_color, border_width);
187 quad_sink->Append(debug_border_quad.PassAs<DrawQuad>(),
188 append_quads_data);
193 if (skips_draw_)
194 return;
196 for (int j = top; j <= bottom; ++j) {
197 for (int i = left; i <= right; ++i) {
198 DrawableTile* tile = TileAt(i, j);
199 gfx::Rect tile_rect = tiler_->tile_bounds(i, j);
200 gfx::Rect display_rect = tile_rect;
201 tile_rect.Intersect(content_rect);
203 // Skip empty tiles.
204 if (tile_rect.IsEmpty())
205 continue;
207 if (!tile || !tile->resource_id()) {
208 SkColor checker_color;
209 if (ShowDebugBorders()) {
210 checker_color =
211 tile ? DebugColors::InvalidatedTileCheckerboardColor()
212 : DebugColors::EvictedTileCheckerboardColor();
213 } else {
214 checker_color = DebugColors::DefaultCheckerboardColor();
217 scoped_ptr<CheckerboardDrawQuad> checkerboard_quad =
218 CheckerboardDrawQuad::Create();
219 checkerboard_quad->SetNew(
220 shared_quad_state, tile_rect, checker_color);
221 if (quad_sink->Append(checkerboard_quad.PassAs<DrawQuad>(),
222 append_quads_data))
223 append_quads_data->num_missing_tiles++;
225 continue;
228 gfx::Rect tile_opaque_rect =
229 contents_opaque() ? tile_rect : gfx::IntersectRects(
230 tile->opaque_rect(), tile_rect);
232 // Keep track of how the top left has moved, so the texture can be
233 // offset the same amount.
234 gfx::Vector2d display_offset = tile_rect.origin() - display_rect.origin();
235 gfx::Vector2d texture_offset =
236 tiler_->texture_offset(i, j) + display_offset;
237 gfx::RectF tex_coord_rect = gfx::RectF(tile_rect.size()) + texture_offset;
239 float tile_width = static_cast<float>(tiler_->tile_size().width());
240 float tile_height = static_cast<float>(tiler_->tile_size().height());
241 gfx::Size texture_size(tile_width, tile_height);
243 scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create();
244 quad->SetNew(shared_quad_state,
245 tile_rect,
246 tile_opaque_rect,
247 tile->resource_id(),
248 tex_coord_rect,
249 texture_size,
250 tile->contents_swizzled());
251 quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
256 void TiledLayerImpl::SetTilingData(const LayerTilingData& tiler) {
257 if (tiler_) {
258 tiler_->reset();
259 } else {
260 tiler_ = LayerTilingData::Create(tiler.tile_size(),
261 tiler.has_border_texels()
262 ? LayerTilingData::HAS_BORDER_TEXELS
263 : LayerTilingData::NO_BORDER_TEXELS);
265 *tiler_ = tiler;
268 void TiledLayerImpl::PushTileProperties(
269 int i,
270 int j,
271 ResourceProvider::ResourceId resource_id,
272 const gfx::Rect& opaque_rect,
273 bool contents_swizzled) {
274 DrawableTile* tile = TileAt(i, j);
275 if (!tile)
276 tile = CreateTile(i, j);
277 tile->set_resource_id(resource_id);
278 tile->set_opaque_rect(opaque_rect);
279 tile->set_contents_swizzled(contents_swizzled);
282 void TiledLayerImpl::PushInvalidTile(int i, int j) {
283 DrawableTile* tile = TileAt(i, j);
284 if (!tile)
285 tile = CreateTile(i, j);
286 tile->set_resource_id(0);
287 tile->set_opaque_rect(gfx::Rect());
288 tile->set_contents_swizzled(false);
291 Region TiledLayerImpl::VisibleContentOpaqueRegion() const {
292 if (skips_draw_)
293 return Region();
294 if (contents_opaque())
295 return visible_content_rect();
296 return tiler_->OpaqueRegionInContentRect(visible_content_rect());
299 void TiledLayerImpl::ReleaseResources() {
300 tiler_->reset();
303 const char* TiledLayerImpl::LayerTypeAsString() const {
304 return "cc::TiledLayerImpl";
307 } // namespace cc