| 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; |
| 593 } |
| 594 |
| 595 mask_layer_ = mask_layer.Pass(); |
| 596 mask_layer_id_ = new_layer_id; |
| 597 if (mask_layer_) |
| 598 mask_layer_->set_parent(this); |
| 599 NoteLayerPropertyChangedForSubtree(); |
| 600 } |
| 601 |
| 602 scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() { |
| 603 mask_layer_id_ = -1; |
| 604 return mask_layer_.Pass(); |
| 605 } |
| 606 |
| 607 void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { |
| 608 int new_layer_id = replica_layer ? replica_layer->id() : -1; |
| 609 |
| 610 if (replica_layer) { |
| 611 DCHECK_EQ(layer_tree_impl(), replica_layer->layer_tree_impl()); |
| 612 DCHECK_NE(new_layer_id, replica_layer_id_); |
| 613 } else if (new_layer_id == replica_layer_id_) { |
| 614 return; |
| 615 } |
| 616 |
| 617 replica_layer_ = replica_layer.Pass(); |
| 618 replica_layer_id_ = new_layer_id; |
| 619 if (replica_layer_) |
| 620 replica_layer_->set_parent(this); |
| 621 NoteLayerPropertyChangedForSubtree(); |
| 622 } |
| 623 |
| 624 scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() { |
| 625 replica_layer_id_ = -1; |
| 626 return replica_layer_.Pass(); |
| 627 } |
| 628 |
| 629 ScrollbarLayerImpl* LayerImpl::ToScrollbarLayer() { |
| 630 return NULL; |
| 631 } |
| 632 |
| 633 void LayerImpl::SetDrawsContent(bool draws_content) { |
| 634 if (draws_content_ == draws_content) |
| 635 return; |
| 636 |
| 637 draws_content_ = draws_content; |
| 638 NoteLayerPropertyChanged(); |
| 639 } |
| 640 |
| 641 void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point) { |
| 642 if (anchor_point_ == anchor_point) |
| 643 return; |
| 644 |
| 645 anchor_point_ = anchor_point; |
| 646 NoteLayerPropertyChangedForSubtree(); |
| 647 } |
| 648 |
| 649 void LayerImpl::SetAnchorPointZ(float anchor_point_z) { |
| 650 if (anchor_point_z_ == anchor_point_z) |
| 651 return; |
| 652 |
| 653 anchor_point_z_ = anchor_point_z; |
| 654 NoteLayerPropertyChangedForSubtree(); |
| 655 } |
| 656 |
| 657 void LayerImpl::SetBackgroundColor(SkColor background_color) { |
| 658 if (background_color_ == background_color) |
| 659 return; |
| 660 |
| 661 background_color_ = background_color; |
| 662 NoteLayerPropertyChanged(); |
| 663 } |
| 664 |
| 665 void LayerImpl::SetFilters(const WebKit::WebFilterOperations& filters) { |
| 666 if (filters_ == filters) |
| 667 return; |
| 668 |
| 669 DCHECK(!filter_); |
| 670 filters_ = filters; |
| 671 NoteLayerPropertyChangedForSubtree(); |
| 672 } |
| 673 |
| 674 void LayerImpl::SetBackgroundFilters( |
| 675 const WebKit::WebFilterOperations& filters) { |
| 676 if (background_filters_ == filters) |
| 677 return; |
| 678 |
| 679 background_filters_ = filters; |
| 680 NoteLayerPropertyChanged(); |
| 681 } |
| 682 |
| 683 void LayerImpl::SetFilter(const skia::RefPtr<SkImageFilter>& filter) { |
| 684 if (filter_.get() == filter.get()) |
| 685 return; |
| 686 |
| 687 DCHECK(filters_.isEmpty()); |
| 688 filter_ = filter; |
| 689 NoteLayerPropertyChangedForSubtree(); |
| 690 } |
| 691 |
| 692 void LayerImpl::SetMasksToBounds(bool masks_to_bounds) { |
| 693 if (masks_to_bounds_ == masks_to_bounds) |
| 694 return; |
| 695 |
| 696 masks_to_bounds_ = masks_to_bounds; |
| 697 NoteLayerPropertyChangedForSubtree(); |
| 698 } |
| 699 |
| 700 void LayerImpl::SetContentsOpaque(bool opaque) { |
| 701 if (contents_opaque_ == opaque) |
| 702 return; |
| 703 |
| 704 contents_opaque_ = opaque; |
| 705 NoteLayerPropertyChangedForSubtree(); |
| 706 } |
| 707 |
| 708 void LayerImpl::SetOpacity(float opacity) { |
| 709 if (opacity_ == opacity) |
| 710 return; |
| 711 |
| 712 opacity_ = opacity; |
| 713 NoteLayerSurfacePropertyChanged(); |
| 714 } |
| 715 |
| 716 bool LayerImpl::OpacityIsAnimating() const { |
| 717 return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity); |
| 718 } |
| 719 |
| 720 void LayerImpl::SetPosition(gfx::PointF position) { |
| 721 if (position_ == position) |
| 722 return; |
| 723 |
| 724 position_ = position; |
| 725 NoteLayerPropertyChangedForSubtree(); |
| 726 } |
| 727 |
| 728 void LayerImpl::SetPreserves3d(bool preserves3_d) { |
| 729 if (preserves_3d_ == preserves3_d) |
| 730 return; |
| 731 |
| 732 preserves_3d_ = preserves3_d; |
| 733 NoteLayerPropertyChangedForSubtree(); |
| 734 } |
| 735 |
| 736 void LayerImpl::SetSublayerTransform(const gfx::Transform& sublayer_transform) { |
| 737 if (sublayer_transform_ == sublayer_transform) |
| 738 return; |
| 739 |
| 740 sublayer_transform_ = sublayer_transform; |
| 741 // Sublayer transform does not affect the current layer; it affects only its |
| 742 // children. |
| 743 NoteLayerPropertyChangedForDescendants(); |
| 744 } |
| 745 |
| 746 void LayerImpl::SetTransform(const gfx::Transform& transform) { |
| 747 if (transform_ == transform) |
| 748 return; |
| 749 |
| 750 transform_ = transform; |
| 751 NoteLayerSurfacePropertyChanged(); |
| 752 } |
| 753 |
| 754 bool LayerImpl::TransformIsAnimating() const { |
| 755 return layer_animation_controller_->IsAnimatingProperty(Animation::Transform); |
| 756 } |
| 757 |
| 758 void LayerImpl::SetContentBounds(gfx::Size content_bounds) { |
| 759 if (this->content_bounds() == content_bounds) |
| 760 return; |
| 761 |
| 762 draw_properties_.content_bounds = content_bounds; |
| 763 NoteLayerPropertyChanged(); |
| 764 } |
| 765 |
| 766 void LayerImpl::SetContentsScale(float contents_scale_x, |
| 767 float contents_scale_y) { |
| 768 if (this->contents_scale_x() == contents_scale_x && |
| 769 this->contents_scale_y() == contents_scale_y) |
| 770 return; |
| 771 |
| 772 draw_properties_.contents_scale_x = contents_scale_x; |
| 773 draw_properties_.contents_scale_y = contents_scale_y; |
| 774 NoteLayerPropertyChanged(); |
| 775 } |
| 776 |
| 777 void LayerImpl::CalculateContentsScale( |
| 778 float ideal_contents_scale, |
| 779 bool animating_transform_to_screen, |
| 780 float* contents_scale_x, |
| 781 float* contents_scale_y, |
| 782 gfx::Size* content_bounds) { |
| 783 // Base LayerImpl has all of its content scales and content bounds pushed |
| 784 // from its Layer during commit and just reuses those values as-is. |
| 785 *contents_scale_x = this->contents_scale_x(); |
| 786 *contents_scale_y = this->contents_scale_y(); |
| 787 *content_bounds = this->content_bounds(); |
| 788 } |
| 789 |
| 790 void LayerImpl::UpdateScrollbarPositions() { |
| 791 gfx::Vector2dF current_offset = scroll_offset_ + scroll_delta_; |
| 792 |
| 793 if (horizontal_scrollbar_layer_) { |
| 794 horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x()); |
| 795 horizontal_scrollbar_layer_->SetTotalSize(bounds_.width()); |
| 796 horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x()); |
| 797 } |
| 798 if (vertical_scrollbar_layer_) { |
| 799 vertical_scrollbar_layer_->SetCurrentPos(current_offset.y()); |
| 800 vertical_scrollbar_layer_->SetTotalSize(bounds_.height()); |
| 801 vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y()); |
| 802 } |
| 803 |
| 804 if (current_offset == last_scroll_offset_) |
| 805 return; |
| 806 last_scroll_offset_ = current_offset; |
| 807 |
| 808 if (scrollbar_animation_controller_) { |
| 809 scrollbar_animation_controller_->didUpdateScrollOffset( |
| 810 base::TimeTicks::Now()); |
| 811 } |
| 812 |
| 813 // Get the current_offset_.y() value for a sanity-check on scrolling |
| 814 // benchmark metrics. Specifically, we want to make sure |
| 815 // BasicMouseWheelSmoothScrollGesture has proper scroll curves. |
| 816 if (layer_tree_impl()->IsActiveTree()) { |
| 817 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y()); |
| 818 } |
| 819 } |
| 820 |
| 821 void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { |
| 822 if (scroll_offset_ == scroll_offset) |
| 823 return; |
| 824 |
| 825 scroll_offset_ = scroll_offset; |
| 826 NoteLayerPropertyChangedForSubtree(); |
| 827 UpdateScrollbarPositions(); |
| 828 } |
| 829 |
| 830 void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) { |
| 831 if (scroll_delta_ == scroll_delta) |
| 832 return; |
| 833 |
| 834 if (layer_tree_impl()->IsActiveTree()) { |
| 835 LayerImpl* pending_twin = layer_tree_impl()->FindPendingTreeLayerById(id()); |
| 836 if (pending_twin) { |
| 837 // The pending twin can't mirror the scroll delta of the active |
| 838 // layer. Although the delta - sent scroll delta difference is |
| 839 // identical for both twins, the sent scroll delta for the pending |
| 840 // layer is zero, as anything that has been sent has been baked |
| 841 // into the layer's position/scroll offset as a part of commit. |
| 842 DCHECK(pending_twin->sent_scroll_delta().IsZero()); |
| 843 pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta()); |
| 244 } | 844 } |
| 245 | 845 } |
| 246 if (!screenSpaceTransform().IsInvertible()) { | 846 |
| 247 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored nonInvertibleTransform
"); | 847 scroll_delta_ = scroll_delta; |
| 248 return InputHandlerClient::ScrollIgnored; | 848 NoteLayerPropertyChangedForSubtree(); |
| 849 |
| 850 UpdateScrollbarPositions(); |
| 851 } |
| 852 |
| 853 void LayerImpl::SetImplTransform(const gfx::Transform& transform) { |
| 854 if (impl_transform_ == transform) |
| 855 return; |
| 856 |
| 857 impl_transform_ = transform; |
| 858 NoteLayerPropertyChangedForSubtree(); |
| 859 } |
| 860 |
| 861 void LayerImpl::SetDoubleSided(bool double_sided) { |
| 862 if (double_sided_ == double_sided) |
| 863 return; |
| 864 |
| 865 double_sided_ = double_sided; |
| 866 NoteLayerPropertyChangedForSubtree(); |
| 867 } |
| 868 |
| 869 Region LayerImpl::VisibleContentOpaqueRegion() const { |
| 870 if (contents_opaque()) |
| 871 return visible_content_rect(); |
| 872 return Region(); |
| 873 } |
| 874 |
| 875 void LayerImpl::DidLoseOutputSurface() {} |
| 876 |
| 877 void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { |
| 878 if (max_scroll_offset_ == max_scroll_offset) |
| 879 return; |
| 880 max_scroll_offset_ = max_scroll_offset; |
| 881 |
| 882 layer_tree_impl()->set_needs_update_draw_properties(); |
| 883 UpdateScrollbarPositions(); |
| 884 } |
| 885 |
| 886 void LayerImpl::SetScrollbarOpacity(float opacity) { |
| 887 if (horizontal_scrollbar_layer_) |
| 888 horizontal_scrollbar_layer_->SetOpacity(opacity); |
| 889 if (vertical_scrollbar_layer_) |
| 890 vertical_scrollbar_layer_->SetOpacity(opacity); |
| 891 } |
| 892 |
| 893 inline scoped_ptr<ScrollbarAnimationController> |
| 894 CreateScrollbarAnimationControllerWithFade(LayerImpl* layer) { |
| 895 double fadeout_delay = 0.3; |
| 896 double fadeout_length = 0.3; |
| 897 return ScrollbarAnimationControllerLinearFade::create( |
| 898 layer, fadeout_delay, fadeout_length) |
| 899 .PassAs<ScrollbarAnimationController>(); |
| 900 } |
| 901 |
| 902 void LayerImpl::DidBecomeActive() { |
| 903 if (!layer_tree_impl_->settings().useLinearFadeScrollbarAnimator) |
| 904 return; |
| 905 |
| 906 bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ || |
| 907 vertical_scrollbar_layer_; |
| 908 if (need_scrollbar_animation_controller) { |
| 909 if (!scrollbar_animation_controller_) { |
| 910 scrollbar_animation_controller_ = |
| 911 CreateScrollbarAnimationControllerWithFade(this); |
| 249 } | 912 } |
| 250 | 913 } else { |
| 251 if (!nonFastScrollableRegion().IsEmpty()) { | 914 scrollbar_animation_controller_.reset(); |
| 252 bool clipped = false; | 915 } |
| 253 gfx::Transform inverseScreenSpaceTransform(gfx::Transform::kSkipInitiali
zation); | 916 |
| 254 if (!screenSpaceTransform().GetInverse(&inverseScreenSpaceTransform)) { | 917 } |
| 255 // TODO(shawnsingh): We shouldn't be applying a projection if screen
space | 918 void LayerImpl::SetHorizontalScrollbarLayer( |
| 256 // transform is uninvertible here. Perhaps we should be returning | 919 ScrollbarLayerImpl* scrollbar_layer) { |
| 257 // ScrollOnMainThread in this case? | 920 horizontal_scrollbar_layer_ = scrollbar_layer; |
| 258 } | 921 if (horizontal_scrollbar_layer_) |
| 259 | 922 horizontal_scrollbar_layer_->set_scroll_layer_id(id()); |
| 260 gfx::PointF hitTestPointInContentSpace = MathUtil::projectPoint(inverseS
creenSpaceTransform, screenSpacePoint, clipped); | 923 } |
| 261 gfx::PointF hitTestPointInLayerSpace = gfx::ScalePoint(hitTestPointInCon
tentSpace, 1 / contentsScaleX(), 1 / contentsScaleY()); | 924 |
| 262 if (!clipped && nonFastScrollableRegion().Contains(gfx::ToRoundedPoint(h
itTestPointInLayerSpace))) { | 925 void LayerImpl::SetVerticalScrollbarLayer(ScrollbarLayerImpl* scrollbar_layer) { |
| 263 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed nonFastScrollableRe
gion"); | 926 vertical_scrollbar_layer_ = scrollbar_layer; |
| 264 return InputHandlerClient::ScrollOnMainThread; | 927 if (vertical_scrollbar_layer_) |
| 265 } | 928 vertical_scrollbar_layer_->set_scroll_layer_id(id()); |
| 266 } | 929 } |
| 267 | 930 |
| 268 if (type == InputHandlerClient::Wheel && haveWheelEventHandlers()) { | 931 void LayerImpl::AsValueInto(base::DictionaryValue* dict) const { |
| 269 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed wheelEventHandlers"); | 932 dict->SetInteger("id", id()); |
| 270 return InputHandlerClient::ScrollOnMainThread; | 933 dict->Set("bounds", MathUtil::asValue(bounds()).release()); |
| 271 } | 934 dict->SetInteger("draws_content", DrawsContent()); |
| 272 | 935 |
| 273 if (!scrollable()) { | 936 bool clipped; |
| 274 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); | 937 gfx::QuadF layer_quad = MathUtil::mapQuad( |
| 275 return InputHandlerClient::ScrollIgnored; | 938 screen_space_transform(), |
| 276 } | 939 gfx::QuadF(gfx::Rect(content_bounds())), |
| 277 | 940 clipped); |
| 278 if (m_maxScrollOffset.x() <= 0 && m_maxScrollOffset.y() <= 0) { | 941 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."); | 942 |
| 280 return InputHandlerClient::ScrollIgnored; | 943 } |
| 281 } | 944 |
| 282 | 945 scoped_ptr<base::Value> LayerImpl::AsValue() const { |
| 283 return InputHandlerClient::ScrollStarted; | 946 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| 284 } | 947 AsValueInto(state.get()); |
| 285 | 948 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 } | 949 } |
| 993 | 950 |
| 994 } // namespace cc | 951 } // namespace cc |
| OLD | NEW |