Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: cc/layer_impl.cc

Issue 12774006: cc: Chromify Layer and LayerImpl classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: MoreAndroidCompilings Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/layer_impl.h ('k') | cc/layer_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
OLDNEW
« no previous file with comments | « cc/layer_impl.h ('k') | cc/layer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698