Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/layer_impl.h" | 5 #include "cc/layer_impl.h" |
| 6 | 6 |
| 7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "cc/animation_registrar.h" | 10 #include "cc/animation_registrar.h" |
| 11 #include "cc/debug_border_draw_quad.h" | 11 #include "cc/debug_border_draw_quad.h" |
| 12 #include "cc/debug_colors.h" | 12 #include "cc/debug_colors.h" |
| 13 #include "cc/layer_tree_debug_state.h" | 13 #include "cc/layer_tree_debug_state.h" |
| 14 #include "cc/layer_tree_impl.h" | 14 #include "cc/layer_tree_impl.h" |
| 15 #include "cc/layer_tree_settings.h" | 15 #include "cc/layer_tree_settings.h" |
| 16 #include "cc/math_util.h" | 16 #include "cc/math_util.h" |
| 17 #include "cc/proxy.h" | 17 #include "cc/proxy.h" |
| 18 #include "cc/quad_sink.h" | 18 #include "cc/quad_sink.h" |
| 19 #include "cc/scrollbar_animation_controller.h" | 19 #include "cc/scrollbar_animation_controller.h" |
| 20 #include "cc/scrollbar_animation_controller_linear_fade.h" | 20 #include "cc/scrollbar_animation_controller_linear_fade.h" |
| 21 #include "cc/scrollbar_layer_impl.h" | 21 #include "cc/scrollbar_layer_impl.h" |
| 22 #include "ui/gfx/point_conversions.h" | 22 #include "ui/gfx/point_conversions.h" |
| 23 #include "ui/gfx/quad_f.h" | 23 #include "ui/gfx/quad_f.h" |
| 24 #include "ui/gfx/rect_conversions.h" | 24 #include "ui/gfx/rect_conversions.h" |
| 25 | 25 |
| 26 namespace cc { | 26 namespace cc { |
| 27 | 27 |
| 28 LayerImpl::LayerImpl(LayerTreeImpl* treeImpl, int id) | 28 LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) |
| 29 : m_parent(0) | 29 : parent_(NULL), |
| 30 , m_maskLayerId(-1) | 30 mask_layer_id_(-1), |
| 31 , m_replicaLayerId(-1) | 31 replica_layer_id_(-1), |
| 32 , m_layerId(id) | 32 layer_id_(id), |
| 33 , m_layerTreeImpl(treeImpl) | 33 layer_tree_impl_(tree_impl), |
| 34 , m_anchorPoint(0.5, 0.5) | 34 anchor_point_(0.5f, 0.5f), |
| 35 , m_anchorPointZ(0) | 35 anchor_point_z_(0.f), |
| 36 , m_scrollable(false) | 36 scrollable_(false), |
| 37 , m_shouldScrollOnMainThread(false) | 37 should_scroll_on_main_thread_(false), |
| 38 , m_haveWheelEventHandlers(false) | 38 have_wheel_event_handlers_(false), |
| 39 , m_backgroundColor(0) | 39 background_color_(0), |
| 40 , m_stackingOrderChanged(false) | 40 stacking_order_changed_(false), |
| 41 , m_doubleSided(true) | 41 double_sided_(true), |
| 42 , m_layerPropertyChanged(false) | 42 layer_property_changed_(false), |
| 43 , m_layerSurfacePropertyChanged(false) | 43 layer_surface_property_changed_(false), |
| 44 , m_masksToBounds(false) | 44 masks_to_bounds_(false), |
| 45 , m_contentsOpaque(false) | 45 contents_opaque_(false), |
| 46 , m_opacity(1.0) | 46 opacity_(1.0), |
| 47 , m_preserves3D(false) | 47 preserves_3d_(false), |
| 48 , m_useParentBackfaceVisibility(false) | 48 use_parent_backface_visibility_(false), |
| 49 , m_drawCheckerboardForMissingTiles(false) | 49 draw_checkerboard_for_missing_tiles_(false), |
| 50 , m_drawsContent(false) | 50 draws_content_(false), |
| 51 , m_forceRenderSurface(false) | 51 force_render_surface_(false), |
| 52 , m_isContainerForFixedPositionLayers(false) | 52 is_container_for_fixed_position_layers_(false), |
| 53 , m_fixedToContainerLayer(false) | 53 fixed_to_container_layer_(false), |
| 54 , m_drawDepth(0) | 54 draw_depth_(0.f), |
| 55 #ifndef NDEBUG | 55 #ifndef NDEBUG |
| 56 , m_betweenWillDrawAndDidDraw(false) | 56 between_will_draw_and_did_draw_(false), |
| 57 #endif | 57 #endif |
| 58 , m_horizontalScrollbarLayer(0) | 58 horizontal_scrollbar_layer_(NULL), |
| 59 , m_verticalScrollbarLayer(0) | 59 vertical_scrollbar_layer_(NULL) { |
| 60 { | 60 DCHECK(layer_id_ > 0); |
| 61 DCHECK(m_layerId > 0); | 61 DCHECK(layer_tree_impl_); |
| 62 DCHECK(m_layerTreeImpl); | 62 layer_tree_impl_->RegisterLayer(this); |
| 63 m_layerTreeImpl->RegisterLayer(this); | 63 AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar(); |
| 64 AnimationRegistrar* registrar = m_layerTreeImpl->animationRegistrar(); | 64 layer_animation_controller_ = |
| 65 m_layerAnimationController = registrar->GetAnimationControllerForId(m_layerI d); | 65 registrar->GetAnimationControllerForId(layer_id_); |
| 66 m_layerAnimationController->AddObserver(this); | 66 layer_animation_controller_->AddObserver(this); |
| 67 } | 67 } |
| 68 | 68 |
| 69 LayerImpl::~LayerImpl() | 69 LayerImpl::~LayerImpl() { |
| 70 { | |
| 71 #ifndef NDEBUG | 70 #ifndef NDEBUG |
| 72 DCHECK(!m_betweenWillDrawAndDidDraw); | 71 DCHECK(!between_will_draw_and_did_draw_); |
| 73 #endif | 72 #endif |
| 74 m_layerTreeImpl->UnregisterLayer(this); | 73 layer_tree_impl_->UnregisterLayer(this); |
| 75 m_layerAnimationController->RemoveObserver(this); | 74 layer_animation_controller_->RemoveObserver(this); |
| 76 } | 75 } |
| 77 | 76 |
| 78 void LayerImpl::addChild(scoped_ptr<LayerImpl> child) | 77 void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) { |
| 79 { | 78 child->set_parent(this); |
| 80 child->setParent(this); | 79 DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl()); |
| 81 DCHECK_EQ(layerTreeImpl(), child->layerTreeImpl()); | 80 children_.push_back(child.Pass()); |
| 82 m_children.push_back(child.Pass()); | 81 layer_tree_impl()->set_needs_update_draw_properties(); |
| 83 layerTreeImpl()->set_needs_update_draw_properties(); | 82 } |
| 84 } | 83 |
| 85 | 84 scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) { |
| 86 LayerImpl* LayerImpl::childAt(size_t index) const | 85 for (ScopedPtrVector<LayerImpl>::iterator it = children_.begin(); |
| 87 { | 86 it != children_.end(); |
| 88 DCHECK_LT(index, m_children.size()); | 87 ++it) { |
| 89 return m_children[index]; | 88 if (*it == child) { |
| 90 } | 89 scoped_ptr<LayerImpl> ret = children_.take(it); |
| 91 | 90 children_.erase(it); |
| 92 scoped_ptr<LayerImpl> LayerImpl::removeChild(LayerImpl* child) | 91 layer_tree_impl()->set_needs_update_draw_properties(); |
| 93 { | 92 return ret.Pass(); |
| 94 for (ScopedPtrVector<LayerImpl>::iterator it = m_children.begin(); it != m_c hildren.end(); ++it) { | |
| 95 if (*it == child) { | |
| 96 scoped_ptr<LayerImpl> ret = m_children.take(it); | |
| 97 m_children.erase(it); | |
| 98 layerTreeImpl()->set_needs_update_draw_properties(); | |
| 99 return ret.Pass(); | |
| 100 } | |
| 101 } | 93 } |
| 102 return scoped_ptr<LayerImpl>(); | 94 } |
| 103 } | 95 return scoped_ptr<LayerImpl>(); |
| 104 | 96 } |
| 105 void LayerImpl::clearChildList() | 97 |
| 106 { | 98 void LayerImpl::ClearChildList() { |
| 107 if (m_children.empty()) | 99 if (children_.empty()) |
| 108 return; | 100 return; |
| 109 | 101 |
| 110 m_children.clear(); | 102 children_.clear(); |
| 111 layerTreeImpl()->set_needs_update_draw_properties(); | 103 layer_tree_impl()->set_needs_update_draw_properties(); |
| 112 } | 104 } |
| 113 | 105 |
| 114 void LayerImpl::createRenderSurface() | 106 void LayerImpl::CreateRenderSurface() { |
| 115 { | 107 DCHECK(!draw_properties_.render_surface); |
| 116 DCHECK(!m_drawProperties.render_surface); | 108 draw_properties_.render_surface = |
| 117 m_drawProperties.render_surface = make_scoped_ptr(new RenderSurfaceImpl(this )); | 109 make_scoped_ptr(new RenderSurfaceImpl(this)); |
| 118 m_drawProperties.render_target = this; | 110 draw_properties_.render_target = this; |
| 119 } | 111 } |
| 120 | 112 |
| 121 scoped_ptr<SharedQuadState> LayerImpl::createSharedQuadState() const | 113 scoped_ptr<SharedQuadState> LayerImpl::CreateSharedQuadState() const { |
| 122 { | |
| 123 scoped_ptr<SharedQuadState> state = SharedQuadState::Create(); | 114 scoped_ptr<SharedQuadState> state = SharedQuadState::Create(); |
| 124 state->SetAll(m_drawProperties.target_space_transform, | 115 state->SetAll(draw_properties_.target_space_transform, |
| 125 m_drawProperties.content_bounds, | 116 draw_properties_.content_bounds, |
| 126 m_drawProperties.visible_content_rect, | 117 draw_properties_.visible_content_rect, |
| 127 m_drawProperties.clip_rect, | 118 draw_properties_.clip_rect, |
| 128 m_drawProperties.is_clipped, | 119 draw_properties_.is_clipped, |
| 129 m_drawProperties.opacity); | 120 draw_properties_.opacity); |
| 130 return state.Pass(); | 121 return state.Pass(); |
| 131 } | 122 } |
| 132 | 123 |
| 133 void LayerImpl::willDraw(ResourceProvider*) | 124 void LayerImpl::WillDraw(ResourceProvider* resource_provider) { |
| 134 { | |
| 135 #ifndef NDEBUG | 125 #ifndef NDEBUG |
| 136 // willDraw/didDraw must be matched. | 126 // willDraw/didDraw must be matched. |
| 137 DCHECK(!m_betweenWillDrawAndDidDraw); | 127 DCHECK(!between_will_draw_and_did_draw_); |
| 138 m_betweenWillDrawAndDidDraw = true; | 128 between_will_draw_and_did_draw_ = true; |
| 139 #endif | 129 #endif |
| 140 } | 130 } |
| 141 | 131 |
| 142 void LayerImpl::didDraw(ResourceProvider*) | 132 void LayerImpl::DidDraw(ResourceProvider* resource_provider) { |
| 143 { | |
| 144 #ifndef NDEBUG | 133 #ifndef NDEBUG |
| 145 DCHECK(m_betweenWillDrawAndDidDraw); | 134 DCHECK(between_will_draw_and_did_draw_); |
| 146 m_betweenWillDrawAndDidDraw = false; | 135 between_will_draw_and_did_draw_ = false; |
| 147 #endif | 136 #endif |
| 148 } | 137 } |
| 149 | 138 |
| 150 bool LayerImpl::showDebugBorders() const | 139 bool LayerImpl::ShowDebugBorders() const { |
| 151 { | 140 return layer_tree_impl()->debug_state().showDebugBorders; |
| 152 return layerTreeImpl()->debug_state().showDebugBorders; | 141 } |
| 153 } | 142 |
| 154 | 143 void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const { |
| 155 void LayerImpl::getDebugBorderProperties(SkColor* color, float* width) const | 144 if (draws_content_) { |
| 156 { | 145 *color = DebugColors::ContentLayerBorderColor(); |
| 157 if (m_drawsContent) { | 146 *width = DebugColors::ContentLayerBorderWidth(layer_tree_impl()); |
| 158 *color = DebugColors::ContentLayerBorderColor(); | 147 return; |
| 159 *width = DebugColors::ContentLayerBorderWidth(layerTreeImpl()); | 148 } |
| 160 return; | 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); | |
| 175 quad_sink->append(debugBorderQuad.PassAs<DrawQuad>(), append_quads_data); | |
| 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? | |
| 161 } | 244 } |
| 162 | 245 |
| 163 if (m_masksToBounds) { | 246 gfx::PointF hit_test_point_in_content_space = |
| 164 *color = DebugColors::MaskingLayerBorderColor(); | 247 MathUtil::projectPoint(inverse_screen_space_transform, |
| 165 *width = DebugColors::MaskingLayerBorderWidth(layerTreeImpl()); | 248 screen_space_point, |
| 166 return; | 249 clipped); |
| 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; | |
| 167 } | 260 } |
| 168 | 261 } |
| 169 *color = DebugColors::ContainerLayerBorderColor(); | 262 |
| 170 *width = DebugColors::ContainerLayerBorderWidth(layerTreeImpl()); | 263 if (type == InputHandlerClient::Wheel && have_wheel_event_handlers()) { |
| 171 } | 264 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed wheelEventHandlers"); |
| 172 | 265 return InputHandlerClient::ScrollOnMainThread; |
| 173 void LayerImpl::appendDebugBorderQuad(QuadSink& quadList, const SharedQuadState* sharedQuadState, AppendQuadsData& appendQuadsData) const | 266 } |
| 174 { | 267 |
| 175 if (!showDebugBorders()) | 268 if (!scrollable()) { |
| 176 return; | 269 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); |
| 177 | 270 return InputHandlerClient::ScrollIgnored; |
| 178 SkColor color; | 271 } |
| 179 float width; | 272 |
| 180 getDebugBorderProperties(&color, &width); | 273 if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) { |
| 181 | 274 TRACE_EVENT0("cc", |
| 182 gfx::Rect contentRect(gfx::Point(), contentBounds()); | 275 "LayerImpl::tryScroll: Ignored. Technically scrollable," |
| 183 scoped_ptr<DebugBorderDrawQuad> debugBorderQuad = DebugBorderDrawQuad::Creat e(); | 276 " but has no affordance in either direction."); |
| 184 debugBorderQuad->SetNew(sharedQuadState, contentRect, color, width); | 277 return InputHandlerClient::ScrollIgnored; |
| 185 quadList.append(debugBorderQuad.PassAs<DrawQuad>(), appendQuadsData); | 278 } |
| 186 } | 279 |
| 187 | 280 return InputHandlerClient::ScrollStarted; |
| 188 bool LayerImpl::hasDelegatedContent() const | 281 } |
| 189 { | 282 |
| 190 return false; | 283 bool LayerImpl::DrawCheckerboardForMissingTiles() const { |
| 191 } | 284 return draw_checkerboard_for_missing_tiles_ && |
| 192 | 285 !layer_tree_impl()->settings().backgroundColorInsteadOfCheckerboard; |
| 193 bool LayerImpl::hasContributingDelegatedRenderPasses() const | 286 } |
| 194 { | 287 |
| 195 return false; | 288 gfx::Rect LayerImpl::LayerRectToContentRect( |
| 196 } | 289 const gfx::RectF& layer_rect) const { |
| 197 | 290 gfx::RectF content_rect = |
| 198 RenderPass::Id LayerImpl::firstContributingRenderPassId() const | 291 gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y()); |
| 199 { | 292 // Intersect with content rect to avoid the extra pixel because for some |
| 200 return RenderPass::Id(0, 0); | 293 // values x and y, ceil((x / y) * y) may be x + 1. |
| 201 } | 294 content_rect.Intersect(gfx::Rect(content_bounds())); |
| 202 | 295 return gfx::ToEnclosingRect(content_rect); |
| 203 RenderPass::Id LayerImpl::nextContributingRenderPassId(RenderPass::Id) const | 296 } |
| 204 { | 297 |
| 205 return RenderPass::Id(0, 0); | 298 skia::RefPtr<SkPicture> LayerImpl::GetPicture() { |
| 206 } | 299 return skia::RefPtr<SkPicture>(); |
| 207 | 300 } |
| 208 ResourceProvider::ResourceId LayerImpl::contentsResourceId() const | 301 |
| 209 { | 302 bool LayerImpl::CanClipSelf() const { |
| 210 NOTREACHED(); | 303 return false; |
| 211 return 0; | 304 } |
| 212 } | 305 |
| 213 | 306 bool LayerImpl::AreVisibleResourcesReady() const { |
| 214 void LayerImpl::setSentScrollDelta(const gfx::Vector2d& sentScrollDelta) | 307 return true; |
| 215 { | 308 } |
| 216 // Pending tree never has sent scroll deltas | 309 |
| 217 DCHECK(layerTreeImpl()->IsActiveTree()); | 310 scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { |
| 218 | 311 return LayerImpl::Create(tree_impl, layer_id_); |
| 219 if (m_sentScrollDelta == sentScrollDelta) | 312 } |
| 220 return; | 313 |
| 221 | 314 void LayerImpl::PushPropertiesTo(LayerImpl* layer) { |
| 222 m_sentScrollDelta = sentScrollDelta; | 315 layer->SetAnchorPoint(anchor_point_); |
| 223 } | 316 layer->SetAnchorPointZ(anchor_point_z_); |
| 224 | 317 layer->SetBackgroundColor(background_color_); |
| 225 gfx::Vector2dF LayerImpl::scrollBy(const gfx::Vector2dF& scroll) | 318 layer->SetBounds(bounds_); |
| 226 { | 319 layer->SetContentBounds(content_bounds()); |
| 227 gfx::Vector2dF minDelta = -m_scrollOffset; | 320 layer->SetContentsScale(contents_scale_x(), contents_scale_y()); |
| 228 gfx::Vector2dF maxDelta = m_maxScrollOffset - m_scrollOffset; | 321 layer->SetDebugName(debug_name_); |
| 229 // Clamp newDelta so that position + delta stays within scroll bounds. | 322 layer->SetDoubleSided(double_sided_); |
| 230 gfx::Vector2dF newDelta = (m_scrollDelta + scroll); | 323 layer->SetDrawCheckerboardForMissingTiles( |
| 231 newDelta.ClampToMin(minDelta); | 324 draw_checkerboard_for_missing_tiles_); |
| 232 newDelta.ClampToMax(maxDelta); | 325 layer->SetForceRenderSurface(force_render_surface_); |
| 233 gfx::Vector2dF unscrolled = m_scrollDelta + scroll - newDelta; | 326 layer->SetDrawsContent(DrawsContent()); |
| 234 | 327 layer->SetFilters(filters()); |
| 235 setScrollDelta(newDelta); | 328 layer->SetFilter(filter()); |
| 236 return unscrolled; | 329 layer->SetBackgroundFilters(background_filters()); |
| 237 } | 330 layer->SetMasksToBounds(masks_to_bounds_); |
| 238 | 331 layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_); |
| 239 InputHandlerClient::ScrollStatus LayerImpl::tryScroll(const gfx::PointF& screenS pacePoint, InputHandlerClient::ScrollInputType type) const | 332 layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_); |
| 240 { | 333 layer->SetNonFastScrollableRegion(non_fast_scrollable_region_); |
| 241 if (shouldScrollOnMainThread()) { | 334 layer->SetTouchEventHandlerRegion(touch_event_handler_region_); |
| 242 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed shouldScrollOnMainThrea d"); | 335 layer->SetContentsOpaque(contents_opaque_); |
| 243 return InputHandlerClient::ScrollOnMainThread; | 336 if (!OpacityIsAnimating()) |
| 337 layer->SetOpacity(opacity_); | |
| 338 layer->SetPosition(position_); | |
| 339 layer->SetIsContainerForFixedPositionLayers( | |
| 340 is_container_for_fixed_position_layers_); | |
| 341 layer->SetFixedToContainerLayer(fixed_to_container_layer_); | |
| 342 layer->SetPreserves3d(preserves_3d()); | |
| 343 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); | |
| 344 layer->SetSublayerTransform(sublayer_transform_); | |
| 345 if (!TransformIsAnimating()) | |
| 346 layer->SetTransform(transform_); | |
| 347 | |
| 348 layer->SetScrollable(scrollable_); | |
| 349 layer->SetScrollOffset(scroll_offset_); | |
| 350 layer->SetMaxScrollOffset(max_scroll_offset_); | |
| 351 | |
| 352 // If the main thread commits multiple times before the impl thread actually | |
| 353 // draws, then damage tracking will become incorrect if we simply clobber the | |
| 354 // updateRect here. The LayerImpl's updateRect needs to accumulate (i.e. | |
| 355 // union) any update changes that have occurred on the main thread. | |
| 356 update_rect_.Union(layer->update_rect()); | |
| 357 layer->set_update_rect(update_rect_); | |
| 358 | |
| 359 layer->SetScrollDelta(layer->scroll_delta() - layer->sent_scroll_delta()); | |
| 360 layer->SetSentScrollDelta(gfx::Vector2d()); | |
| 361 | |
| 362 layer->SetStackingOrderChanged(stacking_order_changed_); | |
| 363 | |
| 364 layer_animation_controller_->PushAnimationUpdatesTo( | |
| 365 layer->layer_animation_controller()); | |
| 366 | |
| 367 // Reset any state that should be cleared for the next update. | |
| 368 stacking_order_changed_ = false; | |
| 369 update_rect_ = gfx::RectF(); | |
| 370 } | |
| 371 | |
| 372 std::string LayerImpl::IndentString(int indent) { | |
| 373 std::string str; | |
| 374 for (int i = 0; i != indent; ++i) | |
| 375 str.append(" "); | |
| 376 return str; | |
| 377 } | |
| 378 | |
| 379 void LayerImpl::DumpLayerProperties(std::string* str, int indent) const { | |
| 380 std::string indent_str = IndentString(indent); | |
| 381 str->append(indent_str); | |
| 382 base::StringAppendF(str, "layer ID: %d\n", layer_id_); | |
| 383 | |
| 384 str->append(indent_str); | |
| 385 base::StringAppendF( | |
| 386 str, "bounds: %d, %d\n", bounds().width(), bounds().height()); | |
| 387 | |
| 388 if (draw_properties_.render_target) { | |
| 389 str->append(indent_str); | |
| 390 base::StringAppendF( | |
| 391 str, "renderTarget: %d\n", draw_properties_.render_target->layer_id_); | |
| 392 } | |
| 393 | |
| 394 str->append(indent_str); | |
| 395 base::StringAppendF(str, "position: %f, %f\n", position_.x(), position_.y()); | |
| 396 | |
| 397 str->append(indent_str); | |
| 398 base::StringAppendF(str, "contentsOpaque: %d\n", contents_opaque_); | |
| 399 | |
| 400 str->append(indent_str); | |
| 401 const gfx::Transform& transform = draw_properties_.target_space_transform; | |
| 402 base::StringAppendF(str, | |
| 403 "drawTransform: %f, %f, %f, %f // %f, %f, %f, %f" | |
| 404 " // %f, %f, %f, %f // %f, %f, %f, %f\n", | |
| 405 transform.matrix().getDouble(0, 0), | |
| 406 transform.matrix().getDouble(0, 1), | |
| 407 transform.matrix().getDouble(0, 2), | |
| 408 transform.matrix().getDouble(0, 3), | |
| 409 transform.matrix().getDouble(1, 0), | |
| 410 transform.matrix().getDouble(1, 1), | |
| 411 transform.matrix().getDouble(1, 2), | |
| 412 transform.matrix().getDouble(1, 3), | |
| 413 transform.matrix().getDouble(2, 0), | |
| 414 transform.matrix().getDouble(2, 1), | |
| 415 transform.matrix().getDouble(2, 2), | |
| 416 transform.matrix().getDouble(2, 3), | |
| 417 transform.matrix().getDouble(3, 0), | |
| 418 transform.matrix().getDouble(3, 1), | |
| 419 transform.matrix().getDouble(3, 2), | |
| 420 transform.matrix().getDouble(3, 3)); | |
| 421 | |
| 422 str->append(indent_str); | |
| 423 base::StringAppendF( | |
| 424 str, "draws_content: %s\n", draws_content_ ? "yes" : "no"); | |
| 425 } | |
| 426 | |
| 427 std::string LayerImpl::LayerTreeAsText() const { | |
| 428 std::string str; | |
| 429 DumpLayer(&str, 0); | |
| 430 return str; | |
| 431 } | |
| 432 | |
| 433 void LayerImpl::DumpLayer(std::string* str, int indent) const { | |
| 434 str->append(IndentString(indent)); | |
| 435 base::StringAppendF(str, "%s(%s)\n", LayerTypeAsString(), debug_name_.data()); | |
| 436 DumpLayerProperties(str, indent+2); | |
| 437 if (replica_layer_) { | |
| 438 str->append(IndentString(indent+2)); | |
| 439 str->append("Replica:\n"); | |
| 440 replica_layer_->DumpLayer(str, indent+3); | |
| 441 } | |
| 442 if (mask_layer_) { | |
| 443 str->append(IndentString(indent+2)); | |
| 444 str->append("Mask:\n"); | |
| 445 mask_layer_->DumpLayer(str, indent+3); | |
| 446 } | |
| 447 for (size_t i = 0; i < children_.size(); ++i) | |
| 448 children_[i]->DumpLayer(str, indent+1); | |
| 449 } | |
| 450 | |
| 451 base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { | |
| 452 base::ListValue* list; | |
| 453 base::DictionaryValue* result = new base::DictionaryValue; | |
| 454 result->SetString("LayerType", LayerTypeAsString()); | |
| 455 | |
| 456 list = new base::ListValue; | |
| 457 list->AppendInteger(bounds().width()); | |
| 458 list->AppendInteger(bounds().height()); | |
| 459 result->Set("Bounds", list); | |
| 460 | |
| 461 list = new base::ListValue; | |
| 462 list->AppendDouble(position_.x()); | |
| 463 list->AppendDouble(position_.y()); | |
| 464 result->Set("Position", list); | |
| 465 | |
| 466 const gfx::Transform& gfx_transform = draw_properties_.target_space_transform; | |
| 467 double transform[16]; | |
| 468 gfx_transform.matrix().asColMajord(transform); | |
| 469 list = new base::ListValue; | |
| 470 for (int i = 0; i < 16; ++i) | |
| 471 list->AppendDouble(transform[i]); | |
| 472 result->Set("DrawTransform", list); | |
| 473 | |
| 474 result->SetBoolean("DrawsContent", draws_content_); | |
| 475 result->SetDouble("Opacity", opacity()); | |
| 476 | |
| 477 list = new base::ListValue; | |
| 478 for (size_t i = 0; i < children_.size(); ++i) | |
| 479 list->Append(children_[i]->LayerTreeAsJson()); | |
| 480 result->Set("Children", list); | |
| 481 | |
| 482 return result; | |
| 483 } | |
| 484 | |
| 485 void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) { | |
| 486 if (stacking_order_changed) { | |
| 487 stacking_order_changed_ = true; | |
| 488 NoteLayerPropertyChangedForSubtree(); | |
| 489 } | |
| 490 } | |
| 491 | |
| 492 bool LayerImpl::LayerSurfacePropertyChanged() const { | |
| 493 if (layer_surface_property_changed_) | |
| 494 return true; | |
| 495 | |
| 496 // If this layer's surface property hasn't changed, we want to see if | |
| 497 // some layer above us has changed this property. This is done for the | |
| 498 // case when such parent layer does not draw content, and therefore will | |
| 499 // not be traversed by the damage tracker. We need to make sure that | |
| 500 // property change on such layer will be caught by its descendants. | |
| 501 LayerImpl* current = this->parent_; | |
| 502 while (current && !current->draw_properties_.render_surface) { | |
| 503 if (current->layer_surface_property_changed_) | |
| 504 return true; | |
| 505 current = current->parent_; | |
| 506 } | |
| 507 | |
| 508 return false; | |
| 509 } | |
| 510 | |
| 511 void LayerImpl::NoteLayerSurfacePropertyChanged() { | |
| 512 layer_surface_property_changed_ = true; | |
| 513 layer_tree_impl()->set_needs_update_draw_properties(); | |
| 514 } | |
| 515 | |
| 516 void LayerImpl::NoteLayerPropertyChanged() { | |
| 517 layer_property_changed_ = true; | |
| 518 layer_tree_impl()->set_needs_update_draw_properties(); | |
| 519 } | |
| 520 | |
| 521 void LayerImpl::NoteLayerPropertyChangedForSubtree() { | |
| 522 NoteLayerPropertyChanged(); | |
| 523 NoteLayerPropertyChangedForDescendants(); | |
| 524 } | |
| 525 | |
| 526 void LayerImpl::NoteLayerPropertyChangedForDescendants() { | |
| 527 layer_tree_impl()->set_needs_update_draw_properties(); | |
| 528 for (size_t i = 0; i < children_.size(); ++i) | |
| 529 children_[i]->NoteLayerPropertyChangedForSubtree(); | |
| 530 } | |
| 531 | |
| 532 const char* LayerImpl::LayerTypeAsString() const { | |
| 533 return "Layer"; | |
| 534 } | |
| 535 | |
| 536 void LayerImpl::ResetAllChangeTrackingForSubtree() { | |
| 537 layer_property_changed_ = false; | |
| 538 layer_surface_property_changed_ = false; | |
| 539 | |
| 540 update_rect_ = gfx::RectF(); | |
| 541 | |
| 542 if (draw_properties_.render_surface) | |
| 543 draw_properties_.render_surface->ResetPropertyChangedFlag(); | |
| 544 | |
| 545 if (mask_layer_) | |
| 546 mask_layer_->ResetAllChangeTrackingForSubtree(); | |
| 547 | |
| 548 if (replica_layer_) { | |
| 549 // This also resets the replica mask, if it exists. | |
| 550 replica_layer_->ResetAllChangeTrackingForSubtree(); | |
| 551 } | |
| 552 | |
| 553 for (size_t i = 0; i < children_.size(); ++i) | |
| 554 children_[i]->ResetAllChangeTrackingForSubtree(); | |
| 555 } | |
| 556 | |
| 557 bool LayerImpl::LayerIsAlwaysDamaged() const { | |
| 558 return false; | |
| 559 } | |
| 560 | |
| 561 void LayerImpl::OnOpacityAnimated(float opacity) { | |
| 562 SetOpacity(opacity); | |
| 563 } | |
| 564 | |
| 565 void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { | |
| 566 SetTransform(transform); | |
| 567 } | |
| 568 | |
| 569 bool LayerImpl::IsActive() const { | |
| 570 return layer_tree_impl_->IsActiveTree(); | |
| 571 } | |
| 572 | |
| 573 void LayerImpl::SetBounds(gfx::Size bounds) { | |
| 574 if (bounds_ == bounds) | |
| 575 return; | |
| 576 | |
| 577 bounds_ = bounds; | |
| 578 | |
| 579 if (masks_to_bounds()) | |
| 580 NoteLayerPropertyChangedForSubtree(); | |
| 581 else | |
| 582 NoteLayerPropertyChanged(); | |
| 583 } | |
| 584 | |
| 585 void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { | |
| 586 int new_layer_id = mask_layer ? mask_layer->id() : -1; | |
| 587 | |
| 588 if (mask_layer) { | |
| 589 DCHECK_EQ(layer_tree_impl(), mask_layer->layer_tree_impl()); | |
| 590 DCHECK_NE(new_layer_id, mask_layer_id_); | |
| 591 } else if (new_layer_id == mask_layer_id_) | |
| 592 return; | |
|
enne (OOO)
2013/03/12 02:40:19
Also needs braces to match if clause.
danakj
2013/03/12 02:47:16
Done.
| |
| 593 | |
| 594 mask_layer_ = mask_layer.Pass(); | |
| 595 mask_layer_id_ = new_layer_id; | |
| 596 if (mask_layer_) | |
| 597 mask_layer_->set_parent(this); | |
| 598 NoteLayerPropertyChangedForSubtree(); | |
| 599 } | |
| 600 | |
| 601 scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() { | |
| 602 mask_layer_id_ = -1; | |
| 603 return mask_layer_.Pass(); | |
| 604 } | |
| 605 | |
| 606 void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { | |
| 607 int new_layer_id = replica_layer ? replica_layer->id() : -1; | |
| 608 | |
| 609 if (replica_layer) { | |
| 610 DCHECK_EQ(layer_tree_impl(), replica_layer->layer_tree_impl()); | |
| 611 DCHECK_NE(new_layer_id, replica_layer_id_); | |
| 612 } else if (new_layer_id == replica_layer_id_) | |
| 613 return; | |
|
enne (OOO)
2013/03/12 02:40:19
Braces.
danakj
2013/03/12 02:47:16
Done.
| |
| 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 | |
| 718 void LayerImpl::SetPosition(gfx::PointF position) { | |
| 719 if (position_ == position) | |
| 720 return; | |
| 721 | |
| 722 position_ = position; | |
| 723 NoteLayerPropertyChangedForSubtree(); | |
| 724 } | |
| 725 | |
| 726 void LayerImpl::SetPreserves3d(bool preserves3_d) { | |
| 727 if (preserves_3d_ == preserves3_d) | |
| 728 return; | |
| 729 | |
| 730 preserves_3d_ = preserves3_d; | |
| 731 NoteLayerPropertyChangedForSubtree(); | |
| 732 } | |
| 733 | |
| 734 void LayerImpl::SetSublayerTransform(const gfx::Transform& sublayer_transform) { | |
| 735 if (sublayer_transform_ == sublayer_transform) | |
| 736 return; | |
| 737 | |
| 738 sublayer_transform_ = sublayer_transform; | |
| 739 // Sublayer transform does not affect the current layer; it affects only its | |
| 740 // children. | |
| 741 NoteLayerPropertyChangedForDescendants(); | |
| 742 } | |
| 743 | |
| 744 void LayerImpl::SetTransform(const gfx::Transform& transform) { | |
| 745 if (transform_ == transform) | |
| 746 return; | |
| 747 | |
| 748 transform_ = transform; | |
| 749 NoteLayerSurfacePropertyChanged(); | |
| 750 } | |
| 751 | |
| 752 bool LayerImpl::TransformIsAnimating() const { | |
| 753 return layer_animation_controller_->IsAnimatingProperty(Animation::Transform); | |
| 754 } | |
| 755 | |
| 756 void LayerImpl::SetContentBounds(gfx::Size content_bounds) { | |
| 757 if (this->content_bounds() == content_bounds) | |
| 758 return; | |
| 759 | |
| 760 draw_properties_.content_bounds = content_bounds; | |
| 761 NoteLayerPropertyChanged(); | |
| 762 } | |
| 763 | |
| 764 void LayerImpl::SetContentsScale(float contents_scale_x, | |
| 765 float contents_scale_y) { | |
| 766 if (this->contents_scale_x() == contents_scale_x && | |
| 767 this->contents_scale_y() == contents_scale_y) | |
| 768 return; | |
| 769 | |
| 770 draw_properties_.contents_scale_x = contents_scale_x; | |
| 771 draw_properties_.contents_scale_y = contents_scale_y; | |
| 772 NoteLayerPropertyChanged(); | |
| 773 } | |
| 774 | |
| 775 void LayerImpl::CalculateContentsScale( | |
| 776 float ideal_contents_scale, | |
| 777 bool animating_transform_to_screen, | |
| 778 float* contents_scale_x, | |
| 779 float* contents_scale_y, | |
| 780 gfx::Size* content_bounds) { | |
| 781 // Base LayerImpl has all of its content scales and content bounds pushed | |
| 782 // from its Layer during commit and just reuses those values as-is. | |
| 783 *contents_scale_x = this->contents_scale_x(); | |
| 784 *contents_scale_y = this->contents_scale_y(); | |
| 785 *content_bounds = this->content_bounds(); | |
| 786 } | |
| 787 | |
| 788 void LayerImpl::UpdateScrollbarPositions() { | |
| 789 gfx::Vector2dF current_offset = scroll_offset_ + scroll_delta_; | |
| 790 | |
| 791 if (horizontal_scrollbar_layer_) { | |
| 792 horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x()); | |
| 793 horizontal_scrollbar_layer_->SetTotalSize(bounds_.width()); | |
| 794 horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x()); | |
| 795 } | |
| 796 if (vertical_scrollbar_layer_) { | |
| 797 vertical_scrollbar_layer_->SetCurrentPos(current_offset.y()); | |
| 798 vertical_scrollbar_layer_->SetTotalSize(bounds_.height()); | |
| 799 vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y()); | |
| 800 } | |
| 801 | |
| 802 if (current_offset == last_scroll_offset_) | |
| 803 return; | |
| 804 last_scroll_offset_ = current_offset; | |
| 805 | |
| 806 if (scrollbar_animation_controller_) { | |
| 807 scrollbar_animation_controller_->didUpdateScrollOffset( | |
| 808 base::TimeTicks::Now()); | |
| 809 } | |
| 810 | |
| 811 // Get the current_offset_.y() value for a sanity-check on scrolling | |
| 812 // benchmark metrics. Specifically, we want to make sure | |
| 813 // BasicMouseWheelSmoothScrollGesture has proper scroll curves. | |
| 814 if (layer_tree_impl()->IsActiveTree()) { | |
| 815 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y()); | |
| 816 } | |
| 817 } | |
| 818 | |
| 819 void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { | |
| 820 if (scroll_offset_ == scroll_offset) | |
| 821 return; | |
| 822 | |
| 823 scroll_offset_ = scroll_offset; | |
| 824 NoteLayerPropertyChangedForSubtree(); | |
| 825 UpdateScrollbarPositions(); | |
| 826 } | |
| 827 | |
| 828 void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) { | |
| 829 if (scroll_delta_ == scroll_delta) | |
| 830 return; | |
| 831 | |
| 832 if (layer_tree_impl()->IsActiveTree()) { | |
| 833 LayerImpl* pending_twin = layer_tree_impl()->FindPendingTreeLayerById(id()); | |
| 834 if (pending_twin) { | |
| 835 // The pending twin can't mirror the scroll delta of the active | |
| 836 // layer. Although the delta - sent scroll delta difference is | |
| 837 // identical for both twins, the sent scroll delta for the pending | |
| 838 // layer is zero, as anything that has been sent has been baked | |
| 839 // into the layer's position/scroll offset as a part of commit. | |
| 840 DCHECK(pending_twin->sent_scroll_delta().IsZero()); | |
| 841 pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta()); | |
| 244 } | 842 } |
| 245 | 843 } |
| 246 if (!screenSpaceTransform().IsInvertible()) { | 844 |
| 247 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored nonInvertibleTransform "); | 845 scroll_delta_ = scroll_delta; |
| 248 return InputHandlerClient::ScrollIgnored; | 846 NoteLayerPropertyChangedForSubtree(); |
| 847 | |
| 848 UpdateScrollbarPositions(); | |
| 849 } | |
| 850 | |
| 851 void LayerImpl::SetImplTransform(const gfx::Transform& transform) { | |
| 852 if (impl_transform_ == transform) | |
| 853 return; | |
| 854 | |
| 855 impl_transform_ = transform; | |
| 856 NoteLayerPropertyChangedForSubtree(); | |
| 857 } | |
| 858 | |
| 859 void LayerImpl::SetDoubleSided(bool double_sided) { | |
| 860 if (double_sided_ == double_sided) | |
| 861 return; | |
| 862 | |
| 863 double_sided_ = double_sided; | |
| 864 NoteLayerPropertyChangedForSubtree(); | |
| 865 } | |
| 866 | |
| 867 Region LayerImpl::VisibleContentOpaqueRegion() const { | |
| 868 if (contents_opaque()) | |
| 869 return visible_content_rect(); | |
| 870 return Region(); | |
| 871 } | |
| 872 | |
| 873 void LayerImpl::DidLoseOutputSurface() {} | |
| 874 | |
| 875 void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { | |
| 876 if (max_scroll_offset_ == max_scroll_offset) | |
| 877 return; | |
| 878 max_scroll_offset_ = max_scroll_offset; | |
| 879 | |
| 880 layer_tree_impl()->set_needs_update_draw_properties(); | |
| 881 UpdateScrollbarPositions(); | |
| 882 } | |
| 883 | |
| 884 void LayerImpl::SetScrollbarOpacity(float opacity) { | |
| 885 if (horizontal_scrollbar_layer_) | |
| 886 horizontal_scrollbar_layer_->SetOpacity(opacity); | |
| 887 if (vertical_scrollbar_layer_) | |
| 888 vertical_scrollbar_layer_->SetOpacity(opacity); | |
| 889 } | |
| 890 | |
| 891 inline scoped_ptr<ScrollbarAnimationController> | |
| 892 CreateScrollbarAnimationControllerWithFade(LayerImpl* layer) { | |
| 893 double fadeout_delay = 0.3; | |
| 894 double fadeout_length = 0.3; | |
| 895 return ScrollbarAnimationControllerLinearFade::create( | |
| 896 layer, fadeout_delay, fadeout_length) | |
| 897 .PassAs<ScrollbarAnimationController>(); | |
| 898 } | |
| 899 | |
| 900 void LayerImpl::DidBecomeActive() { | |
| 901 if (!layer_tree_impl_->settings().useLinearFadeScrollbarAnimator) | |
| 902 return; | |
| 903 | |
| 904 bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ || | |
| 905 vertical_scrollbar_layer_; | |
| 906 if (need_scrollbar_animation_controller) { | |
| 907 if (!scrollbar_animation_controller_) { | |
| 908 scrollbar_animation_controller_ = | |
| 909 CreateScrollbarAnimationControllerWithFade(this); | |
| 249 } | 910 } |
| 250 | 911 } else { |
| 251 if (!nonFastScrollableRegion().IsEmpty()) { | 912 scrollbar_animation_controller_.reset(); |
| 252 bool clipped = false; | 913 } |
| 253 gfx::Transform inverseScreenSpaceTransform(gfx::Transform::kSkipInitiali zation); | 914 |
| 254 if (!screenSpaceTransform().GetInverse(&inverseScreenSpaceTransform)) { | 915 } |
| 255 // TODO(shawnsingh): We shouldn't be applying a projection if screen space | 916 void LayerImpl::SetHorizontalScrollbarLayer( |
| 256 // transform is uninvertible here. Perhaps we should be returning | 917 ScrollbarLayerImpl* scrollbar_layer) { |
| 257 // ScrollOnMainThread in this case? | 918 horizontal_scrollbar_layer_ = scrollbar_layer; |
| 258 } | 919 if (horizontal_scrollbar_layer_) |
| 259 | 920 horizontal_scrollbar_layer_->set_scroll_layer_id(id()); |
| 260 gfx::PointF hitTestPointInContentSpace = MathUtil::projectPoint(inverseS creenSpaceTransform, screenSpacePoint, clipped); | 921 } |
| 261 gfx::PointF hitTestPointInLayerSpace = gfx::ScalePoint(hitTestPointInCon tentSpace, 1 / contentsScaleX(), 1 / contentsScaleY()); | 922 |
| 262 if (!clipped && nonFastScrollableRegion().Contains(gfx::ToRoundedPoint(h itTestPointInLayerSpace))) { | 923 void LayerImpl::SetVerticalScrollbarLayer(ScrollbarLayerImpl* scrollbar_layer) { |
| 263 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed nonFastScrollableRe gion"); | 924 vertical_scrollbar_layer_ = scrollbar_layer; |
| 264 return InputHandlerClient::ScrollOnMainThread; | 925 if (vertical_scrollbar_layer_) |
| 265 } | 926 vertical_scrollbar_layer_->set_scroll_layer_id(id()); |
| 266 } | 927 } |
| 267 | 928 |
| 268 if (type == InputHandlerClient::Wheel && haveWheelEventHandlers()) { | 929 void LayerImpl::AsValueInto(base::DictionaryValue* dict) const { |
| 269 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed wheelEventHandlers"); | 930 dict->SetInteger("id", id()); |
| 270 return InputHandlerClient::ScrollOnMainThread; | 931 dict->Set("bounds", MathUtil::asValue(bounds()).release()); |
| 271 } | 932 dict->SetInteger("draws_content", DrawsContent()); |
| 272 | 933 |
| 273 if (!scrollable()) { | 934 bool clipped; |
| 274 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); | 935 gfx::QuadF layer_quad = MathUtil::mapQuad( |
| 275 return InputHandlerClient::ScrollIgnored; | 936 screen_space_transform(), |
| 276 } | 937 gfx::QuadF(gfx::Rect(content_bounds())), |
| 277 | 938 clipped); |
| 278 if (m_maxScrollOffset.x() <= 0 && m_maxScrollOffset.y() <= 0) { | 939 dict->Set("layer_quad", MathUtil::asValue(layer_quad).release()); |
| 279 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored. Technically scrollabl e, but has no affordance in either direction."); | 940 |
| 280 return InputHandlerClient::ScrollIgnored; | 941 } |
| 281 } | 942 |
| 282 | 943 scoped_ptr<base::Value> LayerImpl::AsValue() const { |
| 283 return InputHandlerClient::ScrollStarted; | 944 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| 284 } | 945 AsValueInto(state.get()); |
| 285 | 946 return state.PassAs<base::Value>(); |
| 286 bool LayerImpl::drawCheckerboardForMissingTiles() const | |
| 287 { | |
| 288 return m_drawCheckerboardForMissingTiles && !layerTreeImpl()->settings().bac kgroundColorInsteadOfCheckerboard; | |
| 289 } | |
| 290 | |
| 291 gfx::Rect LayerImpl::layerRectToContentRect(const gfx::RectF& layerRect) const | |
| 292 { | |
| 293 gfx::RectF contentRect = gfx::ScaleRect(layerRect, contentsScaleX(), content sScaleY()); | |
| 294 // Intersect with content rect to avoid the extra pixel because for some | |
| 295 // values x and y, ceil((x / y) * y) may be x + 1. | |
| 296 contentRect.Intersect(gfx::Rect(gfx::Point(), contentBounds())); | |
| 297 return gfx::ToEnclosingRect(contentRect); | |
| 298 } | |
| 299 | |
| 300 skia::RefPtr<SkPicture> LayerImpl::getPicture() | |
| 301 { | |
| 302 return skia::RefPtr<SkPicture>(); | |
| 303 } | |
| 304 | |
| 305 bool LayerImpl::canClipSelf() const | |
| 306 { | |
| 307 return false; | |
| 308 } | |
| 309 | |
| 310 bool LayerImpl::areVisibleResourcesReady() const | |
| 311 { | |
| 312 return true; | |
| 313 } | |
| 314 | |
| 315 scoped_ptr<LayerImpl> LayerImpl::createLayerImpl(LayerTreeImpl* treeImpl) | |
| 316 { | |
| 317 return LayerImpl::create(treeImpl, m_layerId); | |
| 318 } | |
| 319 | |
| 320 void LayerImpl::pushPropertiesTo(LayerImpl* layer) | |
| 321 { | |
| 322 layer->setAnchorPoint(m_anchorPoint); | |
| 323 layer->setAnchorPointZ(m_anchorPointZ); | |
| 324 layer->setBackgroundColor(m_backgroundColor); | |
| 325 layer->setBounds(m_bounds); | |
| 326 layer->setContentBounds(contentBounds()); | |
| 327 layer->setContentsScale(contentsScaleX(), contentsScaleY()); | |
| 328 layer->setDebugName(m_debugName); | |
| 329 layer->setDoubleSided(m_doubleSided); | |
| 330 layer->setDrawCheckerboardForMissingTiles(m_drawCheckerboardForMissingTiles) ; | |
| 331 layer->setForceRenderSurface(m_forceRenderSurface); | |
| 332 layer->setDrawsContent(drawsContent()); | |
| 333 layer->setFilters(filters()); | |
| 334 layer->setFilter(filter()); | |
| 335 layer->setBackgroundFilters(backgroundFilters()); | |
| 336 layer->setMasksToBounds(m_masksToBounds); | |
| 337 layer->setShouldScrollOnMainThread(m_shouldScrollOnMainThread); | |
| 338 layer->setHaveWheelEventHandlers(m_haveWheelEventHandlers); | |
| 339 layer->setNonFastScrollableRegion(m_nonFastScrollableRegion); | |
| 340 layer->setTouchEventHandlerRegion(m_touchEventHandlerRegion); | |
| 341 layer->setContentsOpaque(m_contentsOpaque); | |
| 342 if (!opacityIsAnimating()) | |
| 343 layer->setOpacity(m_opacity); | |
| 344 layer->setPosition(m_position); | |
| 345 layer->setIsContainerForFixedPositionLayers(m_isContainerForFixedPositionLay ers); | |
| 346 layer->setFixedToContainerLayer(m_fixedToContainerLayer); | |
| 347 layer->setPreserves3D(preserves3D()); | |
| 348 layer->setUseParentBackfaceVisibility(m_useParentBackfaceVisibility); | |
| 349 layer->setSublayerTransform(m_sublayerTransform); | |
| 350 if (!transformIsAnimating()) | |
| 351 layer->setTransform(m_transform); | |
| 352 | |
| 353 layer->setScrollable(m_scrollable); | |
| 354 layer->setScrollOffset(m_scrollOffset); | |
| 355 layer->setMaxScrollOffset(m_maxScrollOffset); | |
| 356 | |
| 357 // If the main thread commits multiple times before the impl thread actually draws, then damage tracking | |
| 358 // will become incorrect if we simply clobber the updateRect here. The Layer Impl's updateRect needs to | |
| 359 // accumulate (i.e. union) any update changes that have occurred on the main thread. | |
| 360 m_updateRect.Union(layer->updateRect()); | |
| 361 layer->setUpdateRect(m_updateRect); | |
| 362 | |
| 363 layer->setScrollDelta(layer->scrollDelta() - layer->sentScrollDelta()); | |
| 364 layer->setSentScrollDelta(gfx::Vector2d()); | |
| 365 | |
| 366 layer->setStackingOrderChanged(m_stackingOrderChanged); | |
| 367 | |
| 368 m_layerAnimationController->PushAnimationUpdatesTo(layer->layerAnimationCont roller()); | |
| 369 | |
| 370 // Reset any state that should be cleared for the next update. | |
| 371 m_stackingOrderChanged = false; | |
| 372 m_updateRect = gfx::RectF(); | |
| 373 } | |
| 374 | |
| 375 std::string LayerImpl::indentString(int indent) | |
| 376 { | |
| 377 std::string str; | |
| 378 for (int i = 0; i != indent; ++i) | |
| 379 str.append(" "); | |
| 380 return str; | |
| 381 } | |
| 382 | |
| 383 void LayerImpl::dumpLayerProperties(std::string* str, int indent) const | |
| 384 { | |
| 385 std::string indentStr = indentString(indent); | |
| 386 str->append(indentStr); | |
| 387 base::StringAppendF(str, "layer ID: %d\n", m_layerId); | |
| 388 | |
| 389 str->append(indentStr); | |
| 390 base::StringAppendF(str, "bounds: %d, %d\n", bounds().width(), bounds().heig ht()); | |
| 391 | |
| 392 if (m_drawProperties.render_target) { | |
| 393 str->append(indentStr); | |
| 394 base::StringAppendF(str, "renderTarget: %d\n", m_drawProperties.render_t arget->m_layerId); | |
| 395 } | |
| 396 | |
| 397 str->append(indentStr); | |
| 398 base::StringAppendF(str, "position: %f, %f\n", m_position.x(), m_position.y( )); | |
| 399 | |
| 400 str->append(indentStr); | |
| 401 base::StringAppendF(str, "contentsOpaque: %d\n", m_contentsOpaque); | |
| 402 | |
| 403 str->append(indentStr); | |
| 404 const gfx::Transform& transform = m_drawProperties.target_space_transform; | |
| 405 base::StringAppendF(str, "drawTransform: %f, %f, %f, %f // %f, %f, %f, %f // %f, %f, %f, %f // %f, %f, %f, %f\n", | |
| 406 transform.matrix().getDouble(0, 0), transform.matrix().getDouble(0, 1), transform.matrix().getDouble(0, 2), transform.matrix().getDouble(0, 3), | |
| 407 transform.matrix().getDouble(1, 0), transform.matrix().getDouble(1, 1), transform.matrix().getDouble(1, 2), transform.matrix().getDouble(1, 3), | |
| 408 transform.matrix().getDouble(2, 0), transform.matrix().getDouble(2, 1), transform.matrix().getDouble(2, 2), transform.matrix().getDouble(2, 3), | |
| 409 transform.matrix().getDouble(3, 0), transform.matrix().getDouble(3, 1), transform.matrix().getDouble(3, 2), transform.matrix().getDouble(3, 3)); | |
| 410 | |
| 411 str->append(indentStr); | |
| 412 base::StringAppendF(str, "drawsContent: %s\n", m_drawsContent ? "yes" : "no" ); | |
| 413 } | |
| 414 | |
| 415 std::string LayerImpl::layerTreeAsText() const | |
| 416 { | |
| 417 std::string str; | |
| 418 dumpLayer(&str, 0); | |
| 419 return str; | |
| 420 } | |
| 421 | |
| 422 void LayerImpl::dumpLayer(std::string* str, int indent) const | |
| 423 { | |
| 424 str->append(indentString(indent)); | |
| 425 base::StringAppendF(str, "%s(%s)\n", layerTypeAsString(), m_debugName.data() ); | |
| 426 dumpLayerProperties(str, indent+2); | |
| 427 if (m_replicaLayer) { | |
| 428 str->append(indentString(indent+2)); | |
| 429 str->append("Replica:\n"); | |
| 430 m_replicaLayer->dumpLayer(str, indent+3); | |
| 431 } | |
| 432 if (m_maskLayer) { | |
| 433 str->append(indentString(indent+2)); | |
| 434 str->append("Mask:\n"); | |
| 435 m_maskLayer->dumpLayer(str, indent+3); | |
| 436 } | |
| 437 for (size_t i = 0; i < m_children.size(); ++i) | |
| 438 m_children[i]->dumpLayer(str, indent+1); | |
| 439 } | |
| 440 | |
| 441 base::DictionaryValue* LayerImpl::layerTreeAsJson() const | |
| 442 { | |
| 443 base::ListValue* list; | |
| 444 base::DictionaryValue* result = new base::DictionaryValue; | |
| 445 result->SetString("LayerType", layerTypeAsString()); | |
| 446 | |
| 447 list = new base::ListValue; | |
| 448 list->AppendInteger(bounds().width()); | |
| 449 list->AppendInteger(bounds().height()); | |
| 450 result->Set("Bounds", list); | |
| 451 | |
| 452 list = new base::ListValue; | |
| 453 list->AppendDouble(m_position.x()); | |
| 454 list->AppendDouble(m_position.y()); | |
| 455 result->Set("Position", list); | |
| 456 | |
| 457 const gfx::Transform& gfxTransform = m_drawProperties.target_space_transform ; | |
| 458 double transform[16]; | |
| 459 gfxTransform.matrix().asColMajord(transform); | |
| 460 list = new base::ListValue; | |
| 461 for (int i = 0; i < 16; ++i) | |
| 462 list->AppendDouble(transform[i]); | |
| 463 result->Set("DrawTransform", list); | |
| 464 | |
| 465 result->SetBoolean("DrawsContent", m_drawsContent); | |
| 466 result->SetDouble("Opacity", opacity()); | |
| 467 | |
| 468 list = new base::ListValue; | |
| 469 for (size_t i = 0; i < m_children.size(); ++i) | |
| 470 list->Append(m_children[i]->layerTreeAsJson()); | |
| 471 result->Set("Children", list); | |
| 472 | |
| 473 return result; | |
| 474 } | |
| 475 | |
| 476 void LayerImpl::setStackingOrderChanged(bool stackingOrderChanged) | |
| 477 { | |
| 478 if (stackingOrderChanged) { | |
| 479 m_stackingOrderChanged = true; | |
| 480 noteLayerPropertyChangedForSubtree(); | |
| 481 } | |
| 482 } | |
| 483 | |
| 484 bool LayerImpl::layerSurfacePropertyChanged() const | |
| 485 { | |
| 486 if (m_layerSurfacePropertyChanged) | |
| 487 return true; | |
| 488 | |
| 489 // If this layer's surface property hasn't changed, we want to see if | |
| 490 // some layer above us has changed this property. This is done for the | |
| 491 // case when such parent layer does not draw content, and therefore will | |
| 492 // not be traversed by the damage tracker. We need to make sure that | |
| 493 // property change on such layer will be caught by its descendants. | |
| 494 LayerImpl* current = this->m_parent; | |
| 495 while (current && !current->m_drawProperties.render_surface) { | |
| 496 if (current->m_layerSurfacePropertyChanged) | |
| 497 return true; | |
| 498 current = current->m_parent; | |
| 499 } | |
| 500 | |
| 501 return false; | |
| 502 } | |
| 503 | |
| 504 void LayerImpl::noteLayerSurfacePropertyChanged() | |
| 505 { | |
| 506 m_layerSurfacePropertyChanged = true; | |
| 507 layerTreeImpl()->set_needs_update_draw_properties(); | |
| 508 } | |
| 509 | |
| 510 void LayerImpl::noteLayerPropertyChanged() | |
| 511 { | |
| 512 m_layerPropertyChanged = true; | |
| 513 layerTreeImpl()->set_needs_update_draw_properties(); | |
| 514 } | |
| 515 | |
| 516 void LayerImpl::noteLayerPropertyChangedForSubtree() | |
| 517 { | |
| 518 noteLayerPropertyChanged(); | |
| 519 noteLayerPropertyChangedForDescendants(); | |
| 520 } | |
| 521 | |
| 522 void LayerImpl::noteLayerPropertyChangedForDescendants() | |
| 523 { | |
| 524 layerTreeImpl()->set_needs_update_draw_properties(); | |
| 525 for (size_t i = 0; i < m_children.size(); ++i) | |
| 526 m_children[i]->noteLayerPropertyChangedForSubtree(); | |
| 527 } | |
| 528 | |
| 529 const char* LayerImpl::layerTypeAsString() const | |
| 530 { | |
| 531 return "Layer"; | |
| 532 } | |
| 533 | |
| 534 void LayerImpl::resetAllChangeTrackingForSubtree() | |
| 535 { | |
| 536 m_layerPropertyChanged = false; | |
| 537 m_layerSurfacePropertyChanged = false; | |
| 538 | |
| 539 m_updateRect = gfx::RectF(); | |
| 540 | |
| 541 if (m_drawProperties.render_surface) | |
| 542 m_drawProperties.render_surface->ResetPropertyChangedFlag(); | |
| 543 | |
| 544 if (m_maskLayer) | |
| 545 m_maskLayer->resetAllChangeTrackingForSubtree(); | |
| 546 | |
| 547 if (m_replicaLayer) | |
| 548 m_replicaLayer->resetAllChangeTrackingForSubtree(); // also resets the r eplica mask, if it exists. | |
| 549 | |
| 550 for (size_t i = 0; i < m_children.size(); ++i) | |
| 551 m_children[i]->resetAllChangeTrackingForSubtree(); | |
| 552 } | |
| 553 | |
| 554 bool LayerImpl::layerIsAlwaysDamaged() const | |
| 555 { | |
| 556 return false; | |
| 557 } | |
| 558 | |
| 559 int LayerImpl::id() const | |
| 560 { | |
| 561 return m_layerId; | |
| 562 } | |
| 563 | |
| 564 void LayerImpl::OnOpacityAnimated(float opacity) | |
| 565 { | |
| 566 setOpacity(opacity); | |
| 567 } | |
| 568 | |
| 569 void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) | |
| 570 { | |
| 571 setTransform(transform); | |
| 572 } | |
| 573 | |
| 574 bool LayerImpl::IsActive() const | |
| 575 { | |
| 576 return m_layerTreeImpl->IsActiveTree(); | |
| 577 } | |
| 578 | |
| 579 void LayerImpl::setBounds(const gfx::Size& bounds) | |
| 580 { | |
| 581 if (m_bounds == bounds) | |
| 582 return; | |
| 583 | |
| 584 m_bounds = bounds; | |
| 585 | |
| 586 if (masksToBounds()) | |
| 587 noteLayerPropertyChangedForSubtree(); | |
| 588 else | |
| 589 noteLayerPropertyChanged(); | |
| 590 } | |
| 591 | |
| 592 void LayerImpl::setMaskLayer(scoped_ptr<LayerImpl> maskLayer) | |
| 593 { | |
| 594 int newLayerId = maskLayer ? maskLayer->id() : -1; | |
| 595 | |
| 596 if (maskLayer) { | |
| 597 DCHECK_EQ(layerTreeImpl(), maskLayer->layerTreeImpl()); | |
| 598 DCHECK_NE(newLayerId, m_maskLayerId); | |
| 599 } else if (newLayerId == m_maskLayerId) | |
| 600 return; | |
| 601 | |
| 602 m_maskLayer = maskLayer.Pass(); | |
| 603 m_maskLayerId = newLayerId; | |
| 604 if (m_maskLayer) | |
| 605 m_maskLayer->setParent(this); | |
| 606 noteLayerPropertyChangedForSubtree(); | |
| 607 } | |
| 608 | |
| 609 scoped_ptr<LayerImpl> LayerImpl::takeMaskLayer() | |
| 610 { | |
| 611 m_maskLayerId = -1; | |
| 612 return m_maskLayer.Pass(); | |
| 613 } | |
| 614 | |
| 615 void LayerImpl::setReplicaLayer(scoped_ptr<LayerImpl> replicaLayer) | |
| 616 { | |
| 617 int newLayerId = replicaLayer ? replicaLayer->id() : -1; | |
| 618 | |
| 619 if (replicaLayer) { | |
| 620 DCHECK_EQ(layerTreeImpl(), replicaLayer->layerTreeImpl()); | |
| 621 DCHECK_NE(newLayerId, m_replicaLayerId); | |
| 622 } else if (newLayerId == m_replicaLayerId) | |
| 623 return; | |
| 624 | |
| 625 m_replicaLayer = replicaLayer.Pass(); | |
| 626 m_replicaLayerId = newLayerId; | |
| 627 if (m_replicaLayer) | |
| 628 m_replicaLayer->setParent(this); | |
| 629 noteLayerPropertyChangedForSubtree(); | |
| 630 } | |
| 631 | |
| 632 scoped_ptr<LayerImpl> LayerImpl::takeReplicaLayer() | |
| 633 { | |
| 634 m_replicaLayerId = -1; | |
| 635 return m_replicaLayer.Pass(); | |
| 636 } | |
| 637 | |
| 638 ScrollbarLayerImpl* LayerImpl::toScrollbarLayer() | |
| 639 { | |
| 640 return 0; | |
| 641 } | |
| 642 | |
| 643 void LayerImpl::setDrawsContent(bool drawsContent) | |
| 644 { | |
| 645 if (m_drawsContent == drawsContent) | |
| 646 return; | |
| 647 | |
| 648 m_drawsContent = drawsContent; | |
| 649 noteLayerPropertyChanged(); | |
| 650 } | |
| 651 | |
| 652 void LayerImpl::setAnchorPoint(const gfx::PointF& anchorPoint) | |
| 653 { | |
| 654 if (m_anchorPoint == anchorPoint) | |
| 655 return; | |
| 656 | |
| 657 m_anchorPoint = anchorPoint; | |
| 658 noteLayerPropertyChangedForSubtree(); | |
| 659 } | |
| 660 | |
| 661 void LayerImpl::setAnchorPointZ(float anchorPointZ) | |
| 662 { | |
| 663 if (m_anchorPointZ == anchorPointZ) | |
| 664 return; | |
| 665 | |
| 666 m_anchorPointZ = anchorPointZ; | |
| 667 noteLayerPropertyChangedForSubtree(); | |
| 668 } | |
| 669 | |
| 670 void LayerImpl::setBackgroundColor(SkColor backgroundColor) | |
| 671 { | |
| 672 if (m_backgroundColor == backgroundColor) | |
| 673 return; | |
| 674 | |
| 675 m_backgroundColor = backgroundColor; | |
| 676 noteLayerPropertyChanged(); | |
| 677 } | |
| 678 | |
| 679 void LayerImpl::setFilters(const WebKit::WebFilterOperations& filters) | |
| 680 { | |
| 681 if (m_filters == filters) | |
| 682 return; | |
| 683 | |
| 684 DCHECK(!m_filter); | |
| 685 m_filters = filters; | |
| 686 noteLayerPropertyChangedForSubtree(); | |
| 687 } | |
| 688 | |
| 689 void LayerImpl::setBackgroundFilters(const WebKit::WebFilterOperations& backgrou ndFilters) | |
| 690 { | |
| 691 if (m_backgroundFilters == backgroundFilters) | |
| 692 return; | |
| 693 | |
| 694 m_backgroundFilters = backgroundFilters; | |
| 695 noteLayerPropertyChanged(); | |
| 696 } | |
| 697 | |
| 698 void LayerImpl::setFilter(const skia::RefPtr<SkImageFilter>& filter) | |
| 699 { | |
| 700 if (m_filter.get() == filter.get()) | |
| 701 return; | |
| 702 | |
| 703 DCHECK(m_filters.isEmpty()); | |
| 704 m_filter = filter; | |
| 705 noteLayerPropertyChangedForSubtree(); | |
| 706 } | |
| 707 | |
| 708 void LayerImpl::setMasksToBounds(bool masksToBounds) | |
| 709 { | |
| 710 if (m_masksToBounds == masksToBounds) | |
| 711 return; | |
| 712 | |
| 713 m_masksToBounds = masksToBounds; | |
| 714 noteLayerPropertyChangedForSubtree(); | |
| 715 } | |
| 716 | |
| 717 void LayerImpl::setContentsOpaque(bool opaque) | |
| 718 { | |
| 719 if (m_contentsOpaque == opaque) | |
| 720 return; | |
| 721 | |
| 722 m_contentsOpaque = opaque; | |
| 723 noteLayerPropertyChangedForSubtree(); | |
| 724 } | |
| 725 | |
| 726 void LayerImpl::setOpacity(float opacity) | |
| 727 { | |
| 728 if (m_opacity == opacity) | |
| 729 return; | |
| 730 | |
| 731 m_opacity = opacity; | |
| 732 noteLayerSurfacePropertyChanged(); | |
| 733 } | |
| 734 | |
| 735 float LayerImpl::opacity() const | |
| 736 { | |
| 737 return m_opacity; | |
| 738 } | |
| 739 | |
| 740 bool LayerImpl::opacityIsAnimating() const | |
| 741 { | |
| 742 return m_layerAnimationController->IsAnimatingProperty(Animation::Opacity); | |
| 743 } | |
| 744 | |
| 745 void LayerImpl::setPosition(const gfx::PointF& position) | |
| 746 { | |
| 747 if (m_position == position) | |
| 748 return; | |
| 749 | |
| 750 m_position = position; | |
| 751 noteLayerPropertyChangedForSubtree(); | |
| 752 } | |
| 753 | |
| 754 void LayerImpl::setPreserves3D(bool preserves3D) | |
| 755 { | |
| 756 if (m_preserves3D == preserves3D) | |
| 757 return; | |
| 758 | |
| 759 m_preserves3D = preserves3D; | |
| 760 noteLayerPropertyChangedForSubtree(); | |
| 761 } | |
| 762 | |
| 763 void LayerImpl::setSublayerTransform(const gfx::Transform& sublayerTransform) | |
| 764 { | |
| 765 if (m_sublayerTransform == sublayerTransform) | |
| 766 return; | |
| 767 | |
| 768 m_sublayerTransform = sublayerTransform; | |
| 769 // sublayer transform does not affect the current layer; it affects only its children. | |
| 770 noteLayerPropertyChangedForDescendants(); | |
| 771 } | |
| 772 | |
| 773 void LayerImpl::setTransform(const gfx::Transform& transform) | |
| 774 { | |
| 775 if (m_transform == transform) | |
| 776 return; | |
| 777 | |
| 778 m_transform = transform; | |
| 779 noteLayerSurfacePropertyChanged(); | |
| 780 } | |
| 781 | |
| 782 const gfx::Transform& LayerImpl::transform() const | |
| 783 { | |
| 784 return m_transform; | |
| 785 } | |
| 786 | |
| 787 bool LayerImpl::transformIsAnimating() const | |
| 788 { | |
| 789 return m_layerAnimationController->IsAnimatingProperty(Animation::Transform) ; | |
| 790 } | |
| 791 | |
| 792 void LayerImpl::setContentBounds(const gfx::Size& contentBounds) | |
| 793 { | |
| 794 if (this->contentBounds() == contentBounds) | |
| 795 return; | |
| 796 | |
| 797 m_drawProperties.content_bounds = contentBounds; | |
| 798 noteLayerPropertyChanged(); | |
| 799 } | |
| 800 | |
| 801 void LayerImpl::setContentsScale(float contentsScaleX, float contentsScaleY) | |
| 802 { | |
| 803 if (this->contentsScaleX() == contentsScaleX && this->contentsScaleY() == co ntentsScaleY) | |
| 804 return; | |
| 805 | |
| 806 m_drawProperties.contents_scale_x = contentsScaleX; | |
| 807 m_drawProperties.contents_scale_y = contentsScaleY; | |
| 808 noteLayerPropertyChanged(); | |
| 809 } | |
| 810 | |
| 811 void LayerImpl::calculateContentsScale( | |
| 812 float idealContentsScale, | |
| 813 bool animatingTransformToScreen, | |
| 814 float* contentsScaleX, | |
| 815 float* contentsScaleY, | |
| 816 gfx::Size* contentBounds) | |
| 817 { | |
| 818 // Base LayerImpl has all of its content scales and content bounds pushed | |
| 819 // from its Layer during commit and just reuses those values as-is. | |
| 820 *contentsScaleX = this->contentsScaleX(); | |
| 821 *contentsScaleY = this->contentsScaleY(); | |
| 822 *contentBounds = this->contentBounds(); | |
| 823 } | |
| 824 | |
| 825 void LayerImpl::updateScrollbarPositions() | |
| 826 { | |
| 827 gfx::Vector2dF currentOffset = m_scrollOffset + m_scrollDelta; | |
| 828 | |
| 829 if (m_horizontalScrollbarLayer) { | |
| 830 m_horizontalScrollbarLayer->SetCurrentPos(currentOffset.x()); | |
| 831 m_horizontalScrollbarLayer->SetTotalSize(m_bounds.width()); | |
| 832 m_horizontalScrollbarLayer->SetMaximum(m_maxScrollOffset.x()); | |
| 833 } | |
| 834 if (m_verticalScrollbarLayer) { | |
| 835 m_verticalScrollbarLayer->SetCurrentPos(currentOffset.y()); | |
| 836 m_verticalScrollbarLayer->SetTotalSize(m_bounds.height()); | |
| 837 m_verticalScrollbarLayer->SetMaximum(m_maxScrollOffset.y()); | |
| 838 } | |
| 839 | |
| 840 if (currentOffset == m_lastScrollOffset) | |
| 841 return; | |
| 842 m_lastScrollOffset = currentOffset; | |
| 843 | |
| 844 if (m_scrollbarAnimationController) | |
| 845 m_scrollbarAnimationController->didUpdateScrollOffset(base::TimeTicks::N ow()); | |
| 846 | |
| 847 // Get the m_currentOffset.y() value for a sanity-check on scrolling | |
| 848 // benchmark metrics. Specifically, we want to make sure | |
| 849 // BasicMouseWheelSmoothScrollGesture has proper scroll curves. | |
| 850 if (layerTreeImpl()->IsActiveTree()) { | |
| 851 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), currentOffset.y( )); | |
| 852 } | |
| 853 } | |
| 854 | |
| 855 void LayerImpl::setScrollOffset(gfx::Vector2d scrollOffset) | |
| 856 { | |
| 857 if (m_scrollOffset == scrollOffset) | |
| 858 return; | |
| 859 | |
| 860 m_scrollOffset = scrollOffset; | |
| 861 noteLayerPropertyChangedForSubtree(); | |
| 862 updateScrollbarPositions(); | |
| 863 } | |
| 864 | |
| 865 void LayerImpl::setScrollDelta(const gfx::Vector2dF& scrollDelta) | |
| 866 { | |
| 867 if (m_scrollDelta == scrollDelta) | |
| 868 return; | |
| 869 | |
| 870 if (layerTreeImpl()->IsActiveTree()) | |
| 871 { | |
| 872 LayerImpl* pending_twin = layerTreeImpl()->FindPendingTreeLayerById(id() ); | |
| 873 if (pending_twin) { | |
| 874 // The pending twin can't mirror the scroll delta of the active | |
| 875 // layer. Although the delta - sent scroll delta difference is | |
| 876 // identical for both twins, the sent scroll delta for the pending | |
| 877 // layer is zero, as anything that has been sent has been baked | |
| 878 // into the layer's position/scroll offset as a part of commit. | |
| 879 DCHECK(pending_twin->sentScrollDelta().IsZero()); | |
| 880 pending_twin->setScrollDelta(scrollDelta - sentScrollDelta()); | |
| 881 } | |
| 882 } | |
| 883 | |
| 884 m_scrollDelta = scrollDelta; | |
| 885 noteLayerPropertyChangedForSubtree(); | |
| 886 | |
| 887 updateScrollbarPositions(); | |
| 888 } | |
| 889 | |
| 890 void LayerImpl::setImplTransform(const gfx::Transform& transform) | |
| 891 { | |
| 892 if (m_implTransform == transform) | |
| 893 return; | |
| 894 | |
| 895 m_implTransform = transform; | |
| 896 noteLayerPropertyChangedForSubtree(); | |
| 897 } | |
| 898 | |
| 899 void LayerImpl::setDoubleSided(bool doubleSided) | |
| 900 { | |
| 901 if (m_doubleSided == doubleSided) | |
| 902 return; | |
| 903 | |
| 904 m_doubleSided = doubleSided; | |
| 905 noteLayerPropertyChangedForSubtree(); | |
| 906 } | |
| 907 | |
| 908 Region LayerImpl::visibleContentOpaqueRegion() const | |
| 909 { | |
| 910 if (contentsOpaque()) | |
| 911 return visibleContentRect(); | |
| 912 return Region(); | |
| 913 } | |
| 914 | |
| 915 void LayerImpl::didLoseOutputSurface() | |
| 916 { | |
| 917 } | |
| 918 | |
| 919 void LayerImpl::setMaxScrollOffset(gfx::Vector2d maxScrollOffset) | |
| 920 { | |
| 921 if (m_maxScrollOffset == maxScrollOffset) | |
| 922 return; | |
| 923 m_maxScrollOffset = maxScrollOffset; | |
| 924 | |
| 925 layerTreeImpl()->set_needs_update_draw_properties(); | |
| 926 updateScrollbarPositions(); | |
| 927 } | |
| 928 | |
| 929 void LayerImpl::setScrollbarOpacity(float opacity) | |
| 930 { | |
| 931 if (m_horizontalScrollbarLayer) | |
| 932 m_horizontalScrollbarLayer->setOpacity(opacity); | |
| 933 if (m_verticalScrollbarLayer) | |
| 934 m_verticalScrollbarLayer->setOpacity(opacity); | |
| 935 } | |
| 936 | |
| 937 inline scoped_ptr<ScrollbarAnimationController> createScrollbarAnimationControll erWithFade(LayerImpl* layer) | |
| 938 { | |
| 939 double fadeoutDelay = 0.3; | |
| 940 double fadeoutLength = 0.3; | |
| 941 return ScrollbarAnimationControllerLinearFade::create(layer, fadeoutDelay, f adeoutLength).PassAs<ScrollbarAnimationController>(); | |
| 942 } | |
| 943 | |
| 944 void LayerImpl::didBecomeActive() | |
| 945 { | |
| 946 if (!m_layerTreeImpl->settings().useLinearFadeScrollbarAnimator) | |
| 947 return; | |
| 948 | |
| 949 bool needScrollbarAnimationController = m_horizontalScrollbarLayer || m_vert icalScrollbarLayer; | |
| 950 if (needScrollbarAnimationController) { | |
| 951 if (!m_scrollbarAnimationController) | |
| 952 m_scrollbarAnimationController = createScrollbarAnimationControllerW ithFade(this); | |
| 953 } else { | |
| 954 m_scrollbarAnimationController.reset(); | |
| 955 } | |
| 956 | |
| 957 } | |
| 958 void LayerImpl::setHorizontalScrollbarLayer(ScrollbarLayerImpl* scrollbarLayer) | |
| 959 { | |
| 960 m_horizontalScrollbarLayer = scrollbarLayer; | |
| 961 if (m_horizontalScrollbarLayer) | |
| 962 m_horizontalScrollbarLayer->set_scroll_layer_id(id()); | |
| 963 } | |
| 964 | |
| 965 void LayerImpl::setVerticalScrollbarLayer(ScrollbarLayerImpl* scrollbarLayer) | |
| 966 { | |
| 967 m_verticalScrollbarLayer = scrollbarLayer; | |
| 968 if (m_verticalScrollbarLayer) | |
| 969 m_verticalScrollbarLayer->set_scroll_layer_id(id()); | |
| 970 } | |
| 971 | |
| 972 void LayerImpl::AsValueInto(base::DictionaryValue* dict) const | |
| 973 { | |
| 974 dict->SetInteger("id", id()); | |
| 975 dict->Set("bounds", MathUtil::asValue(bounds()).release()); | |
| 976 dict->SetInteger("draws_content", drawsContent()); | |
| 977 | |
| 978 bool clipped; | |
| 979 gfx::QuadF layer_quad = MathUtil::mapQuad( | |
| 980 screenSpaceTransform(), | |
| 981 gfx::QuadF(gfx::Rect(contentBounds())), | |
| 982 clipped); | |
| 983 dict->Set("layer_quad", MathUtil::asValue(layer_quad).release()); | |
| 984 | |
| 985 } | |
| 986 | |
| 987 scoped_ptr<base::Value> LayerImpl::AsValue() const | |
| 988 { | |
| 989 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | |
| 990 AsValueInto(state.get()); | |
| 991 return state.PassAs<base::Value>(); | |
| 992 } | 947 } |
| 993 | 948 |
| 994 } // namespace cc | 949 } // namespace cc |
| OLD | NEW |