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

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: 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
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;
enne (OOO) 2013/03/12 02:40:19 Also needs braces to match if clause.
danakj 2013/03/12 02:47:16 Done.
593
594 mask_layer_ = mask_layer.Pass();
595 mask_layer_id_ = new_layer_id;
596 if (mask_layer_)
597 mask_layer_->set_parent(this);
598 NoteLayerPropertyChangedForSubtree();
599 }
600
601 scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() {
602 mask_layer_id_ = -1;
603 return mask_layer_.Pass();
604 }
605
606 void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) {
607 int new_layer_id = replica_layer ? replica_layer->id() : -1;
608
609 if (replica_layer) {
610 DCHECK_EQ(layer_tree_impl(), replica_layer->layer_tree_impl());
611 DCHECK_NE(new_layer_id, replica_layer_id_);
612 } else if (new_layer_id == replica_layer_id_)
613 return;
enne (OOO) 2013/03/12 02:40:19 Braces.
danakj 2013/03/12 02:47:16 Done.
614
615 replica_layer_ = replica_layer.Pass();
616 replica_layer_id_ = new_layer_id;
617 if (replica_layer_)
618 replica_layer_->set_parent(this);
619 NoteLayerPropertyChangedForSubtree();
620 }
621
622 scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() {
623 replica_layer_id_ = -1;
624 return replica_layer_.Pass();
625 }
626
627 ScrollbarLayerImpl* LayerImpl::ToScrollbarLayer() {
628 return NULL;
629 }
630
631 void LayerImpl::SetDrawsContent(bool draws_content) {
632 if (draws_content_ == draws_content)
633 return;
634
635 draws_content_ = draws_content;
636 NoteLayerPropertyChanged();
637 }
638
639 void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point) {
640 if (anchor_point_ == anchor_point)
641 return;
642
643 anchor_point_ = anchor_point;
644 NoteLayerPropertyChangedForSubtree();
645 }
646
647 void LayerImpl::SetAnchorPointZ(float anchor_point_z) {
648 if (anchor_point_z_ == anchor_point_z)
649 return;
650
651 anchor_point_z_ = anchor_point_z;
652 NoteLayerPropertyChangedForSubtree();
653 }
654
655 void LayerImpl::SetBackgroundColor(SkColor background_color) {
656 if (background_color_ == background_color)
657 return;
658
659 background_color_ = background_color;
660 NoteLayerPropertyChanged();
661 }
662
663 void LayerImpl::SetFilters(const WebKit::WebFilterOperations& filters) {
664 if (filters_ == filters)
665 return;
666
667 DCHECK(!filter_);
668 filters_ = filters;
669 NoteLayerPropertyChangedForSubtree();
670 }
671
672 void LayerImpl::SetBackgroundFilters(
673 const WebKit::WebFilterOperations& filters) {
674 if (background_filters_ == filters)
675 return;
676
677 background_filters_ = filters;
678 NoteLayerPropertyChanged();
679 }
680
681 void LayerImpl::SetFilter(const skia::RefPtr<SkImageFilter>& filter) {
682 if (filter_.get() == filter.get())
683 return;
684
685 DCHECK(filters_.isEmpty());
686 filter_ = filter;
687 NoteLayerPropertyChangedForSubtree();
688 }
689
690 void LayerImpl::SetMasksToBounds(bool masks_to_bounds) {
691 if (masks_to_bounds_ == masks_to_bounds)
692 return;
693
694 masks_to_bounds_ = masks_to_bounds;
695 NoteLayerPropertyChangedForSubtree();
696 }
697
698 void LayerImpl::SetContentsOpaque(bool opaque) {
699 if (contents_opaque_ == opaque)
700 return;
701
702 contents_opaque_ = opaque;
703 NoteLayerPropertyChangedForSubtree();
704 }
705
706 void LayerImpl::SetOpacity(float opacity) {
707 if (opacity_ == opacity)
708 return;
709
710 opacity_ = opacity;
711 NoteLayerSurfacePropertyChanged();
712 }
713
714 bool LayerImpl::OpacityIsAnimating() const {
715 return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity);
716 }
717
718 void LayerImpl::SetPosition(gfx::PointF position) {
719 if (position_ == position)
720 return;
721
722 position_ = position;
723 NoteLayerPropertyChangedForSubtree();
724 }
725
726 void LayerImpl::SetPreserves3d(bool preserves3_d) {
727 if (preserves_3d_ == preserves3_d)
728 return;
729
730 preserves_3d_ = preserves3_d;
731 NoteLayerPropertyChangedForSubtree();
732 }
733
734 void LayerImpl::SetSublayerTransform(const gfx::Transform& sublayer_transform) {
735 if (sublayer_transform_ == sublayer_transform)
736 return;
737
738 sublayer_transform_ = sublayer_transform;
739 // Sublayer transform does not affect the current layer; it affects only its
740 // children.
741 NoteLayerPropertyChangedForDescendants();
742 }
743
744 void LayerImpl::SetTransform(const gfx::Transform& transform) {
745 if (transform_ == transform)
746 return;
747
748 transform_ = transform;
749 NoteLayerSurfacePropertyChanged();
750 }
751
752 bool LayerImpl::TransformIsAnimating() const {
753 return layer_animation_controller_->IsAnimatingProperty(Animation::Transform);
754 }
755
756 void LayerImpl::SetContentBounds(gfx::Size content_bounds) {
757 if (this->content_bounds() == content_bounds)
758 return;
759
760 draw_properties_.content_bounds = content_bounds;
761 NoteLayerPropertyChanged();
762 }
763
764 void LayerImpl::SetContentsScale(float contents_scale_x,
765 float contents_scale_y) {
766 if (this->contents_scale_x() == contents_scale_x &&
767 this->contents_scale_y() == contents_scale_y)
768 return;
769
770 draw_properties_.contents_scale_x = contents_scale_x;
771 draw_properties_.contents_scale_y = contents_scale_y;
772 NoteLayerPropertyChanged();
773 }
774
775 void LayerImpl::CalculateContentsScale(
776 float ideal_contents_scale,
777 bool animating_transform_to_screen,
778 float* contents_scale_x,
779 float* contents_scale_y,
780 gfx::Size* content_bounds) {
781 // Base LayerImpl has all of its content scales and content bounds pushed
782 // from its Layer during commit and just reuses those values as-is.
783 *contents_scale_x = this->contents_scale_x();
784 *contents_scale_y = this->contents_scale_y();
785 *content_bounds = this->content_bounds();
786 }
787
788 void LayerImpl::UpdateScrollbarPositions() {
789 gfx::Vector2dF current_offset = scroll_offset_ + scroll_delta_;
790
791 if (horizontal_scrollbar_layer_) {
792 horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x());
793 horizontal_scrollbar_layer_->SetTotalSize(bounds_.width());
794 horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x());
795 }
796 if (vertical_scrollbar_layer_) {
797 vertical_scrollbar_layer_->SetCurrentPos(current_offset.y());
798 vertical_scrollbar_layer_->SetTotalSize(bounds_.height());
799 vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y());
800 }
801
802 if (current_offset == last_scroll_offset_)
803 return;
804 last_scroll_offset_ = current_offset;
805
806 if (scrollbar_animation_controller_) {
807 scrollbar_animation_controller_->didUpdateScrollOffset(
808 base::TimeTicks::Now());
809 }
810
811 // Get the current_offset_.y() value for a sanity-check on scrolling
812 // benchmark metrics. Specifically, we want to make sure
813 // BasicMouseWheelSmoothScrollGesture has proper scroll curves.
814 if (layer_tree_impl()->IsActiveTree()) {
815 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y());
816 }
817 }
818
819 void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) {
820 if (scroll_offset_ == scroll_offset)
821 return;
822
823 scroll_offset_ = scroll_offset;
824 NoteLayerPropertyChangedForSubtree();
825 UpdateScrollbarPositions();
826 }
827
828 void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) {
829 if (scroll_delta_ == scroll_delta)
830 return;
831
832 if (layer_tree_impl()->IsActiveTree()) {
833 LayerImpl* pending_twin = layer_tree_impl()->FindPendingTreeLayerById(id());
834 if (pending_twin) {
835 // The pending twin can't mirror the scroll delta of the active
836 // layer. Although the delta - sent scroll delta difference is
837 // identical for both twins, the sent scroll delta for the pending
838 // layer is zero, as anything that has been sent has been baked
839 // into the layer's position/scroll offset as a part of commit.
840 DCHECK(pending_twin->sent_scroll_delta().IsZero());
841 pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta());
244 } 842 }
245 843 }
246 if (!screenSpaceTransform().IsInvertible()) { 844
247 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored nonInvertibleTransform "); 845 scroll_delta_ = scroll_delta;
248 return InputHandlerClient::ScrollIgnored; 846 NoteLayerPropertyChangedForSubtree();
847
848 UpdateScrollbarPositions();
849 }
850
851 void LayerImpl::SetImplTransform(const gfx::Transform& transform) {
852 if (impl_transform_ == transform)
853 return;
854
855 impl_transform_ = transform;
856 NoteLayerPropertyChangedForSubtree();
857 }
858
859 void LayerImpl::SetDoubleSided(bool double_sided) {
860 if (double_sided_ == double_sided)
861 return;
862
863 double_sided_ = double_sided;
864 NoteLayerPropertyChangedForSubtree();
865 }
866
867 Region LayerImpl::VisibleContentOpaqueRegion() const {
868 if (contents_opaque())
869 return visible_content_rect();
870 return Region();
871 }
872
873 void LayerImpl::DidLoseOutputSurface() {}
874
875 void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) {
876 if (max_scroll_offset_ == max_scroll_offset)
877 return;
878 max_scroll_offset_ = max_scroll_offset;
879
880 layer_tree_impl()->set_needs_update_draw_properties();
881 UpdateScrollbarPositions();
882 }
883
884 void LayerImpl::SetScrollbarOpacity(float opacity) {
885 if (horizontal_scrollbar_layer_)
886 horizontal_scrollbar_layer_->SetOpacity(opacity);
887 if (vertical_scrollbar_layer_)
888 vertical_scrollbar_layer_->SetOpacity(opacity);
889 }
890
891 inline scoped_ptr<ScrollbarAnimationController>
892 CreateScrollbarAnimationControllerWithFade(LayerImpl* layer) {
893 double fadeout_delay = 0.3;
894 double fadeout_length = 0.3;
895 return ScrollbarAnimationControllerLinearFade::create(
896 layer, fadeout_delay, fadeout_length)
897 .PassAs<ScrollbarAnimationController>();
898 }
899
900 void LayerImpl::DidBecomeActive() {
901 if (!layer_tree_impl_->settings().useLinearFadeScrollbarAnimator)
902 return;
903
904 bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ ||
905 vertical_scrollbar_layer_;
906 if (need_scrollbar_animation_controller) {
907 if (!scrollbar_animation_controller_) {
908 scrollbar_animation_controller_ =
909 CreateScrollbarAnimationControllerWithFade(this);
249 } 910 }
250 911 } else {
251 if (!nonFastScrollableRegion().IsEmpty()) { 912 scrollbar_animation_controller_.reset();
252 bool clipped = false; 913 }
253 gfx::Transform inverseScreenSpaceTransform(gfx::Transform::kSkipInitiali zation); 914
254 if (!screenSpaceTransform().GetInverse(&inverseScreenSpaceTransform)) { 915 }
255 // TODO(shawnsingh): We shouldn't be applying a projection if screen space 916 void LayerImpl::SetHorizontalScrollbarLayer(
256 // transform is uninvertible here. Perhaps we should be returning 917 ScrollbarLayerImpl* scrollbar_layer) {
257 // ScrollOnMainThread in this case? 918 horizontal_scrollbar_layer_ = scrollbar_layer;
258 } 919 if (horizontal_scrollbar_layer_)
259 920 horizontal_scrollbar_layer_->set_scroll_layer_id(id());
260 gfx::PointF hitTestPointInContentSpace = MathUtil::projectPoint(inverseS creenSpaceTransform, screenSpacePoint, clipped); 921 }
261 gfx::PointF hitTestPointInLayerSpace = gfx::ScalePoint(hitTestPointInCon tentSpace, 1 / contentsScaleX(), 1 / contentsScaleY()); 922
262 if (!clipped && nonFastScrollableRegion().Contains(gfx::ToRoundedPoint(h itTestPointInLayerSpace))) { 923 void LayerImpl::SetVerticalScrollbarLayer(ScrollbarLayerImpl* scrollbar_layer) {
263 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed nonFastScrollableRe gion"); 924 vertical_scrollbar_layer_ = scrollbar_layer;
264 return InputHandlerClient::ScrollOnMainThread; 925 if (vertical_scrollbar_layer_)
265 } 926 vertical_scrollbar_layer_->set_scroll_layer_id(id());
266 } 927 }
267 928
268 if (type == InputHandlerClient::Wheel && haveWheelEventHandlers()) { 929 void LayerImpl::AsValueInto(base::DictionaryValue* dict) const {
269 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed wheelEventHandlers"); 930 dict->SetInteger("id", id());
270 return InputHandlerClient::ScrollOnMainThread; 931 dict->Set("bounds", MathUtil::asValue(bounds()).release());
271 } 932 dict->SetInteger("draws_content", DrawsContent());
272 933
273 if (!scrollable()) { 934 bool clipped;
274 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); 935 gfx::QuadF layer_quad = MathUtil::mapQuad(
275 return InputHandlerClient::ScrollIgnored; 936 screen_space_transform(),
276 } 937 gfx::QuadF(gfx::Rect(content_bounds())),
277 938 clipped);
278 if (m_maxScrollOffset.x() <= 0 && m_maxScrollOffset.y() <= 0) { 939 dict->Set("layer_quad", MathUtil::asValue(layer_quad).release());
279 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored. Technically scrollabl e, but has no affordance in either direction."); 940
280 return InputHandlerClient::ScrollIgnored; 941 }
281 } 942
282 943 scoped_ptr<base::Value> LayerImpl::AsValue() const {
283 return InputHandlerClient::ScrollStarted; 944 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
284 } 945 AsValueInto(state.get());
285 946 return state.PassAs<base::Value>();
286 bool LayerImpl::drawCheckerboardForMissingTiles() const
287 {
288 return m_drawCheckerboardForMissingTiles && !layerTreeImpl()->settings().bac kgroundColorInsteadOfCheckerboard;
289 }
290
291 gfx::Rect LayerImpl::layerRectToContentRect(const gfx::RectF& layerRect) const
292 {
293 gfx::RectF contentRect = gfx::ScaleRect(layerRect, contentsScaleX(), content sScaleY());
294 // Intersect with content rect to avoid the extra pixel because for some
295 // values x and y, ceil((x / y) * y) may be x + 1.
296 contentRect.Intersect(gfx::Rect(gfx::Point(), contentBounds()));
297 return gfx::ToEnclosingRect(contentRect);
298 }
299
300 skia::RefPtr<SkPicture> LayerImpl::getPicture()
301 {
302 return skia::RefPtr<SkPicture>();
303 }
304
305 bool LayerImpl::canClipSelf() const
306 {
307 return false;
308 }
309
310 bool LayerImpl::areVisibleResourcesReady() const
311 {
312 return true;
313 }
314
315 scoped_ptr<LayerImpl> LayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
316 {
317 return LayerImpl::create(treeImpl, m_layerId);
318 }
319
320 void LayerImpl::pushPropertiesTo(LayerImpl* layer)
321 {
322 layer->setAnchorPoint(m_anchorPoint);
323 layer->setAnchorPointZ(m_anchorPointZ);
324 layer->setBackgroundColor(m_backgroundColor);
325 layer->setBounds(m_bounds);
326 layer->setContentBounds(contentBounds());
327 layer->setContentsScale(contentsScaleX(), contentsScaleY());
328 layer->setDebugName(m_debugName);
329 layer->setDoubleSided(m_doubleSided);
330 layer->setDrawCheckerboardForMissingTiles(m_drawCheckerboardForMissingTiles) ;
331 layer->setForceRenderSurface(m_forceRenderSurface);
332 layer->setDrawsContent(drawsContent());
333 layer->setFilters(filters());
334 layer->setFilter(filter());
335 layer->setBackgroundFilters(backgroundFilters());
336 layer->setMasksToBounds(m_masksToBounds);
337 layer->setShouldScrollOnMainThread(m_shouldScrollOnMainThread);
338 layer->setHaveWheelEventHandlers(m_haveWheelEventHandlers);
339 layer->setNonFastScrollableRegion(m_nonFastScrollableRegion);
340 layer->setTouchEventHandlerRegion(m_touchEventHandlerRegion);
341 layer->setContentsOpaque(m_contentsOpaque);
342 if (!opacityIsAnimating())
343 layer->setOpacity(m_opacity);
344 layer->setPosition(m_position);
345 layer->setIsContainerForFixedPositionLayers(m_isContainerForFixedPositionLay ers);
346 layer->setFixedToContainerLayer(m_fixedToContainerLayer);
347 layer->setPreserves3D(preserves3D());
348 layer->setUseParentBackfaceVisibility(m_useParentBackfaceVisibility);
349 layer->setSublayerTransform(m_sublayerTransform);
350 if (!transformIsAnimating())
351 layer->setTransform(m_transform);
352
353 layer->setScrollable(m_scrollable);
354 layer->setScrollOffset(m_scrollOffset);
355 layer->setMaxScrollOffset(m_maxScrollOffset);
356
357 // If the main thread commits multiple times before the impl thread actually draws, then damage tracking
358 // will become incorrect if we simply clobber the updateRect here. The Layer Impl's updateRect needs to
359 // accumulate (i.e. union) any update changes that have occurred on the main thread.
360 m_updateRect.Union(layer->updateRect());
361 layer->setUpdateRect(m_updateRect);
362
363 layer->setScrollDelta(layer->scrollDelta() - layer->sentScrollDelta());
364 layer->setSentScrollDelta(gfx::Vector2d());
365
366 layer->setStackingOrderChanged(m_stackingOrderChanged);
367
368 m_layerAnimationController->PushAnimationUpdatesTo(layer->layerAnimationCont roller());
369
370 // Reset any state that should be cleared for the next update.
371 m_stackingOrderChanged = false;
372 m_updateRect = gfx::RectF();
373 }
374
375 std::string LayerImpl::indentString(int indent)
376 {
377 std::string str;
378 for (int i = 0; i != indent; ++i)
379 str.append(" ");
380 return str;
381 }
382
383 void LayerImpl::dumpLayerProperties(std::string* str, int indent) const
384 {
385 std::string indentStr = indentString(indent);
386 str->append(indentStr);
387 base::StringAppendF(str, "layer ID: %d\n", m_layerId);
388
389 str->append(indentStr);
390 base::StringAppendF(str, "bounds: %d, %d\n", bounds().width(), bounds().heig ht());
391
392 if (m_drawProperties.render_target) {
393 str->append(indentStr);
394 base::StringAppendF(str, "renderTarget: %d\n", m_drawProperties.render_t arget->m_layerId);
395 }
396
397 str->append(indentStr);
398 base::StringAppendF(str, "position: %f, %f\n", m_position.x(), m_position.y( ));
399
400 str->append(indentStr);
401 base::StringAppendF(str, "contentsOpaque: %d\n", m_contentsOpaque);
402
403 str->append(indentStr);
404 const gfx::Transform& transform = m_drawProperties.target_space_transform;
405 base::StringAppendF(str, "drawTransform: %f, %f, %f, %f // %f, %f, %f, %f // %f, %f, %f, %f // %f, %f, %f, %f\n",
406 transform.matrix().getDouble(0, 0), transform.matrix().getDouble(0, 1), transform.matrix().getDouble(0, 2), transform.matrix().getDouble(0, 3),
407 transform.matrix().getDouble(1, 0), transform.matrix().getDouble(1, 1), transform.matrix().getDouble(1, 2), transform.matrix().getDouble(1, 3),
408 transform.matrix().getDouble(2, 0), transform.matrix().getDouble(2, 1), transform.matrix().getDouble(2, 2), transform.matrix().getDouble(2, 3),
409 transform.matrix().getDouble(3, 0), transform.matrix().getDouble(3, 1), transform.matrix().getDouble(3, 2), transform.matrix().getDouble(3, 3));
410
411 str->append(indentStr);
412 base::StringAppendF(str, "drawsContent: %s\n", m_drawsContent ? "yes" : "no" );
413 }
414
415 std::string LayerImpl::layerTreeAsText() const
416 {
417 std::string str;
418 dumpLayer(&str, 0);
419 return str;
420 }
421
422 void LayerImpl::dumpLayer(std::string* str, int indent) const
423 {
424 str->append(indentString(indent));
425 base::StringAppendF(str, "%s(%s)\n", layerTypeAsString(), m_debugName.data() );
426 dumpLayerProperties(str, indent+2);
427 if (m_replicaLayer) {
428 str->append(indentString(indent+2));
429 str->append("Replica:\n");
430 m_replicaLayer->dumpLayer(str, indent+3);
431 }
432 if (m_maskLayer) {
433 str->append(indentString(indent+2));
434 str->append("Mask:\n");
435 m_maskLayer->dumpLayer(str, indent+3);
436 }
437 for (size_t i = 0; i < m_children.size(); ++i)
438 m_children[i]->dumpLayer(str, indent+1);
439 }
440
441 base::DictionaryValue* LayerImpl::layerTreeAsJson() const
442 {
443 base::ListValue* list;
444 base::DictionaryValue* result = new base::DictionaryValue;
445 result->SetString("LayerType", layerTypeAsString());
446
447 list = new base::ListValue;
448 list->AppendInteger(bounds().width());
449 list->AppendInteger(bounds().height());
450 result->Set("Bounds", list);
451
452 list = new base::ListValue;
453 list->AppendDouble(m_position.x());
454 list->AppendDouble(m_position.y());
455 result->Set("Position", list);
456
457 const gfx::Transform& gfxTransform = m_drawProperties.target_space_transform ;
458 double transform[16];
459 gfxTransform.matrix().asColMajord(transform);
460 list = new base::ListValue;
461 for (int i = 0; i < 16; ++i)
462 list->AppendDouble(transform[i]);
463 result->Set("DrawTransform", list);
464
465 result->SetBoolean("DrawsContent", m_drawsContent);
466 result->SetDouble("Opacity", opacity());
467
468 list = new base::ListValue;
469 for (size_t i = 0; i < m_children.size(); ++i)
470 list->Append(m_children[i]->layerTreeAsJson());
471 result->Set("Children", list);
472
473 return result;
474 }
475
476 void LayerImpl::setStackingOrderChanged(bool stackingOrderChanged)
477 {
478 if (stackingOrderChanged) {
479 m_stackingOrderChanged = true;
480 noteLayerPropertyChangedForSubtree();
481 }
482 }
483
484 bool LayerImpl::layerSurfacePropertyChanged() const
485 {
486 if (m_layerSurfacePropertyChanged)
487 return true;
488
489 // If this layer's surface property hasn't changed, we want to see if
490 // some layer above us has changed this property. This is done for the
491 // case when such parent layer does not draw content, and therefore will
492 // not be traversed by the damage tracker. We need to make sure that
493 // property change on such layer will be caught by its descendants.
494 LayerImpl* current = this->m_parent;
495 while (current && !current->m_drawProperties.render_surface) {
496 if (current->m_layerSurfacePropertyChanged)
497 return true;
498 current = current->m_parent;
499 }
500
501 return false;
502 }
503
504 void LayerImpl::noteLayerSurfacePropertyChanged()
505 {
506 m_layerSurfacePropertyChanged = true;
507 layerTreeImpl()->set_needs_update_draw_properties();
508 }
509
510 void LayerImpl::noteLayerPropertyChanged()
511 {
512 m_layerPropertyChanged = true;
513 layerTreeImpl()->set_needs_update_draw_properties();
514 }
515
516 void LayerImpl::noteLayerPropertyChangedForSubtree()
517 {
518 noteLayerPropertyChanged();
519 noteLayerPropertyChangedForDescendants();
520 }
521
522 void LayerImpl::noteLayerPropertyChangedForDescendants()
523 {
524 layerTreeImpl()->set_needs_update_draw_properties();
525 for (size_t i = 0; i < m_children.size(); ++i)
526 m_children[i]->noteLayerPropertyChangedForSubtree();
527 }
528
529 const char* LayerImpl::layerTypeAsString() const
530 {
531 return "Layer";
532 }
533
534 void LayerImpl::resetAllChangeTrackingForSubtree()
535 {
536 m_layerPropertyChanged = false;
537 m_layerSurfacePropertyChanged = false;
538
539 m_updateRect = gfx::RectF();
540
541 if (m_drawProperties.render_surface)
542 m_drawProperties.render_surface->ResetPropertyChangedFlag();
543
544 if (m_maskLayer)
545 m_maskLayer->resetAllChangeTrackingForSubtree();
546
547 if (m_replicaLayer)
548 m_replicaLayer->resetAllChangeTrackingForSubtree(); // also resets the r eplica mask, if it exists.
549
550 for (size_t i = 0; i < m_children.size(); ++i)
551 m_children[i]->resetAllChangeTrackingForSubtree();
552 }
553
554 bool LayerImpl::layerIsAlwaysDamaged() const
555 {
556 return false;
557 }
558
559 int LayerImpl::id() const
560 {
561 return m_layerId;
562 }
563
564 void LayerImpl::OnOpacityAnimated(float opacity)
565 {
566 setOpacity(opacity);
567 }
568
569 void LayerImpl::OnTransformAnimated(const gfx::Transform& transform)
570 {
571 setTransform(transform);
572 }
573
574 bool LayerImpl::IsActive() const
575 {
576 return m_layerTreeImpl->IsActiveTree();
577 }
578
579 void LayerImpl::setBounds(const gfx::Size& bounds)
580 {
581 if (m_bounds == bounds)
582 return;
583
584 m_bounds = bounds;
585
586 if (masksToBounds())
587 noteLayerPropertyChangedForSubtree();
588 else
589 noteLayerPropertyChanged();
590 }
591
592 void LayerImpl::setMaskLayer(scoped_ptr<LayerImpl> maskLayer)
593 {
594 int newLayerId = maskLayer ? maskLayer->id() : -1;
595
596 if (maskLayer) {
597 DCHECK_EQ(layerTreeImpl(), maskLayer->layerTreeImpl());
598 DCHECK_NE(newLayerId, m_maskLayerId);
599 } else if (newLayerId == m_maskLayerId)
600 return;
601
602 m_maskLayer = maskLayer.Pass();
603 m_maskLayerId = newLayerId;
604 if (m_maskLayer)
605 m_maskLayer->setParent(this);
606 noteLayerPropertyChangedForSubtree();
607 }
608
609 scoped_ptr<LayerImpl> LayerImpl::takeMaskLayer()
610 {
611 m_maskLayerId = -1;
612 return m_maskLayer.Pass();
613 }
614
615 void LayerImpl::setReplicaLayer(scoped_ptr<LayerImpl> replicaLayer)
616 {
617 int newLayerId = replicaLayer ? replicaLayer->id() : -1;
618
619 if (replicaLayer) {
620 DCHECK_EQ(layerTreeImpl(), replicaLayer->layerTreeImpl());
621 DCHECK_NE(newLayerId, m_replicaLayerId);
622 } else if (newLayerId == m_replicaLayerId)
623 return;
624
625 m_replicaLayer = replicaLayer.Pass();
626 m_replicaLayerId = newLayerId;
627 if (m_replicaLayer)
628 m_replicaLayer->setParent(this);
629 noteLayerPropertyChangedForSubtree();
630 }
631
632 scoped_ptr<LayerImpl> LayerImpl::takeReplicaLayer()
633 {
634 m_replicaLayerId = -1;
635 return m_replicaLayer.Pass();
636 }
637
638 ScrollbarLayerImpl* LayerImpl::toScrollbarLayer()
639 {
640 return 0;
641 }
642
643 void LayerImpl::setDrawsContent(bool drawsContent)
644 {
645 if (m_drawsContent == drawsContent)
646 return;
647
648 m_drawsContent = drawsContent;
649 noteLayerPropertyChanged();
650 }
651
652 void LayerImpl::setAnchorPoint(const gfx::PointF& anchorPoint)
653 {
654 if (m_anchorPoint == anchorPoint)
655 return;
656
657 m_anchorPoint = anchorPoint;
658 noteLayerPropertyChangedForSubtree();
659 }
660
661 void LayerImpl::setAnchorPointZ(float anchorPointZ)
662 {
663 if (m_anchorPointZ == anchorPointZ)
664 return;
665
666 m_anchorPointZ = anchorPointZ;
667 noteLayerPropertyChangedForSubtree();
668 }
669
670 void LayerImpl::setBackgroundColor(SkColor backgroundColor)
671 {
672 if (m_backgroundColor == backgroundColor)
673 return;
674
675 m_backgroundColor = backgroundColor;
676 noteLayerPropertyChanged();
677 }
678
679 void LayerImpl::setFilters(const WebKit::WebFilterOperations& filters)
680 {
681 if (m_filters == filters)
682 return;
683
684 DCHECK(!m_filter);
685 m_filters = filters;
686 noteLayerPropertyChangedForSubtree();
687 }
688
689 void LayerImpl::setBackgroundFilters(const WebKit::WebFilterOperations& backgrou ndFilters)
690 {
691 if (m_backgroundFilters == backgroundFilters)
692 return;
693
694 m_backgroundFilters = backgroundFilters;
695 noteLayerPropertyChanged();
696 }
697
698 void LayerImpl::setFilter(const skia::RefPtr<SkImageFilter>& filter)
699 {
700 if (m_filter.get() == filter.get())
701 return;
702
703 DCHECK(m_filters.isEmpty());
704 m_filter = filter;
705 noteLayerPropertyChangedForSubtree();
706 }
707
708 void LayerImpl::setMasksToBounds(bool masksToBounds)
709 {
710 if (m_masksToBounds == masksToBounds)
711 return;
712
713 m_masksToBounds = masksToBounds;
714 noteLayerPropertyChangedForSubtree();
715 }
716
717 void LayerImpl::setContentsOpaque(bool opaque)
718 {
719 if (m_contentsOpaque == opaque)
720 return;
721
722 m_contentsOpaque = opaque;
723 noteLayerPropertyChangedForSubtree();
724 }
725
726 void LayerImpl::setOpacity(float opacity)
727 {
728 if (m_opacity == opacity)
729 return;
730
731 m_opacity = opacity;
732 noteLayerSurfacePropertyChanged();
733 }
734
735 float LayerImpl::opacity() const
736 {
737 return m_opacity;
738 }
739
740 bool LayerImpl::opacityIsAnimating() const
741 {
742 return m_layerAnimationController->IsAnimatingProperty(Animation::Opacity);
743 }
744
745 void LayerImpl::setPosition(const gfx::PointF& position)
746 {
747 if (m_position == position)
748 return;
749
750 m_position = position;
751 noteLayerPropertyChangedForSubtree();
752 }
753
754 void LayerImpl::setPreserves3D(bool preserves3D)
755 {
756 if (m_preserves3D == preserves3D)
757 return;
758
759 m_preserves3D = preserves3D;
760 noteLayerPropertyChangedForSubtree();
761 }
762
763 void LayerImpl::setSublayerTransform(const gfx::Transform& sublayerTransform)
764 {
765 if (m_sublayerTransform == sublayerTransform)
766 return;
767
768 m_sublayerTransform = sublayerTransform;
769 // sublayer transform does not affect the current layer; it affects only its children.
770 noteLayerPropertyChangedForDescendants();
771 }
772
773 void LayerImpl::setTransform(const gfx::Transform& transform)
774 {
775 if (m_transform == transform)
776 return;
777
778 m_transform = transform;
779 noteLayerSurfacePropertyChanged();
780 }
781
782 const gfx::Transform& LayerImpl::transform() const
783 {
784 return m_transform;
785 }
786
787 bool LayerImpl::transformIsAnimating() const
788 {
789 return m_layerAnimationController->IsAnimatingProperty(Animation::Transform) ;
790 }
791
792 void LayerImpl::setContentBounds(const gfx::Size& contentBounds)
793 {
794 if (this->contentBounds() == contentBounds)
795 return;
796
797 m_drawProperties.content_bounds = contentBounds;
798 noteLayerPropertyChanged();
799 }
800
801 void LayerImpl::setContentsScale(float contentsScaleX, float contentsScaleY)
802 {
803 if (this->contentsScaleX() == contentsScaleX && this->contentsScaleY() == co ntentsScaleY)
804 return;
805
806 m_drawProperties.contents_scale_x = contentsScaleX;
807 m_drawProperties.contents_scale_y = contentsScaleY;
808 noteLayerPropertyChanged();
809 }
810
811 void LayerImpl::calculateContentsScale(
812 float idealContentsScale,
813 bool animatingTransformToScreen,
814 float* contentsScaleX,
815 float* contentsScaleY,
816 gfx::Size* contentBounds)
817 {
818 // Base LayerImpl has all of its content scales and content bounds pushed
819 // from its Layer during commit and just reuses those values as-is.
820 *contentsScaleX = this->contentsScaleX();
821 *contentsScaleY = this->contentsScaleY();
822 *contentBounds = this->contentBounds();
823 }
824
825 void LayerImpl::updateScrollbarPositions()
826 {
827 gfx::Vector2dF currentOffset = m_scrollOffset + m_scrollDelta;
828
829 if (m_horizontalScrollbarLayer) {
830 m_horizontalScrollbarLayer->SetCurrentPos(currentOffset.x());
831 m_horizontalScrollbarLayer->SetTotalSize(m_bounds.width());
832 m_horizontalScrollbarLayer->SetMaximum(m_maxScrollOffset.x());
833 }
834 if (m_verticalScrollbarLayer) {
835 m_verticalScrollbarLayer->SetCurrentPos(currentOffset.y());
836 m_verticalScrollbarLayer->SetTotalSize(m_bounds.height());
837 m_verticalScrollbarLayer->SetMaximum(m_maxScrollOffset.y());
838 }
839
840 if (currentOffset == m_lastScrollOffset)
841 return;
842 m_lastScrollOffset = currentOffset;
843
844 if (m_scrollbarAnimationController)
845 m_scrollbarAnimationController->didUpdateScrollOffset(base::TimeTicks::N ow());
846
847 // Get the m_currentOffset.y() value for a sanity-check on scrolling
848 // benchmark metrics. Specifically, we want to make sure
849 // BasicMouseWheelSmoothScrollGesture has proper scroll curves.
850 if (layerTreeImpl()->IsActiveTree()) {
851 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), currentOffset.y( ));
852 }
853 }
854
855 void LayerImpl::setScrollOffset(gfx::Vector2d scrollOffset)
856 {
857 if (m_scrollOffset == scrollOffset)
858 return;
859
860 m_scrollOffset = scrollOffset;
861 noteLayerPropertyChangedForSubtree();
862 updateScrollbarPositions();
863 }
864
865 void LayerImpl::setScrollDelta(const gfx::Vector2dF& scrollDelta)
866 {
867 if (m_scrollDelta == scrollDelta)
868 return;
869
870 if (layerTreeImpl()->IsActiveTree())
871 {
872 LayerImpl* pending_twin = layerTreeImpl()->FindPendingTreeLayerById(id() );
873 if (pending_twin) {
874 // The pending twin can't mirror the scroll delta of the active
875 // layer. Although the delta - sent scroll delta difference is
876 // identical for both twins, the sent scroll delta for the pending
877 // layer is zero, as anything that has been sent has been baked
878 // into the layer's position/scroll offset as a part of commit.
879 DCHECK(pending_twin->sentScrollDelta().IsZero());
880 pending_twin->setScrollDelta(scrollDelta - sentScrollDelta());
881 }
882 }
883
884 m_scrollDelta = scrollDelta;
885 noteLayerPropertyChangedForSubtree();
886
887 updateScrollbarPositions();
888 }
889
890 void LayerImpl::setImplTransform(const gfx::Transform& transform)
891 {
892 if (m_implTransform == transform)
893 return;
894
895 m_implTransform = transform;
896 noteLayerPropertyChangedForSubtree();
897 }
898
899 void LayerImpl::setDoubleSided(bool doubleSided)
900 {
901 if (m_doubleSided == doubleSided)
902 return;
903
904 m_doubleSided = doubleSided;
905 noteLayerPropertyChangedForSubtree();
906 }
907
908 Region LayerImpl::visibleContentOpaqueRegion() const
909 {
910 if (contentsOpaque())
911 return visibleContentRect();
912 return Region();
913 }
914
915 void LayerImpl::didLoseOutputSurface()
916 {
917 }
918
919 void LayerImpl::setMaxScrollOffset(gfx::Vector2d maxScrollOffset)
920 {
921 if (m_maxScrollOffset == maxScrollOffset)
922 return;
923 m_maxScrollOffset = maxScrollOffset;
924
925 layerTreeImpl()->set_needs_update_draw_properties();
926 updateScrollbarPositions();
927 }
928
929 void LayerImpl::setScrollbarOpacity(float opacity)
930 {
931 if (m_horizontalScrollbarLayer)
932 m_horizontalScrollbarLayer->setOpacity(opacity);
933 if (m_verticalScrollbarLayer)
934 m_verticalScrollbarLayer->setOpacity(opacity);
935 }
936
937 inline scoped_ptr<ScrollbarAnimationController> createScrollbarAnimationControll erWithFade(LayerImpl* layer)
938 {
939 double fadeoutDelay = 0.3;
940 double fadeoutLength = 0.3;
941 return ScrollbarAnimationControllerLinearFade::create(layer, fadeoutDelay, f adeoutLength).PassAs<ScrollbarAnimationController>();
942 }
943
944 void LayerImpl::didBecomeActive()
945 {
946 if (!m_layerTreeImpl->settings().useLinearFadeScrollbarAnimator)
947 return;
948
949 bool needScrollbarAnimationController = m_horizontalScrollbarLayer || m_vert icalScrollbarLayer;
950 if (needScrollbarAnimationController) {
951 if (!m_scrollbarAnimationController)
952 m_scrollbarAnimationController = createScrollbarAnimationControllerW ithFade(this);
953 } else {
954 m_scrollbarAnimationController.reset();
955 }
956
957 }
958 void LayerImpl::setHorizontalScrollbarLayer(ScrollbarLayerImpl* scrollbarLayer)
959 {
960 m_horizontalScrollbarLayer = scrollbarLayer;
961 if (m_horizontalScrollbarLayer)
962 m_horizontalScrollbarLayer->set_scroll_layer_id(id());
963 }
964
965 void LayerImpl::setVerticalScrollbarLayer(ScrollbarLayerImpl* scrollbarLayer)
966 {
967 m_verticalScrollbarLayer = scrollbarLayer;
968 if (m_verticalScrollbarLayer)
969 m_verticalScrollbarLayer->set_scroll_layer_id(id());
970 }
971
972 void LayerImpl::AsValueInto(base::DictionaryValue* dict) const
973 {
974 dict->SetInteger("id", id());
975 dict->Set("bounds", MathUtil::asValue(bounds()).release());
976 dict->SetInteger("draws_content", drawsContent());
977
978 bool clipped;
979 gfx::QuadF layer_quad = MathUtil::mapQuad(
980 screenSpaceTransform(),
981 gfx::QuadF(gfx::Rect(contentBounds())),
982 clipped);
983 dict->Set("layer_quad", MathUtil::asValue(layer_quad).release());
984
985 }
986
987 scoped_ptr<base::Value> LayerImpl::AsValue() const
988 {
989 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
990 AsValueInto(state.get());
991 return state.PassAs<base::Value>();
992 } 947 }
993 948
994 } // namespace cc 949 } // namespace cc
OLDNEW
« cc/layer_impl.h ('K') | « 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