[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 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 | |
[email protected] | d50c686 | 2012-10-23 02:08:31 | [diff] [blame] | 5 | #include "cc/layer_impl.h" |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 6 | |
[email protected] | c4040a52 | 2012-10-21 15:01:40 | [diff] [blame] | 7 | #include "base/debug/trace_event.h" |
| 8 | #include "base/stringprintf.h" |
[email protected] | 4a23c374c | 2012-12-08 08:38:55 | [diff] [blame] | 9 | #include "base/values.h" |
[email protected] | 95e4e1a0 | 2013-03-18 07:09:09 | [diff] [blame] | 10 | #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] | 681ccff | 2013-03-18 06:13:52 | [diff] [blame] | 13 | #include "cc/base/math_util.h" |
[email protected] | 6e84de2 | 2013-03-18 06:54:27 | [diff] [blame] | 14 | #include "cc/debug/debug_colors.h" |
| 15 | #include "cc/debug/layer_tree_debug_state.h" |
[email protected] | 55a124d0 | 2012-10-22 03:07:13 | [diff] [blame] | 16 | #include "cc/quad_sink.h" |
[email protected] | 89e8267a | 2013-03-18 07:50:56 | [diff] [blame] | 17 | #include "cc/quads/debug_border_draw_quad.h" |
[email protected] | e45638c | 2013-01-17 22:01:40 | [diff] [blame] | 18 | #include "cc/scrollbar_layer_impl.h" |
[email protected] | 556fd29 | 2013-03-18 08:03:04 | [diff] [blame^] | 19 | #include "cc/trees/layer_tree_impl.h" |
| 20 | #include "cc/trees/layer_tree_settings.h" |
| 21 | #include "cc/trees/proxy.h" |
[email protected] | aad0a007 | 2012-11-01 18:15:58 | [diff] [blame] | 22 | #include "ui/gfx/point_conversions.h" |
[email protected] | 8c569022 | 2013-02-15 17:36:43 | [diff] [blame] | 23 | #include "ui/gfx/quad_f.h" |
[email protected] | aad0a007 | 2012-11-01 18:15:58 | [diff] [blame] | 24 | #include "ui/gfx/rect_conversions.h" |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 25 | |
[email protected] | 9c88e56 | 2012-09-14 22:21:30 | [diff] [blame] | 26 | namespace cc { |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 27 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 28 | LayerImpl::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] | e7f87cfb | 2012-10-17 01:25:18 | [diff] [blame] | 55 | #ifndef NDEBUG |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 56 | between_will_draw_and_did_draw_(false), |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 57 | #endif |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 58 | 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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 67 | } |
| 68 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 69 | LayerImpl::~LayerImpl() { |
[email protected] | e7f87cfb | 2012-10-17 01:25:18 | [diff] [blame] | 70 | #ifndef NDEBUG |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 71 | DCHECK(!between_will_draw_and_did_draw_); |
[email protected] | e7f87cfb | 2012-10-17 01:25:18 | [diff] [blame] | 72 | #endif |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 73 | layer_tree_impl_->UnregisterLayer(this); |
| 74 | layer_animation_controller_->RemoveObserver(this); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 75 | } |
| 76 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 77 | void 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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 82 | } |
| 83 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 84 | scoped_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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 93 | } |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 94 | } |
| 95 | return scoped_ptr<LayerImpl>(); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 96 | } |
| 97 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 98 | void LayerImpl::ClearChildList() { |
| 99 | if (children_.empty()) |
| 100 | return; |
[email protected] | 0ede3bb | 2012-12-09 09:14:39 | [diff] [blame] | 101 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 102 | children_.clear(); |
| 103 | layer_tree_impl()->set_needs_update_draw_properties(); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 104 | } |
| 105 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 106 | void 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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 111 | } |
| 112 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 113 | scoped_ptr<SharedQuadState> LayerImpl::CreateSharedQuadState() const { |
[email protected] | cb7af74 | 2012-11-21 04:02:24 | [diff] [blame] | 114 | scoped_ptr<SharedQuadState> state = SharedQuadState::Create(); |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 115 | 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] | cb7af74 | 2012-11-21 04:02:24 | [diff] [blame] | 121 | return state.Pass(); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 122 | } |
| 123 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 124 | void LayerImpl::WillDraw(ResourceProvider* resource_provider) { |
[email protected] | e7f87cfb | 2012-10-17 01:25:18 | [diff] [blame] | 125 | #ifndef NDEBUG |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 126 | // willDraw/didDraw must be matched. |
| 127 | DCHECK(!between_will_draw_and_did_draw_); |
| 128 | between_will_draw_and_did_draw_ = true; |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 129 | #endif |
| 130 | } |
| 131 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 132 | void LayerImpl::DidDraw(ResourceProvider* resource_provider) { |
[email protected] | e7f87cfb | 2012-10-17 01:25:18 | [diff] [blame] | 133 | #ifndef NDEBUG |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 134 | DCHECK(between_will_draw_and_did_draw_); |
| 135 | between_will_draw_and_did_draw_ = false; |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 136 | #endif |
| 137 | } |
| 138 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 139 | bool LayerImpl::ShowDebugBorders() const { |
| 140 | return layer_tree_impl()->debug_state().showDebugBorders; |
[email protected] | 3dce3723 | 2012-11-15 01:47:44 | [diff] [blame] | 141 | } |
| 142 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 143 | void 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 | |
| 160 | void 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] | c7e95b4 | 2013-03-18 01:13:49 | [diff] [blame] | 175 | quad_sink->Append(debugBorderQuad.PassAs<DrawQuad>(), append_quads_data); |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 176 | } |
| 177 | |
| 178 | bool LayerImpl::HasDelegatedContent() const { |
| 179 | return false; |
| 180 | } |
| 181 | |
| 182 | bool LayerImpl::HasContributingDelegatedRenderPasses() const { |
| 183 | return false; |
| 184 | } |
| 185 | |
| 186 | RenderPass::Id LayerImpl::FirstContributingRenderPassId() const { |
| 187 | return RenderPass::Id(0, 0); |
| 188 | } |
| 189 | |
| 190 | RenderPass::Id LayerImpl::NextContributingRenderPassId(RenderPass::Id id) |
| 191 | const { |
| 192 | return RenderPass::Id(0, 0); |
| 193 | } |
| 194 | |
| 195 | ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const { |
| 196 | NOTREACHED(); |
| 197 | return 0; |
| 198 | } |
| 199 | |
| 200 | void 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 | |
| 210 | gfx::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 | |
| 223 | InputHandlerClient::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] | 3dce3723 | 2012-11-15 01:47:44 | [diff] [blame] | 244 | } |
| 245 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 246 | gfx::PointF hit_test_point_in_content_space = |
[email protected] | fa816c6 | 2013-03-18 04:24:21 | [diff] [blame] | 247 | MathUtil::ProjectPoint(inverse_screen_space_transform, |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 248 | screen_space_point, |
[email protected] | fa816c6 | 2013-03-18 04:24:21 | [diff] [blame] | 249 | &clipped); |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 250 | 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] | 3dce3723 | 2012-11-15 01:47:44 | [diff] [blame] | 260 | } |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 261 | } |
[email protected] | 3dce3723 | 2012-11-15 01:47:44 | [diff] [blame] | 262 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 263 | 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] | 3dce3723 | 2012-11-15 01:47:44 | [diff] [blame] | 281 | } |
| 282 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 283 | bool LayerImpl::DrawCheckerboardForMissingTiles() const { |
| 284 | return draw_checkerboard_for_missing_tiles_ && |
| 285 | !layer_tree_impl()->settings().backgroundColorInsteadOfCheckerboard; |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 286 | } |
| 287 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 288 | gfx::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] | b5b1fce | 2012-12-12 22:49:36 | [diff] [blame] | 296 | } |
| 297 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 298 | skia::RefPtr<SkPicture> LayerImpl::GetPicture() { |
| 299 | return skia::RefPtr<SkPicture>(); |
[email protected] | 7648159 | 2012-09-21 16:47:06 | [diff] [blame] | 300 | } |
| 301 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 302 | bool LayerImpl::CanClipSelf() const { |
| 303 | return false; |
[email protected] | 7648159 | 2012-09-21 16:47:06 | [diff] [blame] | 304 | } |
| 305 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 306 | bool LayerImpl::AreVisibleResourcesReady() const { |
| 307 | return true; |
[email protected] | 7648159 | 2012-09-21 16:47:06 | [diff] [blame] | 308 | } |
| 309 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 310 | scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { |
| 311 | return LayerImpl::Create(tree_impl, layer_id_); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 312 | } |
| 313 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 314 | void 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] | 4361587 | 2013-03-13 16:35:17 | [diff] [blame] | 336 | layer->SetOpacity(opacity_); |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 337 | 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] | 4361587 | 2013-03-13 16:35:17 | [diff] [blame] | 344 | layer->SetTransform(transform_); |
[email protected] | 9bd1cb5 | 2013-01-03 22:26:33 | [diff] [blame] | 345 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 346 | layer->SetScrollable(scrollable_); |
| 347 | layer->SetScrollOffset(scroll_offset_); |
| 348 | layer->SetMaxScrollOffset(max_scroll_offset_); |
[email protected] | 9bd1cb5 | 2013-01-03 22:26:33 | [diff] [blame] | 349 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 350 | // 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] | caa567d | 2012-12-20 07:56:16 | [diff] [blame] | 368 | } |
| 369 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 370 | std::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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 375 | } |
| 376 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 377 | void 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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 381 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 382 | str->append(indent_str); |
| 383 | base::StringAppendF( |
| 384 | str, "bounds: %d, %d\n", bounds().width(), bounds().height()); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 385 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 386 | 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] | bda4196 | 2013-01-07 18:46:17 | [diff] [blame] | 391 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 392 | str->append(indent_str); |
| 393 | base::StringAppendF(str, "position: %f, %f\n", position_.x(), position_.y()); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 394 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 395 | str->append(indent_str); |
| 396 | base::StringAppendF(str, "contentsOpaque: %d\n", contents_opaque_); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 397 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 398 | 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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 419 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 420 | str->append(indent_str); |
| 421 | base::StringAppendF( |
| 422 | str, "draws_content: %s\n", draws_content_ ? "yes" : "no"); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 423 | } |
| 424 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 425 | std::string LayerImpl::LayerTreeAsText() const { |
| 426 | std::string str; |
| 427 | DumpLayer(&str, 0); |
| 428 | return str; |
[email protected] | 15dabb7 | 2012-10-04 20:07:29 | [diff] [blame] | 429 | } |
| 430 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 431 | void 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] | e1324f25 | 2012-09-24 21:39:15 | [diff] [blame] | 447 | } |
| 448 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 449 | base::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] | b9dcf43a | 2013-01-09 00:15:29 | [diff] [blame] | 481 | } |
| 482 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 483 | void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) { |
| 484 | if (stacking_order_changed) { |
| 485 | stacking_order_changed_ = true; |
| 486 | NoteLayerPropertyChangedForSubtree(); |
| 487 | } |
[email protected] | aedf4e5 | 2013-01-09 23:24:44 | [diff] [blame] | 488 | } |
| 489 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 490 | bool LayerImpl::LayerSurfacePropertyChanged() const { |
| 491 | if (layer_surface_property_changed_) |
[email protected] | b0a917c8d | 2013-01-12 17:42:25 | [diff] [blame] | 492 | return true; |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 493 | |
| 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] | b0a917c8d | 2013-01-12 17:42:25 | [diff] [blame] | 507 | } |
| 508 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 509 | void LayerImpl::NoteLayerSurfacePropertyChanged() { |
| 510 | layer_surface_property_changed_ = true; |
| 511 | layer_tree_impl()->set_needs_update_draw_properties(); |
[email protected] | 48871fc | 2013-01-23 07:36:51 | [diff] [blame] | 512 | } |
| 513 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 514 | void LayerImpl::NoteLayerPropertyChanged() { |
| 515 | layer_property_changed_ = true; |
| 516 | layer_tree_impl()->set_needs_update_draw_properties(); |
[email protected] | 48871fc | 2013-01-23 07:36:51 | [diff] [blame] | 517 | } |
| 518 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 519 | void LayerImpl::NoteLayerPropertyChangedForSubtree() { |
| 520 | NoteLayerPropertyChanged(); |
| 521 | NoteLayerPropertyChangedForDescendants(); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 522 | } |
| 523 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 524 | void 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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 529 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 530 | const char* LayerImpl::LayerTypeAsString() const { |
| 531 | return "Layer"; |
| 532 | } |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 533 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 534 | void 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 | |
| 555 | bool LayerImpl::LayerIsAlwaysDamaged() const { |
| 556 | return false; |
| 557 | } |
| 558 | |
| 559 | void LayerImpl::OnOpacityAnimated(float opacity) { |
| 560 | SetOpacity(opacity); |
| 561 | } |
| 562 | |
| 563 | void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { |
| 564 | SetTransform(transform); |
| 565 | } |
| 566 | |
| 567 | bool LayerImpl::IsActive() const { |
| 568 | return layer_tree_impl_->IsActiveTree(); |
| 569 | } |
| 570 | |
| 571 | void 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 | |
| 583 | void 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 | |
| 600 | scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() { |
| 601 | mask_layer_id_ = -1; |
| 602 | return mask_layer_.Pass(); |
| 603 | } |
| 604 | |
| 605 | void 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 | |
| 622 | scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() { |
| 623 | replica_layer_id_ = -1; |
| 624 | return replica_layer_.Pass(); |
| 625 | } |
| 626 | |
| 627 | ScrollbarLayerImpl* LayerImpl::ToScrollbarLayer() { |
| 628 | return NULL; |
| 629 | } |
| 630 | |
| 631 | void LayerImpl::SetDrawsContent(bool draws_content) { |
| 632 | if (draws_content_ == draws_content) |
| 633 | return; |
| 634 | |
| 635 | draws_content_ = draws_content; |
| 636 | NoteLayerPropertyChanged(); |
| 637 | } |
| 638 | |
| 639 | void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point) { |
| 640 | if (anchor_point_ == anchor_point) |
| 641 | return; |
| 642 | |
| 643 | anchor_point_ = anchor_point; |
| 644 | NoteLayerPropertyChangedForSubtree(); |
| 645 | } |
| 646 | |
| 647 | void 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 | |
| 655 | void LayerImpl::SetBackgroundColor(SkColor background_color) { |
| 656 | if (background_color_ == background_color) |
| 657 | return; |
| 658 | |
| 659 | background_color_ = background_color; |
| 660 | NoteLayerPropertyChanged(); |
| 661 | } |
| 662 | |
| 663 | void LayerImpl::SetFilters(const WebKit::WebFilterOperations& filters) { |
| 664 | if (filters_ == filters) |
| 665 | return; |
| 666 | |
| 667 | DCHECK(!filter_); |
| 668 | filters_ = filters; |
| 669 | NoteLayerPropertyChangedForSubtree(); |
| 670 | } |
| 671 | |
| 672 | void LayerImpl::SetBackgroundFilters( |
| 673 | const WebKit::WebFilterOperations& filters) { |
| 674 | if (background_filters_ == filters) |
| 675 | return; |
| 676 | |
| 677 | background_filters_ = filters; |
| 678 | NoteLayerPropertyChanged(); |
| 679 | } |
| 680 | |
| 681 | void 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 | |
| 690 | void 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 | |
| 698 | void LayerImpl::SetContentsOpaque(bool opaque) { |
| 699 | if (contents_opaque_ == opaque) |
| 700 | return; |
| 701 | |
| 702 | contents_opaque_ = opaque; |
| 703 | NoteLayerPropertyChangedForSubtree(); |
| 704 | } |
| 705 | |
| 706 | void LayerImpl::SetOpacity(float opacity) { |
| 707 | if (opacity_ == opacity) |
| 708 | return; |
| 709 | |
| 710 | opacity_ = opacity; |
| 711 | NoteLayerSurfacePropertyChanged(); |
| 712 | } |
| 713 | |
| 714 | bool LayerImpl::OpacityIsAnimating() const { |
| 715 | return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity); |
| 716 | } |
| 717 | |
[email protected] | 4361587 | 2013-03-13 16:35:17 | [diff] [blame] | 718 | bool 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] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 724 | void LayerImpl::SetPosition(gfx::PointF position) { |
| 725 | if (position_ == position) |
| 726 | return; |
| 727 | |
| 728 | position_ = position; |
| 729 | NoteLayerPropertyChangedForSubtree(); |
| 730 | } |
| 731 | |
| 732 | void LayerImpl::SetPreserves3d(bool preserves3_d) { |
| 733 | if (preserves_3d_ == preserves3_d) |
| 734 | return; |
| 735 | |
| 736 | preserves_3d_ = preserves3_d; |
| 737 | NoteLayerPropertyChangedForSubtree(); |
| 738 | } |
| 739 | |
| 740 | void 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 | |
| 750 | void LayerImpl::SetTransform(const gfx::Transform& transform) { |
| 751 | if (transform_ == transform) |
| 752 | return; |
| 753 | |
| 754 | transform_ = transform; |
| 755 | NoteLayerSurfacePropertyChanged(); |
| 756 | } |
| 757 | |
| 758 | bool LayerImpl::TransformIsAnimating() const { |
| 759 | return layer_animation_controller_->IsAnimatingProperty(Animation::Transform); |
| 760 | } |
| 761 | |
[email protected] | 4361587 | 2013-03-13 16:35:17 | [diff] [blame] | 762 | bool 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] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 768 | void 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 | |
| 776 | void 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 | |
| 787 | void 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 | |
| 800 | void 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] | 0fc818e | 2013-03-18 06:45:20 | [diff] [blame] | 818 | if (scrollbar_animation_controller_ && |
| 819 | !scrollbar_animation_controller_->isScrollGestureInProgress()) { |
| 820 | scrollbar_animation_controller_->didProgrammaticallyUpdateScroll( |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 821 | 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 | |
| 832 | void 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 | |
| 841 | void 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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 855 | } |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 856 | } |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 857 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 858 | scroll_delta_ = scroll_delta; |
| 859 | NoteLayerPropertyChangedForSubtree(); |
[email protected] | 9a571043 | 2012-11-09 20:52:35 | [diff] [blame] | 860 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 861 | UpdateScrollbarPositions(); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 862 | } |
| 863 | |
[email protected] | ffb2720f | 2013-03-15 19:18:37 | [diff] [blame] | 864 | gfx::Vector2dF LayerImpl::TotalScrollOffset() const { |
| 865 | return scroll_offset_ + scroll_delta_; |
| 866 | } |
| 867 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 868 | void LayerImpl::SetImplTransform(const gfx::Transform& transform) { |
| 869 | if (impl_transform_ == transform) |
| 870 | return; |
| 871 | |
| 872 | impl_transform_ = transform; |
| 873 | NoteLayerPropertyChangedForSubtree(); |
[email protected] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 874 | } |
| 875 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 876 | void LayerImpl::SetDoubleSided(bool double_sided) { |
| 877 | if (double_sided_ == double_sided) |
| 878 | return; |
| 879 | |
| 880 | double_sided_ = double_sided; |
| 881 | NoteLayerPropertyChangedForSubtree(); |
| 882 | } |
| 883 | |
| 884 | Region LayerImpl::VisibleContentOpaqueRegion() const { |
| 885 | if (contents_opaque()) |
| 886 | return visible_content_rect(); |
| 887 | return Region(); |
| 888 | } |
| 889 | |
| 890 | void LayerImpl::DidLoseOutputSurface() {} |
| 891 | |
| 892 | void 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 | |
| 901 | void 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 | |
| 908 | inline scoped_ptr<ScrollbarAnimationController> |
| 909 | CreateScrollbarAnimationControllerWithFade(LayerImpl* layer) { |
[email protected] | 0fc818e | 2013-03-18 06:45:20 | [diff] [blame] | 910 | base::TimeDelta fadeout_delay = base::TimeDelta::FromMilliseconds(300); |
| 911 | base::TimeDelta fadeout_length = base::TimeDelta::FromMilliseconds(300); |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 912 | return ScrollbarAnimationControllerLinearFade::create( |
| 913 | layer, fadeout_delay, fadeout_length) |
| 914 | .PassAs<ScrollbarAnimationController>(); |
| 915 | } |
| 916 | |
| 917 | void 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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 927 | } |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 928 | } else { |
| 929 | scrollbar_animation_controller_.reset(); |
| 930 | } |
[email protected] | e45638c | 2013-01-17 22:01:40 | [diff] [blame] | 931 | |
| 932 | } |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 933 | void 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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 938 | } |
| 939 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 940 | void 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] | 94f206c1 | 2012-08-25 00:09:14 | [diff] [blame] | 944 | } |
| 945 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 946 | void LayerImpl::AsValueInto(base::DictionaryValue* dict) const { |
| 947 | dict->SetInteger("id", id()); |
[email protected] | fa816c6 | 2013-03-18 04:24:21 | [diff] [blame] | 948 | dict->Set("bounds", MathUtil::AsValue(bounds()).release()); |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 949 | dict->SetInteger("draws_content", DrawsContent()); |
[email protected] | 8c569022 | 2013-02-15 17:36:43 | [diff] [blame] | 950 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 951 | bool clipped; |
[email protected] | fa816c6 | 2013-03-18 04:24:21 | [diff] [blame] | 952 | gfx::QuadF layer_quad = MathUtil::MapQuad( |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 953 | screen_space_transform(), |
| 954 | gfx::QuadF(gfx::Rect(content_bounds())), |
[email protected] | fa816c6 | 2013-03-18 04:24:21 | [diff] [blame] | 955 | &clipped); |
| 956 | dict->Set("layer_quad", MathUtil::AsValue(layer_quad).release()); |
[email protected] | 8c569022 | 2013-02-15 17:36:43 | [diff] [blame] | 957 | |
| 958 | } |
| 959 | |
[email protected] | 7aba666 | 2013-03-12 10:17:34 | [diff] [blame] | 960 | scoped_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] | 8c569022 | 2013-02-15 17:36:43 | [diff] [blame] | 964 | } |
| 965 | |
[email protected] | bc5e77c | 2012-11-05 20:00:49 | [diff] [blame] | 966 | } // namespace cc |