blob: 421078f7bbe5e12bd8eea436fabbdc1816c6072e [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// 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
[email protected]d50c6862012-10-23 02:08:315#include "cc/layer_impl.h"
[email protected]94f206c12012-08-25 00:09:146
[email protected]c4040a522012-10-21 15:01:407#include "base/debug/trace_event.h"
8#include "base/stringprintf.h"
[email protected]4a23c374c2012-12-08 08:38:559#include "base/values.h"
[email protected]95e4e1a02013-03-18 07:09:0910#include "cc/animation/animation_registrar.h"
11#include "cc/animation/scrollbar_animation_controller.h"
12#include "cc/animation/scrollbar_animation_controller_linear_fade.h"
[email protected]681ccff2013-03-18 06:13:5213#include "cc/base/math_util.h"
[email protected]6e84de22013-03-18 06:54:2714#include "cc/debug/debug_colors.h"
15#include "cc/debug/layer_tree_debug_state.h"
[email protected]55a124d02012-10-22 03:07:1316#include "cc/quad_sink.h"
[email protected]89e8267a2013-03-18 07:50:5617#include "cc/quads/debug_border_draw_quad.h"
[email protected]e45638c2013-01-17 22:01:4018#include "cc/scrollbar_layer_impl.h"
[email protected]556fd292013-03-18 08:03:0419#include "cc/trees/layer_tree_impl.h"
20#include "cc/trees/layer_tree_settings.h"
21#include "cc/trees/proxy.h"
[email protected]aad0a0072012-11-01 18:15:5822#include "ui/gfx/point_conversions.h"
[email protected]8c5690222013-02-15 17:36:4323#include "ui/gfx/quad_f.h"
[email protected]aad0a0072012-11-01 18:15:5824#include "ui/gfx/rect_conversions.h"
[email protected]94f206c12012-08-25 00:09:1425
[email protected]9c88e562012-09-14 22:21:3026namespace cc {
[email protected]94f206c12012-08-25 00:09:1427
[email protected]7aba6662013-03-12 10:17:3428LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id)
29 : parent_(NULL),
30 mask_layer_id_(-1),
31 replica_layer_id_(-1),
32 layer_id_(id),
33 layer_tree_impl_(tree_impl),
34 anchor_point_(0.5f, 0.5f),
35 anchor_point_z_(0.f),
36 scrollable_(false),
37 should_scroll_on_main_thread_(false),
38 have_wheel_event_handlers_(false),
39 background_color_(0),
40 stacking_order_changed_(false),
41 double_sided_(true),
42 layer_property_changed_(false),
43 layer_surface_property_changed_(false),
44 masks_to_bounds_(false),
45 contents_opaque_(false),
46 opacity_(1.0),
47 preserves_3d_(false),
48 use_parent_backface_visibility_(false),
49 draw_checkerboard_for_missing_tiles_(false),
50 draws_content_(false),
51 force_render_surface_(false),
52 is_container_for_fixed_position_layers_(false),
53 fixed_to_container_layer_(false),
54 draw_depth_(0.f),
[email protected]e7f87cfb2012-10-17 01:25:1855#ifndef NDEBUG
[email protected]7aba6662013-03-12 10:17:3456 between_will_draw_and_did_draw_(false),
[email protected]94f206c12012-08-25 00:09:1457#endif
[email protected]7aba6662013-03-12 10:17:3458 horizontal_scrollbar_layer_(NULL),
59 vertical_scrollbar_layer_(NULL) {
60 DCHECK(layer_id_ > 0);
61 DCHECK(layer_tree_impl_);
62 layer_tree_impl_->RegisterLayer(this);
63 AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar();
64 layer_animation_controller_ =
65 registrar->GetAnimationControllerForId(layer_id_);
66 layer_animation_controller_->AddObserver(this);
[email protected]94f206c12012-08-25 00:09:1467}
68
[email protected]7aba6662013-03-12 10:17:3469LayerImpl::~LayerImpl() {
[email protected]e7f87cfb2012-10-17 01:25:1870#ifndef NDEBUG
[email protected]7aba6662013-03-12 10:17:3471 DCHECK(!between_will_draw_and_did_draw_);
[email protected]e7f87cfb2012-10-17 01:25:1872#endif
[email protected]7aba6662013-03-12 10:17:3473 layer_tree_impl_->UnregisterLayer(this);
74 layer_animation_controller_->RemoveObserver(this);
[email protected]94f206c12012-08-25 00:09:1475}
76
[email protected]7aba6662013-03-12 10:17:3477void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) {
78 child->set_parent(this);
79 DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl());
80 children_.push_back(child.Pass());
81 layer_tree_impl()->set_needs_update_draw_properties();
[email protected]94f206c12012-08-25 00:09:1482}
83
[email protected]7aba6662013-03-12 10:17:3484scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) {
85 for (ScopedPtrVector<LayerImpl>::iterator it = children_.begin();
86 it != children_.end();
87 ++it) {
88 if (*it == child) {
89 scoped_ptr<LayerImpl> ret = children_.take(it);
90 children_.erase(it);
91 layer_tree_impl()->set_needs_update_draw_properties();
92 return ret.Pass();
[email protected]94f206c12012-08-25 00:09:1493 }
[email protected]7aba6662013-03-12 10:17:3494 }
95 return scoped_ptr<LayerImpl>();
[email protected]94f206c12012-08-25 00:09:1496}
97
[email protected]7aba6662013-03-12 10:17:3498void LayerImpl::ClearChildList() {
99 if (children_.empty())
100 return;
[email protected]0ede3bb2012-12-09 09:14:39101
[email protected]7aba6662013-03-12 10:17:34102 children_.clear();
103 layer_tree_impl()->set_needs_update_draw_properties();
[email protected]94f206c12012-08-25 00:09:14104}
105
[email protected]7aba6662013-03-12 10:17:34106void LayerImpl::CreateRenderSurface() {
107 DCHECK(!draw_properties_.render_surface);
108 draw_properties_.render_surface =
109 make_scoped_ptr(new RenderSurfaceImpl(this));
110 draw_properties_.render_target = this;
[email protected]94f206c12012-08-25 00:09:14111}
112
[email protected]7aba6662013-03-12 10:17:34113scoped_ptr<SharedQuadState> LayerImpl::CreateSharedQuadState() const {
[email protected]cb7af742012-11-21 04:02:24114 scoped_ptr<SharedQuadState> state = SharedQuadState::Create();
[email protected]7aba6662013-03-12 10:17:34115 state->SetAll(draw_properties_.target_space_transform,
116 draw_properties_.content_bounds,
117 draw_properties_.visible_content_rect,
118 draw_properties_.clip_rect,
119 draw_properties_.is_clipped,
120 draw_properties_.opacity);
[email protected]cb7af742012-11-21 04:02:24121 return state.Pass();
[email protected]94f206c12012-08-25 00:09:14122}
123
[email protected]7aba6662013-03-12 10:17:34124void LayerImpl::WillDraw(ResourceProvider* resource_provider) {
[email protected]e7f87cfb2012-10-17 01:25:18125#ifndef NDEBUG
[email protected]7aba6662013-03-12 10:17:34126 // willDraw/didDraw must be matched.
127 DCHECK(!between_will_draw_and_did_draw_);
128 between_will_draw_and_did_draw_ = true;
[email protected]94f206c12012-08-25 00:09:14129#endif
130}
131
[email protected]7aba6662013-03-12 10:17:34132void LayerImpl::DidDraw(ResourceProvider* resource_provider) {
[email protected]e7f87cfb2012-10-17 01:25:18133#ifndef NDEBUG
[email protected]7aba6662013-03-12 10:17:34134 DCHECK(between_will_draw_and_did_draw_);
135 between_will_draw_and_did_draw_ = false;
[email protected]94f206c12012-08-25 00:09:14136#endif
137}
138
[email protected]7aba6662013-03-12 10:17:34139bool LayerImpl::ShowDebugBorders() const {
140 return layer_tree_impl()->debug_state().showDebugBorders;
[email protected]3dce37232012-11-15 01:47:44141}
142
[email protected]7aba6662013-03-12 10:17:34143void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const {
144 if (draws_content_) {
145 *color = DebugColors::ContentLayerBorderColor();
146 *width = DebugColors::ContentLayerBorderWidth(layer_tree_impl());
147 return;
148 }
149
150 if (masks_to_bounds_) {
151 *color = DebugColors::MaskingLayerBorderColor();
152 *width = DebugColors::MaskingLayerBorderWidth(layer_tree_impl());
153 return;
154 }
155
156 *color = DebugColors::ContainerLayerBorderColor();
157 *width = DebugColors::ContainerLayerBorderWidth(layer_tree_impl());
158}
159
160void LayerImpl::AppendDebugBorderQuad(
161 QuadSink* quad_sink,
162 const SharedQuadState* shared_quad_state,
163 AppendQuadsData* append_quads_data) const {
164 if (!ShowDebugBorders())
165 return;
166
167 SkColor color;
168 float width;
169 GetDebugBorderProperties(&color, &width);
170
171 gfx::Rect content_rect(content_bounds());
172 scoped_ptr<DebugBorderDrawQuad> debugBorderQuad =
173 DebugBorderDrawQuad::Create();
174 debugBorderQuad->SetNew(shared_quad_state, content_rect, color, width);
[email protected]c7e95b42013-03-18 01:13:49175 quad_sink->Append(debugBorderQuad.PassAs<DrawQuad>(), append_quads_data);
[email protected]7aba6662013-03-12 10:17:34176}
177
178bool LayerImpl::HasDelegatedContent() const {
179 return false;
180}
181
182bool LayerImpl::HasContributingDelegatedRenderPasses() const {
183 return false;
184}
185
186RenderPass::Id LayerImpl::FirstContributingRenderPassId() const {
187 return RenderPass::Id(0, 0);
188}
189
190RenderPass::Id LayerImpl::NextContributingRenderPassId(RenderPass::Id id)
191 const {
192 return RenderPass::Id(0, 0);
193}
194
195ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const {
196 NOTREACHED();
197 return 0;
198}
199
200void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta) {
201 // Pending tree never has sent scroll deltas
202 DCHECK(layer_tree_impl()->IsActiveTree());
203
204 if (sent_scroll_delta_ == sent_scroll_delta)
205 return;
206
207 sent_scroll_delta_ = sent_scroll_delta;
208}
209
210gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) {
211 gfx::Vector2dF min_delta = -scroll_offset_;
212 gfx::Vector2dF max_delta = max_scroll_offset_ - scroll_offset_;
213 // Clamp new_delta so that position + delta stays within scroll bounds.
214 gfx::Vector2dF new_delta = (scroll_delta_ + scroll);
215 new_delta.ClampToMin(min_delta);
216 new_delta.ClampToMax(max_delta);
217 gfx::Vector2dF unscrolled = scroll_delta_ + scroll - new_delta;
218
219 SetScrollDelta(new_delta);
220 return unscrolled;
221}
222
223InputHandlerClient::ScrollStatus LayerImpl::TryScroll(
224 gfx::PointF screen_space_point,
225 InputHandlerClient::ScrollInputType type) const {
226 if (should_scroll_on_main_thread()) {
227 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed shouldScrollOnMainThread");
228 return InputHandlerClient::ScrollOnMainThread;
229 }
230
231 if (!screen_space_transform().IsInvertible()) {
232 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored nonInvertibleTransform");
233 return InputHandlerClient::ScrollIgnored;
234 }
235
236 if (!non_fast_scrollable_region().IsEmpty()) {
237 bool clipped = false;
238 gfx::Transform inverse_screen_space_transform(
239 gfx::Transform::kSkipInitialization);
240 if (!screen_space_transform().GetInverse(&inverse_screen_space_transform)) {
241 // TODO(shawnsingh): We shouldn't be applying a projection if screen space
242 // transform is uninvertible here. Perhaps we should be returning
243 // ScrollOnMainThread in this case?
[email protected]3dce37232012-11-15 01:47:44244 }
245
[email protected]7aba6662013-03-12 10:17:34246 gfx::PointF hit_test_point_in_content_space =
[email protected]fa816c62013-03-18 04:24:21247 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]7aba6662013-03-12 10:17:34248 screen_space_point,
[email protected]fa816c62013-03-18 04:24:21249 &clipped);
[email protected]7aba6662013-03-12 10:17:34250 gfx::PointF hit_test_point_in_layer_space =
251 gfx::ScalePoint(hit_test_point_in_content_space,
252 1.f / contents_scale_x(),
253 1.f / contents_scale_y());
254 if (!clipped &&
255 non_fast_scrollable_region().Contains(
256 gfx::ToRoundedPoint(hit_test_point_in_layer_space))) {
257 TRACE_EVENT0("cc",
258 "LayerImpl::tryScroll: Failed nonFastScrollableRegion");
259 return InputHandlerClient::ScrollOnMainThread;
[email protected]3dce37232012-11-15 01:47:44260 }
[email protected]7aba6662013-03-12 10:17:34261 }
[email protected]3dce37232012-11-15 01:47:44262
[email protected]7aba6662013-03-12 10:17:34263 if (type == InputHandlerClient::Wheel && have_wheel_event_handlers()) {
264 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed wheelEventHandlers");
265 return InputHandlerClient::ScrollOnMainThread;
266 }
267
268 if (!scrollable()) {
269 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable");
270 return InputHandlerClient::ScrollIgnored;
271 }
272
273 if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) {
274 TRACE_EVENT0("cc",
275 "LayerImpl::tryScroll: Ignored. Technically scrollable,"
276 " but has no affordance in either direction.");
277 return InputHandlerClient::ScrollIgnored;
278 }
279
280 return InputHandlerClient::ScrollStarted;
[email protected]3dce37232012-11-15 01:47:44281}
282
[email protected]7aba6662013-03-12 10:17:34283bool LayerImpl::DrawCheckerboardForMissingTiles() const {
284 return draw_checkerboard_for_missing_tiles_ &&
285 !layer_tree_impl()->settings().backgroundColorInsteadOfCheckerboard;
[email protected]94f206c12012-08-25 00:09:14286}
287
[email protected]7aba6662013-03-12 10:17:34288gfx::Rect LayerImpl::LayerRectToContentRect(
289 const gfx::RectF& layer_rect) const {
290 gfx::RectF content_rect =
291 gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y());
292 // Intersect with content rect to avoid the extra pixel because for some
293 // values x and y, ceil((x / y) * y) may be x + 1.
294 content_rect.Intersect(gfx::Rect(content_bounds()));
295 return gfx::ToEnclosingRect(content_rect);
[email protected]b5b1fce2012-12-12 22:49:36296}
297
[email protected]7aba6662013-03-12 10:17:34298skia::RefPtr<SkPicture> LayerImpl::GetPicture() {
299 return skia::RefPtr<SkPicture>();
[email protected]76481592012-09-21 16:47:06300}
301
[email protected]7aba6662013-03-12 10:17:34302bool LayerImpl::CanClipSelf() const {
303 return false;
[email protected]76481592012-09-21 16:47:06304}
305
[email protected]7aba6662013-03-12 10:17:34306bool LayerImpl::AreVisibleResourcesReady() const {
307 return true;
[email protected]76481592012-09-21 16:47:06308}
309
[email protected]7aba6662013-03-12 10:17:34310scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) {
311 return LayerImpl::Create(tree_impl, layer_id_);
[email protected]94f206c12012-08-25 00:09:14312}
313
[email protected]7aba6662013-03-12 10:17:34314void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
315 layer->SetAnchorPoint(anchor_point_);
316 layer->SetAnchorPointZ(anchor_point_z_);
317 layer->SetBackgroundColor(background_color_);
318 layer->SetBounds(bounds_);
319 layer->SetContentBounds(content_bounds());
320 layer->SetContentsScale(contents_scale_x(), contents_scale_y());
321 layer->SetDebugName(debug_name_);
322 layer->SetDoubleSided(double_sided_);
323 layer->SetDrawCheckerboardForMissingTiles(
324 draw_checkerboard_for_missing_tiles_);
325 layer->SetForceRenderSurface(force_render_surface_);
326 layer->SetDrawsContent(DrawsContent());
327 layer->SetFilters(filters());
328 layer->SetFilter(filter());
329 layer->SetBackgroundFilters(background_filters());
330 layer->SetMasksToBounds(masks_to_bounds_);
331 layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_);
332 layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_);
333 layer->SetNonFastScrollableRegion(non_fast_scrollable_region_);
334 layer->SetTouchEventHandlerRegion(touch_event_handler_region_);
335 layer->SetContentsOpaque(contents_opaque_);
[email protected]43615872013-03-13 16:35:17336 layer->SetOpacity(opacity_);
[email protected]7aba6662013-03-12 10:17:34337 layer->SetPosition(position_);
338 layer->SetIsContainerForFixedPositionLayers(
339 is_container_for_fixed_position_layers_);
340 layer->SetFixedToContainerLayer(fixed_to_container_layer_);
341 layer->SetPreserves3d(preserves_3d());
342 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_);
343 layer->SetSublayerTransform(sublayer_transform_);
[email protected]43615872013-03-13 16:35:17344 layer->SetTransform(transform_);
[email protected]9bd1cb52013-01-03 22:26:33345
[email protected]7aba6662013-03-12 10:17:34346 layer->SetScrollable(scrollable_);
347 layer->SetScrollOffset(scroll_offset_);
348 layer->SetMaxScrollOffset(max_scroll_offset_);
[email protected]9bd1cb52013-01-03 22:26:33349
[email protected]7aba6662013-03-12 10:17:34350 // If the main thread commits multiple times before the impl thread actually
351 // draws, then damage tracking will become incorrect if we simply clobber the
352 // updateRect here. The LayerImpl's updateRect needs to accumulate (i.e.
353 // union) any update changes that have occurred on the main thread.
354 update_rect_.Union(layer->update_rect());
355 layer->set_update_rect(update_rect_);
356
357 layer->SetScrollDelta(layer->scroll_delta() - layer->sent_scroll_delta());
358 layer->SetSentScrollDelta(gfx::Vector2d());
359
360 layer->SetStackingOrderChanged(stacking_order_changed_);
361
362 layer_animation_controller_->PushAnimationUpdatesTo(
363 layer->layer_animation_controller());
364
365 // Reset any state that should be cleared for the next update.
366 stacking_order_changed_ = false;
367 update_rect_ = gfx::RectF();
[email protected]caa567d2012-12-20 07:56:16368}
369
[email protected]7aba6662013-03-12 10:17:34370std::string LayerImpl::IndentString(int indent) {
371 std::string str;
372 for (int i = 0; i != indent; ++i)
373 str.append(" ");
374 return str;
[email protected]94f206c12012-08-25 00:09:14375}
376
[email protected]7aba6662013-03-12 10:17:34377void LayerImpl::DumpLayerProperties(std::string* str, int indent) const {
378 std::string indent_str = IndentString(indent);
379 str->append(indent_str);
380 base::StringAppendF(str, "layer ID: %d\n", layer_id_);
[email protected]94f206c12012-08-25 00:09:14381
[email protected]7aba6662013-03-12 10:17:34382 str->append(indent_str);
383 base::StringAppendF(
384 str, "bounds: %d, %d\n", bounds().width(), bounds().height());
[email protected]94f206c12012-08-25 00:09:14385
[email protected]7aba6662013-03-12 10:17:34386 if (draw_properties_.render_target) {
387 str->append(indent_str);
388 base::StringAppendF(
389 str, "renderTarget: %d\n", draw_properties_.render_target->layer_id_);
390 }
[email protected]bda41962013-01-07 18:46:17391
[email protected]7aba6662013-03-12 10:17:34392 str->append(indent_str);
393 base::StringAppendF(str, "position: %f, %f\n", position_.x(), position_.y());
[email protected]94f206c12012-08-25 00:09:14394
[email protected]7aba6662013-03-12 10:17:34395 str->append(indent_str);
396 base::StringAppendF(str, "contentsOpaque: %d\n", contents_opaque_);
[email protected]94f206c12012-08-25 00:09:14397
[email protected]7aba6662013-03-12 10:17:34398 str->append(indent_str);
399 const gfx::Transform& transform = draw_properties_.target_space_transform;
400 base::StringAppendF(str,
401 "drawTransform: %f, %f, %f, %f // %f, %f, %f, %f"
402 " // %f, %f, %f, %f // %f, %f, %f, %f\n",
403 transform.matrix().getDouble(0, 0),
404 transform.matrix().getDouble(0, 1),
405 transform.matrix().getDouble(0, 2),
406 transform.matrix().getDouble(0, 3),
407 transform.matrix().getDouble(1, 0),
408 transform.matrix().getDouble(1, 1),
409 transform.matrix().getDouble(1, 2),
410 transform.matrix().getDouble(1, 3),
411 transform.matrix().getDouble(2, 0),
412 transform.matrix().getDouble(2, 1),
413 transform.matrix().getDouble(2, 2),
414 transform.matrix().getDouble(2, 3),
415 transform.matrix().getDouble(3, 0),
416 transform.matrix().getDouble(3, 1),
417 transform.matrix().getDouble(3, 2),
418 transform.matrix().getDouble(3, 3));
[email protected]94f206c12012-08-25 00:09:14419
[email protected]7aba6662013-03-12 10:17:34420 str->append(indent_str);
421 base::StringAppendF(
422 str, "draws_content: %s\n", draws_content_ ? "yes" : "no");
[email protected]94f206c12012-08-25 00:09:14423}
424
[email protected]7aba6662013-03-12 10:17:34425std::string LayerImpl::LayerTreeAsText() const {
426 std::string str;
427 DumpLayer(&str, 0);
428 return str;
[email protected]15dabb72012-10-04 20:07:29429}
430
[email protected]7aba6662013-03-12 10:17:34431void LayerImpl::DumpLayer(std::string* str, int indent) const {
432 str->append(IndentString(indent));
433 base::StringAppendF(str, "%s(%s)\n", LayerTypeAsString(), debug_name_.data());
434 DumpLayerProperties(str, indent+2);
435 if (replica_layer_) {
436 str->append(IndentString(indent+2));
437 str->append("Replica:\n");
438 replica_layer_->DumpLayer(str, indent+3);
439 }
440 if (mask_layer_) {
441 str->append(IndentString(indent+2));
442 str->append("Mask:\n");
443 mask_layer_->DumpLayer(str, indent+3);
444 }
445 for (size_t i = 0; i < children_.size(); ++i)
446 children_[i]->DumpLayer(str, indent+1);
[email protected]e1324f252012-09-24 21:39:15447}
448
[email protected]7aba6662013-03-12 10:17:34449base::DictionaryValue* LayerImpl::LayerTreeAsJson() const {
450 base::ListValue* list;
451 base::DictionaryValue* result = new base::DictionaryValue;
452 result->SetString("LayerType", LayerTypeAsString());
453
454 list = new base::ListValue;
455 list->AppendInteger(bounds().width());
456 list->AppendInteger(bounds().height());
457 result->Set("Bounds", list);
458
459 list = new base::ListValue;
460 list->AppendDouble(position_.x());
461 list->AppendDouble(position_.y());
462 result->Set("Position", list);
463
464 const gfx::Transform& gfx_transform = draw_properties_.target_space_transform;
465 double transform[16];
466 gfx_transform.matrix().asColMajord(transform);
467 list = new base::ListValue;
468 for (int i = 0; i < 16; ++i)
469 list->AppendDouble(transform[i]);
470 result->Set("DrawTransform", list);
471
472 result->SetBoolean("DrawsContent", draws_content_);
473 result->SetDouble("Opacity", opacity());
474
475 list = new base::ListValue;
476 for (size_t i = 0; i < children_.size(); ++i)
477 list->Append(children_[i]->LayerTreeAsJson());
478 result->Set("Children", list);
479
480 return result;
[email protected]b9dcf43a2013-01-09 00:15:29481}
482
[email protected]7aba6662013-03-12 10:17:34483void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) {
484 if (stacking_order_changed) {
485 stacking_order_changed_ = true;
486 NoteLayerPropertyChangedForSubtree();
487 }
[email protected]aedf4e52013-01-09 23:24:44488}
489
[email protected]7aba6662013-03-12 10:17:34490bool LayerImpl::LayerSurfacePropertyChanged() const {
491 if (layer_surface_property_changed_)
[email protected]b0a917c8d2013-01-12 17:42:25492 return true;
[email protected]7aba6662013-03-12 10:17:34493
494 // If this layer's surface property hasn't changed, we want to see if
495 // some layer above us has changed this property. This is done for the
496 // case when such parent layer does not draw content, and therefore will
497 // not be traversed by the damage tracker. We need to make sure that
498 // property change on such layer will be caught by its descendants.
499 LayerImpl* current = this->parent_;
500 while (current && !current->draw_properties_.render_surface) {
501 if (current->layer_surface_property_changed_)
502 return true;
503 current = current->parent_;
504 }
505
506 return false;
[email protected]b0a917c8d2013-01-12 17:42:25507}
508
[email protected]7aba6662013-03-12 10:17:34509void LayerImpl::NoteLayerSurfacePropertyChanged() {
510 layer_surface_property_changed_ = true;
511 layer_tree_impl()->set_needs_update_draw_properties();
[email protected]48871fc2013-01-23 07:36:51512}
513
[email protected]7aba6662013-03-12 10:17:34514void LayerImpl::NoteLayerPropertyChanged() {
515 layer_property_changed_ = true;
516 layer_tree_impl()->set_needs_update_draw_properties();
[email protected]48871fc2013-01-23 07:36:51517}
518
[email protected]7aba6662013-03-12 10:17:34519void LayerImpl::NoteLayerPropertyChangedForSubtree() {
520 NoteLayerPropertyChanged();
521 NoteLayerPropertyChangedForDescendants();
[email protected]94f206c12012-08-25 00:09:14522}
523
[email protected]7aba6662013-03-12 10:17:34524void LayerImpl::NoteLayerPropertyChangedForDescendants() {
525 layer_tree_impl()->set_needs_update_draw_properties();
526 for (size_t i = 0; i < children_.size(); ++i)
527 children_[i]->NoteLayerPropertyChangedForSubtree();
528}
[email protected]94f206c12012-08-25 00:09:14529
[email protected]7aba6662013-03-12 10:17:34530const char* LayerImpl::LayerTypeAsString() const {
531 return "Layer";
532}
[email protected]94f206c12012-08-25 00:09:14533
[email protected]7aba6662013-03-12 10:17:34534void LayerImpl::ResetAllChangeTrackingForSubtree() {
535 layer_property_changed_ = false;
536 layer_surface_property_changed_ = false;
537
538 update_rect_ = gfx::RectF();
539
540 if (draw_properties_.render_surface)
541 draw_properties_.render_surface->ResetPropertyChangedFlag();
542
543 if (mask_layer_)
544 mask_layer_->ResetAllChangeTrackingForSubtree();
545
546 if (replica_layer_) {
547 // This also resets the replica mask, if it exists.
548 replica_layer_->ResetAllChangeTrackingForSubtree();
549 }
550
551 for (size_t i = 0; i < children_.size(); ++i)
552 children_[i]->ResetAllChangeTrackingForSubtree();
553}
554
555bool LayerImpl::LayerIsAlwaysDamaged() const {
556 return false;
557}
558
559void LayerImpl::OnOpacityAnimated(float opacity) {
560 SetOpacity(opacity);
561}
562
563void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) {
564 SetTransform(transform);
565}
566
567bool LayerImpl::IsActive() const {
568 return layer_tree_impl_->IsActiveTree();
569}
570
571void LayerImpl::SetBounds(gfx::Size bounds) {
572 if (bounds_ == bounds)
573 return;
574
575 bounds_ = bounds;
576
577 if (masks_to_bounds())
578 NoteLayerPropertyChangedForSubtree();
579 else
580 NoteLayerPropertyChanged();
581}
582
583void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) {
584 int new_layer_id = mask_layer ? mask_layer->id() : -1;
585
586 if (mask_layer) {
587 DCHECK_EQ(layer_tree_impl(), mask_layer->layer_tree_impl());
588 DCHECK_NE(new_layer_id, mask_layer_id_);
589 } else if (new_layer_id == mask_layer_id_) {
590 return;
591 }
592
593 mask_layer_ = mask_layer.Pass();
594 mask_layer_id_ = new_layer_id;
595 if (mask_layer_)
596 mask_layer_->set_parent(this);
597 NoteLayerPropertyChangedForSubtree();
598}
599
600scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() {
601 mask_layer_id_ = -1;
602 return mask_layer_.Pass();
603}
604
605void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) {
606 int new_layer_id = replica_layer ? replica_layer->id() : -1;
607
608 if (replica_layer) {
609 DCHECK_EQ(layer_tree_impl(), replica_layer->layer_tree_impl());
610 DCHECK_NE(new_layer_id, replica_layer_id_);
611 } else if (new_layer_id == replica_layer_id_) {
612 return;
613 }
614
615 replica_layer_ = replica_layer.Pass();
616 replica_layer_id_ = new_layer_id;
617 if (replica_layer_)
618 replica_layer_->set_parent(this);
619 NoteLayerPropertyChangedForSubtree();
620}
621
622scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() {
623 replica_layer_id_ = -1;
624 return replica_layer_.Pass();
625}
626
627ScrollbarLayerImpl* LayerImpl::ToScrollbarLayer() {
628 return NULL;
629}
630
631void LayerImpl::SetDrawsContent(bool draws_content) {
632 if (draws_content_ == draws_content)
633 return;
634
635 draws_content_ = draws_content;
636 NoteLayerPropertyChanged();
637}
638
639void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point) {
640 if (anchor_point_ == anchor_point)
641 return;
642
643 anchor_point_ = anchor_point;
644 NoteLayerPropertyChangedForSubtree();
645}
646
647void LayerImpl::SetAnchorPointZ(float anchor_point_z) {
648 if (anchor_point_z_ == anchor_point_z)
649 return;
650
651 anchor_point_z_ = anchor_point_z;
652 NoteLayerPropertyChangedForSubtree();
653}
654
655void LayerImpl::SetBackgroundColor(SkColor background_color) {
656 if (background_color_ == background_color)
657 return;
658
659 background_color_ = background_color;
660 NoteLayerPropertyChanged();
661}
662
663void LayerImpl::SetFilters(const WebKit::WebFilterOperations& filters) {
664 if (filters_ == filters)
665 return;
666
667 DCHECK(!filter_);
668 filters_ = filters;
669 NoteLayerPropertyChangedForSubtree();
670}
671
672void LayerImpl::SetBackgroundFilters(
673 const WebKit::WebFilterOperations& filters) {
674 if (background_filters_ == filters)
675 return;
676
677 background_filters_ = filters;
678 NoteLayerPropertyChanged();
679}
680
681void LayerImpl::SetFilter(const skia::RefPtr<SkImageFilter>& filter) {
682 if (filter_.get() == filter.get())
683 return;
684
685 DCHECK(filters_.isEmpty());
686 filter_ = filter;
687 NoteLayerPropertyChangedForSubtree();
688}
689
690void LayerImpl::SetMasksToBounds(bool masks_to_bounds) {
691 if (masks_to_bounds_ == masks_to_bounds)
692 return;
693
694 masks_to_bounds_ = masks_to_bounds;
695 NoteLayerPropertyChangedForSubtree();
696}
697
698void LayerImpl::SetContentsOpaque(bool opaque) {
699 if (contents_opaque_ == opaque)
700 return;
701
702 contents_opaque_ = opaque;
703 NoteLayerPropertyChangedForSubtree();
704}
705
706void LayerImpl::SetOpacity(float opacity) {
707 if (opacity_ == opacity)
708 return;
709
710 opacity_ = opacity;
711 NoteLayerSurfacePropertyChanged();
712}
713
714bool LayerImpl::OpacityIsAnimating() const {
715 return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity);
716}
717
[email protected]43615872013-03-13 16:35:17718bool LayerImpl::OpacityIsAnimatingOnImplOnly() const {
719 Animation* opacity_animation =
720 layer_animation_controller_->GetAnimation(Animation::Opacity);
721 return opacity_animation && opacity_animation->is_impl_only();
722}
723
[email protected]7aba6662013-03-12 10:17:34724void LayerImpl::SetPosition(gfx::PointF position) {
725 if (position_ == position)
726 return;
727
728 position_ = position;
729 NoteLayerPropertyChangedForSubtree();
730}
731
732void LayerImpl::SetPreserves3d(bool preserves3_d) {
733 if (preserves_3d_ == preserves3_d)
734 return;
735
736 preserves_3d_ = preserves3_d;
737 NoteLayerPropertyChangedForSubtree();
738}
739
740void LayerImpl::SetSublayerTransform(const gfx::Transform& sublayer_transform) {
741 if (sublayer_transform_ == sublayer_transform)
742 return;
743
744 sublayer_transform_ = sublayer_transform;
745 // Sublayer transform does not affect the current layer; it affects only its
746 // children.
747 NoteLayerPropertyChangedForDescendants();
748}
749
750void LayerImpl::SetTransform(const gfx::Transform& transform) {
751 if (transform_ == transform)
752 return;
753
754 transform_ = transform;
755 NoteLayerSurfacePropertyChanged();
756}
757
758bool LayerImpl::TransformIsAnimating() const {
759 return layer_animation_controller_->IsAnimatingProperty(Animation::Transform);
760}
761
[email protected]43615872013-03-13 16:35:17762bool LayerImpl::TransformIsAnimatingOnImplOnly() const {
763 Animation* transform_animation =
764 layer_animation_controller_->GetAnimation(Animation::Transform);
765 return transform_animation && transform_animation->is_impl_only();
766}
767
[email protected]7aba6662013-03-12 10:17:34768void LayerImpl::SetContentBounds(gfx::Size content_bounds) {
769 if (this->content_bounds() == content_bounds)
770 return;
771
772 draw_properties_.content_bounds = content_bounds;
773 NoteLayerPropertyChanged();
774}
775
776void LayerImpl::SetContentsScale(float contents_scale_x,
777 float contents_scale_y) {
778 if (this->contents_scale_x() == contents_scale_x &&
779 this->contents_scale_y() == contents_scale_y)
780 return;
781
782 draw_properties_.contents_scale_x = contents_scale_x;
783 draw_properties_.contents_scale_y = contents_scale_y;
784 NoteLayerPropertyChanged();
785}
786
787void LayerImpl::CalculateContentsScale(
788 float ideal_contents_scale,
789 bool animating_transform_to_screen,
790 float* contents_scale_x,
791 float* contents_scale_y,
792 gfx::Size* content_bounds) {
793 // Base LayerImpl has all of its content scales and content bounds pushed
794 // from its Layer during commit and just reuses those values as-is.
795 *contents_scale_x = this->contents_scale_x();
796 *contents_scale_y = this->contents_scale_y();
797 *content_bounds = this->content_bounds();
798}
799
800void LayerImpl::UpdateScrollbarPositions() {
801 gfx::Vector2dF current_offset = scroll_offset_ + scroll_delta_;
802
803 if (horizontal_scrollbar_layer_) {
804 horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x());
805 horizontal_scrollbar_layer_->SetTotalSize(bounds_.width());
806 horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x());
807 }
808 if (vertical_scrollbar_layer_) {
809 vertical_scrollbar_layer_->SetCurrentPos(current_offset.y());
810 vertical_scrollbar_layer_->SetTotalSize(bounds_.height());
811 vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y());
812 }
813
814 if (current_offset == last_scroll_offset_)
815 return;
816 last_scroll_offset_ = current_offset;
817
[email protected]0fc818e2013-03-18 06:45:20818 if (scrollbar_animation_controller_ &&
819 !scrollbar_animation_controller_->isScrollGestureInProgress()) {
820 scrollbar_animation_controller_->didProgrammaticallyUpdateScroll(
[email protected]7aba6662013-03-12 10:17:34821 base::TimeTicks::Now());
822 }
823
824 // Get the current_offset_.y() value for a sanity-check on scrolling
825 // benchmark metrics. Specifically, we want to make sure
826 // BasicMouseWheelSmoothScrollGesture has proper scroll curves.
827 if (layer_tree_impl()->IsActiveTree()) {
828 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y());
829 }
830}
831
832void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) {
833 if (scroll_offset_ == scroll_offset)
834 return;
835
836 scroll_offset_ = scroll_offset;
837 NoteLayerPropertyChangedForSubtree();
838 UpdateScrollbarPositions();
839}
840
841void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) {
842 if (scroll_delta_ == scroll_delta)
843 return;
844
845 if (layer_tree_impl()->IsActiveTree()) {
846 LayerImpl* pending_twin = layer_tree_impl()->FindPendingTreeLayerById(id());
847 if (pending_twin) {
848 // The pending twin can't mirror the scroll delta of the active
849 // layer. Although the delta - sent scroll delta difference is
850 // identical for both twins, the sent scroll delta for the pending
851 // layer is zero, as anything that has been sent has been baked
852 // into the layer's position/scroll offset as a part of commit.
853 DCHECK(pending_twin->sent_scroll_delta().IsZero());
854 pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta());
[email protected]94f206c12012-08-25 00:09:14855 }
[email protected]7aba6662013-03-12 10:17:34856 }
[email protected]94f206c12012-08-25 00:09:14857
[email protected]7aba6662013-03-12 10:17:34858 scroll_delta_ = scroll_delta;
859 NoteLayerPropertyChangedForSubtree();
[email protected]9a5710432012-11-09 20:52:35860
[email protected]7aba6662013-03-12 10:17:34861 UpdateScrollbarPositions();
[email protected]94f206c12012-08-25 00:09:14862}
863
[email protected]ffb2720f2013-03-15 19:18:37864gfx::Vector2dF LayerImpl::TotalScrollOffset() const {
865 return scroll_offset_ + scroll_delta_;
866}
867
[email protected]7aba6662013-03-12 10:17:34868void LayerImpl::SetImplTransform(const gfx::Transform& transform) {
869 if (impl_transform_ == transform)
870 return;
871
872 impl_transform_ = transform;
873 NoteLayerPropertyChangedForSubtree();
[email protected]94f206c12012-08-25 00:09:14874}
875
[email protected]7aba6662013-03-12 10:17:34876void LayerImpl::SetDoubleSided(bool double_sided) {
877 if (double_sided_ == double_sided)
878 return;
879
880 double_sided_ = double_sided;
881 NoteLayerPropertyChangedForSubtree();
882}
883
884Region LayerImpl::VisibleContentOpaqueRegion() const {
885 if (contents_opaque())
886 return visible_content_rect();
887 return Region();
888}
889
890void LayerImpl::DidLoseOutputSurface() {}
891
892void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) {
893 if (max_scroll_offset_ == max_scroll_offset)
894 return;
895 max_scroll_offset_ = max_scroll_offset;
896
897 layer_tree_impl()->set_needs_update_draw_properties();
898 UpdateScrollbarPositions();
899}
900
901void LayerImpl::SetScrollbarOpacity(float opacity) {
902 if (horizontal_scrollbar_layer_)
903 horizontal_scrollbar_layer_->SetOpacity(opacity);
904 if (vertical_scrollbar_layer_)
905 vertical_scrollbar_layer_->SetOpacity(opacity);
906}
907
908inline scoped_ptr<ScrollbarAnimationController>
909CreateScrollbarAnimationControllerWithFade(LayerImpl* layer) {
[email protected]0fc818e2013-03-18 06:45:20910 base::TimeDelta fadeout_delay = base::TimeDelta::FromMilliseconds(300);
911 base::TimeDelta fadeout_length = base::TimeDelta::FromMilliseconds(300);
[email protected]7aba6662013-03-12 10:17:34912 return ScrollbarAnimationControllerLinearFade::create(
913 layer, fadeout_delay, fadeout_length)
914 .PassAs<ScrollbarAnimationController>();
915}
916
917void LayerImpl::DidBecomeActive() {
918 if (!layer_tree_impl_->settings().useLinearFadeScrollbarAnimator)
919 return;
920
921 bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ ||
922 vertical_scrollbar_layer_;
923 if (need_scrollbar_animation_controller) {
924 if (!scrollbar_animation_controller_) {
925 scrollbar_animation_controller_ =
926 CreateScrollbarAnimationControllerWithFade(this);
[email protected]94f206c12012-08-25 00:09:14927 }
[email protected]7aba6662013-03-12 10:17:34928 } else {
929 scrollbar_animation_controller_.reset();
930 }
[email protected]e45638c2013-01-17 22:01:40931
932}
[email protected]7aba6662013-03-12 10:17:34933void LayerImpl::SetHorizontalScrollbarLayer(
934 ScrollbarLayerImpl* scrollbar_layer) {
935 horizontal_scrollbar_layer_ = scrollbar_layer;
936 if (horizontal_scrollbar_layer_)
937 horizontal_scrollbar_layer_->set_scroll_layer_id(id());
[email protected]94f206c12012-08-25 00:09:14938}
939
[email protected]7aba6662013-03-12 10:17:34940void LayerImpl::SetVerticalScrollbarLayer(ScrollbarLayerImpl* scrollbar_layer) {
941 vertical_scrollbar_layer_ = scrollbar_layer;
942 if (vertical_scrollbar_layer_)
943 vertical_scrollbar_layer_->set_scroll_layer_id(id());
[email protected]94f206c12012-08-25 00:09:14944}
945
[email protected]7aba6662013-03-12 10:17:34946void LayerImpl::AsValueInto(base::DictionaryValue* dict) const {
947 dict->SetInteger("id", id());
[email protected]fa816c62013-03-18 04:24:21948 dict->Set("bounds", MathUtil::AsValue(bounds()).release());
[email protected]7aba6662013-03-12 10:17:34949 dict->SetInteger("draws_content", DrawsContent());
[email protected]8c5690222013-02-15 17:36:43950
[email protected]7aba6662013-03-12 10:17:34951 bool clipped;
[email protected]fa816c62013-03-18 04:24:21952 gfx::QuadF layer_quad = MathUtil::MapQuad(
[email protected]7aba6662013-03-12 10:17:34953 screen_space_transform(),
954 gfx::QuadF(gfx::Rect(content_bounds())),
[email protected]fa816c62013-03-18 04:24:21955 &clipped);
956 dict->Set("layer_quad", MathUtil::AsValue(layer_quad).release());
[email protected]8c5690222013-02-15 17:36:43957
958}
959
[email protected]7aba6662013-03-12 10:17:34960scoped_ptr<base::Value> LayerImpl::AsValue() const {
961 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
962 AsValueInto(state.get());
963 return state.PassAs<base::Value>();
[email protected]8c5690222013-02-15 17:36:43964}
965
[email protected]bc5e77c2012-11-05 20:00:49966} // namespace cc