Disable StorageInfoProviderTest.* on Valgrind bots.
[chromium-blink-merge.git] / cc / layer_impl.cc
blobf87a622ea5f471a907c3ca9635fda443a9dbd8ff
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/layer_impl.h"
7 #include "base/debug/trace_event.h"
8 #include "base/stringprintf.h"
9 #include "cc/debug_border_draw_quad.h"
10 #include "cc/debug_colors.h"
11 #include "cc/layer_sorter.h"
12 #include "cc/layer_tree_host_impl.h"
13 #include "cc/math_util.h"
14 #include "cc/proxy.h"
15 #include "cc/quad_sink.h"
16 #include "cc/scrollbar_animation_controller.h"
17 #include "ui/gfx/point_conversions.h"
18 #include "ui/gfx/rect_conversions.h"
20 namespace cc {
22 LayerImpl::LayerImpl(int id)
23 : m_parent(0)
24 , m_maskLayerId(-1)
25 , m_replicaLayerId(-1)
26 , m_layerId(id)
27 , m_layerTreeHostImpl(0)
28 , m_anchorPoint(0.5, 0.5)
29 , m_anchorPointZ(0)
30 , m_contentsScaleX(1.0)
31 , m_contentsScaleY(1.0)
32 , m_scrollable(false)
33 , m_shouldScrollOnMainThread(false)
34 , m_haveWheelEventHandlers(false)
35 , m_backgroundColor(0)
36 , m_doubleSided(true)
37 , m_layerPropertyChanged(false)
38 , m_layerSurfacePropertyChanged(false)
39 , m_masksToBounds(false)
40 , m_contentsOpaque(false)
41 , m_opacity(1.0)
42 , m_preserves3D(false)
43 , m_useParentBackfaceVisibility(false)
44 , m_drawCheckerboardForMissingTiles(false)
45 , m_useLCDText(false)
46 , m_drawsContent(false)
47 , m_forceRenderSurface(false)
48 , m_isContainerForFixedPositionLayers(false)
49 , m_fixedToContainerLayer(false)
50 , m_drawDepth(0)
51 #ifndef NDEBUG
52 , m_betweenWillDrawAndDidDraw(false)
53 #endif
54 , m_layerAnimationController(LayerAnimationController::create(this))
56 DCHECK(m_layerId > 0);
59 LayerImpl::~LayerImpl()
61 #ifndef NDEBUG
62 DCHECK(!m_betweenWillDrawAndDidDraw);
63 #endif
66 void LayerImpl::addChild(scoped_ptr<LayerImpl> child)
68 child->setParent(this);
69 m_children.append(child.Pass());
72 void LayerImpl::removeFromParent()
74 if (!m_parent)
75 return;
77 LayerImpl* parent = m_parent;
78 m_parent = 0;
80 for (size_t i = 0; i < parent->m_children.size(); ++i) {
81 if (parent->m_children[i] == this) {
82 parent->m_children.remove(i);
83 return;
88 void LayerImpl::removeAllChildren()
90 while (m_children.size())
91 m_children[0]->removeFromParent();
94 void LayerImpl::clearChildList()
96 m_children.clear();
99 void LayerImpl::createRenderSurface()
101 DCHECK(!m_drawProperties.render_surface);
102 m_drawProperties.render_surface = make_scoped_ptr(new RenderSurfaceImpl(this));
103 m_drawProperties.render_target = this;
106 int LayerImpl::descendantsDrawContent()
108 int result = 0;
109 for (size_t i = 0; i < m_children.size(); ++i) {
110 if (m_children[i]->drawsContent())
111 ++result;
112 result += m_children[i]->descendantsDrawContent();
113 if (result > 1)
114 return result;
116 return result;
119 scoped_ptr<SharedQuadState> LayerImpl::createSharedQuadState() const
121 scoped_ptr<SharedQuadState> state = SharedQuadState::Create();
122 state->SetAll(m_drawProperties.target_space_transform,
123 m_drawProperties.visible_content_rect,
124 m_drawProperties.drawable_content_rect,
125 m_drawProperties.clip_rect,
126 m_drawProperties.is_clipped,
127 m_drawProperties.opacity);
128 return state.Pass();
131 void LayerImpl::willDraw(ResourceProvider*)
133 #ifndef NDEBUG
134 // willDraw/didDraw must be matched.
135 DCHECK(!m_betweenWillDrawAndDidDraw);
136 m_betweenWillDrawAndDidDraw = true;
137 #endif
140 void LayerImpl::didDraw(ResourceProvider*)
142 #ifndef NDEBUG
143 DCHECK(m_betweenWillDrawAndDidDraw);
144 m_betweenWillDrawAndDidDraw = false;
145 #endif
148 bool LayerImpl::showDebugBorders() const
150 if (!m_layerTreeHostImpl)
151 return false;
152 return m_layerTreeHostImpl->debugState().showDebugBorders;
155 void LayerImpl::getDebugBorderProperties(SkColor* color, float* width) const
157 if (m_drawsContent) {
158 *color = DebugColors::ContentLayerBorderColor();
159 *width = DebugColors::ContentLayerBorderWidth(m_layerTreeHostImpl);
160 return;
163 if (m_masksToBounds) {
164 *color = DebugColors::MaskingLayerBorderColor();
165 *width = DebugColors::MaskingLayerBorderWidth(m_layerTreeHostImpl);
166 return;
169 *color = DebugColors::ContainerLayerBorderColor();
170 *width = DebugColors::ContainerLayerBorderWidth(m_layerTreeHostImpl);
173 void LayerImpl::appendDebugBorderQuad(QuadSink& quadList, const SharedQuadState* sharedQuadState, AppendQuadsData& appendQuadsData) const
175 if (!showDebugBorders())
176 return;
178 SkColor color;
179 float width;
180 getDebugBorderProperties(&color, &width);
182 gfx::Rect contentRect(gfx::Point(), contentBounds());
183 scoped_ptr<DebugBorderDrawQuad> debugBorderQuad = DebugBorderDrawQuad::Create();
184 debugBorderQuad->SetNew(sharedQuadState, contentRect, color, width);
185 quadList.append(debugBorderQuad.PassAs<DrawQuad>(), appendQuadsData);
188 bool LayerImpl::hasContributingDelegatedRenderPasses() const
190 return false;
193 RenderPass::Id LayerImpl::firstContributingRenderPassId() const
195 return RenderPass::Id(0, 0);
198 RenderPass::Id LayerImpl::nextContributingRenderPassId(RenderPass::Id) const
200 return RenderPass::Id(0, 0);
203 ResourceProvider::ResourceId LayerImpl::contentsResourceId() const
205 NOTREACHED();
206 return 0;
209 gfx::Vector2dF LayerImpl::scrollBy(const gfx::Vector2dF& scroll)
211 gfx::Vector2dF minDelta = -m_scrollOffset;
212 gfx::Vector2dF maxDelta = m_maxScrollOffset - m_scrollOffset;
213 // Clamp newDelta so that position + delta stays within scroll bounds.
214 gfx::Vector2dF newDelta = (m_scrollDelta + scroll);
215 newDelta.ClampToMin(minDelta);
216 newDelta.ClampToMax(maxDelta);
217 gfx::Vector2dF unscrolled = m_scrollDelta + scroll - newDelta;
219 if (m_scrollDelta == newDelta)
220 return unscrolled;
222 m_scrollDelta = newDelta;
223 if (m_scrollbarAnimationController)
224 m_scrollbarAnimationController->updateScrollOffset(this);
225 noteLayerPropertyChangedForSubtree();
227 return unscrolled;
230 InputHandlerClient::ScrollStatus LayerImpl::tryScroll(const gfx::PointF& screenSpacePoint, InputHandlerClient::ScrollInputType type) const
232 if (shouldScrollOnMainThread()) {
233 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed shouldScrollOnMainThread");
234 return InputHandlerClient::ScrollOnMainThread;
237 if (!screenSpaceTransform().IsInvertible()) {
238 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored nonInvertibleTransform");
239 return InputHandlerClient::ScrollIgnored;
242 if (!nonFastScrollableRegion().IsEmpty()) {
243 bool clipped = false;
244 gfx::PointF hitTestPointInContentSpace = MathUtil::projectPoint(MathUtil::inverse(screenSpaceTransform()), screenSpacePoint, clipped);
245 gfx::PointF hitTestPointInLayerSpace = gfx::ScalePoint(hitTestPointInContentSpace, 1 / contentsScaleX(), 1 / contentsScaleY());
246 if (!clipped && nonFastScrollableRegion().Contains(gfx::ToRoundedPoint(hitTestPointInLayerSpace))) {
247 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed nonFastScrollableRegion");
248 return InputHandlerClient::ScrollOnMainThread;
252 if (type == InputHandlerClient::Wheel && haveWheelEventHandlers()) {
253 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed wheelEventHandlers");
254 return InputHandlerClient::ScrollOnMainThread;
257 if (!scrollable()) {
258 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable");
259 return InputHandlerClient::ScrollIgnored;
262 return InputHandlerClient::ScrollStarted;
265 bool LayerImpl::drawCheckerboardForMissingTiles() const
267 return m_drawCheckerboardForMissingTiles && !m_layerTreeHostImpl->settings().backgroundColorInsteadOfCheckerboard;
270 gfx::Rect LayerImpl::layerRectToContentRect(const gfx::RectF& layerRect) const
272 gfx::RectF contentRect = gfx::ScaleRect(layerRect, contentsScaleX(), contentsScaleY());
273 // Intersect with content rect to avoid the extra pixel because for some
274 // values x and y, ceil((x / y) * y) may be x + 1.
275 contentRect.Intersect(gfx::Rect(gfx::Point(), contentBounds()));
276 return gfx::ToEnclosingRect(contentRect);
279 std::string LayerImpl::indentString(int indent)
281 std::string str;
282 for (int i = 0; i != indent; ++i)
283 str.append(" ");
284 return str;
287 void LayerImpl::dumpLayerProperties(std::string* str, int indent) const
289 std::string indentStr = indentString(indent);
290 str->append(indentStr);
291 base::StringAppendF(str, "layer ID: %d\n", m_layerId);
293 str->append(indentStr);
294 base::StringAppendF(str, "bounds: %d, %d\n", bounds().width(), bounds().height());
296 if (m_drawProperties.render_target) {
297 str->append(indentStr);
298 base::StringAppendF(str, "renderTarget: %d\n", m_drawProperties.render_target->m_layerId);
301 str->append(indentStr);
302 base::StringAppendF(str, "position: %f, %f\n", m_position.x(), m_position.y());
304 str->append(indentStr);
305 base::StringAppendF(str, "contentsOpaque: %d\n", m_contentsOpaque);
307 str->append(indentStr);
308 const gfx::Transform& transform = m_drawProperties.target_space_transform;
309 base::StringAppendF(str, "drawTransform: %f, %f, %f, %f // %f, %f, %f, %f // %f, %f, %f, %f // %f, %f, %f, %f\n",
310 transform.matrix().getDouble(0, 0), transform.matrix().getDouble(0, 1), transform.matrix().getDouble(0, 2), transform.matrix().getDouble(0, 3),
311 transform.matrix().getDouble(1, 0), transform.matrix().getDouble(1, 1), transform.matrix().getDouble(1, 2), transform.matrix().getDouble(1, 3),
312 transform.matrix().getDouble(2, 0), transform.matrix().getDouble(2, 1), transform.matrix().getDouble(2, 2), transform.matrix().getDouble(2, 3),
313 transform.matrix().getDouble(3, 0), transform.matrix().getDouble(3, 1), transform.matrix().getDouble(3, 2), transform.matrix().getDouble(3, 3));
315 str->append(indentStr);
316 base::StringAppendF(str, "drawsContent: %s\n", m_drawsContent ? "yes" : "no");
319 void sortLayers(std::vector<LayerImpl*>::iterator first, std::vector<LayerImpl*>::iterator end, LayerSorter* layerSorter)
321 TRACE_EVENT0("cc", "LayerImpl::sortLayers");
322 layerSorter->sort(first, end);
325 std::string LayerImpl::layerTreeAsText() const
327 std::string str;
328 dumpLayer(&str, 0);
329 return str;
332 void LayerImpl::dumpLayer(std::string* str, int indent) const
334 str->append(indentString(indent));
335 base::StringAppendF(str, "%s(%s)\n", layerTypeAsString(), m_debugName.data());
336 dumpLayerProperties(str, indent+2);
337 if (m_replicaLayer) {
338 str->append(indentString(indent+2));
339 str->append("Replica:\n");
340 m_replicaLayer->dumpLayer(str, indent+3);
342 if (m_maskLayer) {
343 str->append(indentString(indent+2));
344 str->append("Mask:\n");
345 m_maskLayer->dumpLayer(str, indent+3);
347 for (size_t i = 0; i < m_children.size(); ++i)
348 m_children[i]->dumpLayer(str, indent+1);
351 void LayerImpl::setStackingOrderChanged(bool stackingOrderChanged)
353 // We don't need to store this flag; we only need to track that the change occurred.
354 if (stackingOrderChanged)
355 noteLayerPropertyChangedForSubtree();
358 bool LayerImpl::layerSurfacePropertyChanged() const
360 if (m_layerSurfacePropertyChanged)
361 return true;
363 // If this layer's surface property hasn't changed, we want to see if
364 // some layer above us has changed this property. This is done for the
365 // case when such parent layer does not draw content, and therefore will
366 // not be traversed by the damage tracker. We need to make sure that
367 // property change on such layer will be caught by its descendants.
368 LayerImpl* current = this->m_parent;
369 while (current && !current->m_drawProperties.render_surface) {
370 if (current->m_layerSurfacePropertyChanged)
371 return true;
372 current = current->m_parent;
375 return false;
378 void LayerImpl::noteLayerPropertyChangedForSubtree()
380 m_layerPropertyChanged = true;
381 noteLayerPropertyChangedForDescendants();
384 void LayerImpl::noteLayerPropertyChangedForDescendants()
386 for (size_t i = 0; i < m_children.size(); ++i)
387 m_children[i]->noteLayerPropertyChangedForSubtree();
390 const char* LayerImpl::layerTypeAsString() const
392 return "Layer";
395 void LayerImpl::resetAllChangeTrackingForSubtree()
397 m_layerPropertyChanged = false;
398 m_layerSurfacePropertyChanged = false;
400 m_updateRect = gfx::RectF();
402 if (m_drawProperties.render_surface)
403 m_drawProperties.render_surface->resetPropertyChangedFlag();
405 if (m_maskLayer)
406 m_maskLayer->resetAllChangeTrackingForSubtree();
408 if (m_replicaLayer)
409 m_replicaLayer->resetAllChangeTrackingForSubtree(); // also resets the replica mask, if it exists.
411 for (size_t i = 0; i < m_children.size(); ++i)
412 m_children[i]->resetAllChangeTrackingForSubtree();
415 bool LayerImpl::layerIsAlwaysDamaged() const
417 return false;
420 int LayerImpl::id() const
422 return m_layerId;
425 float LayerImpl::opacity() const
427 return m_opacity;
430 void LayerImpl::setOpacityFromAnimation(float opacity)
432 setOpacity(opacity);
435 const gfx::Transform& LayerImpl::transform() const
437 return m_transform;
440 void LayerImpl::setTransformFromAnimation(const gfx::Transform& transform)
442 setTransform(transform);
445 void LayerImpl::setBounds(const gfx::Size& bounds)
447 if (m_bounds == bounds)
448 return;
450 m_bounds = bounds;
452 if (masksToBounds())
453 noteLayerPropertyChangedForSubtree();
454 else
455 m_layerPropertyChanged = true;
458 void LayerImpl::setMaskLayer(scoped_ptr<LayerImpl> maskLayer)
460 m_maskLayer = maskLayer.Pass();
462 int newLayerId = m_maskLayer ? m_maskLayer->id() : -1;
463 if (newLayerId == m_maskLayerId)
464 return;
466 m_maskLayerId = newLayerId;
467 noteLayerPropertyChangedForSubtree();
470 void LayerImpl::setReplicaLayer(scoped_ptr<LayerImpl> replicaLayer)
472 m_replicaLayer = replicaLayer.Pass();
474 int newLayerId = m_replicaLayer ? m_replicaLayer->id() : -1;
475 if (newLayerId == m_replicaLayerId)
476 return;
478 m_replicaLayerId = newLayerId;
479 noteLayerPropertyChangedForSubtree();
482 void LayerImpl::setDrawsContent(bool drawsContent)
484 if (m_drawsContent == drawsContent)
485 return;
487 m_drawsContent = drawsContent;
488 m_layerPropertyChanged = true;
491 void LayerImpl::setAnchorPoint(const gfx::PointF& anchorPoint)
493 if (m_anchorPoint == anchorPoint)
494 return;
496 m_anchorPoint = anchorPoint;
497 noteLayerPropertyChangedForSubtree();
500 void LayerImpl::setAnchorPointZ(float anchorPointZ)
502 if (m_anchorPointZ == anchorPointZ)
503 return;
505 m_anchorPointZ = anchorPointZ;
506 noteLayerPropertyChangedForSubtree();
509 void LayerImpl::setBackgroundColor(SkColor backgroundColor)
511 if (m_backgroundColor == backgroundColor)
512 return;
514 m_backgroundColor = backgroundColor;
515 m_layerPropertyChanged = true;
518 void LayerImpl::setFilters(const WebKit::WebFilterOperations& filters)
520 if (m_filters == filters)
521 return;
523 DCHECK(!m_filter);
524 m_filters = filters;
525 noteLayerPropertyChangedForSubtree();
528 void LayerImpl::setBackgroundFilters(const WebKit::WebFilterOperations& backgroundFilters)
530 if (m_backgroundFilters == backgroundFilters)
531 return;
533 m_backgroundFilters = backgroundFilters;
534 m_layerPropertyChanged = true;
537 void LayerImpl::setFilter(const skia::RefPtr<SkImageFilter>& filter)
539 if (m_filter.get() == filter.get())
540 return;
542 DCHECK(m_filters.isEmpty());
543 m_filter = filter;
544 noteLayerPropertyChangedForSubtree();
547 void LayerImpl::setMasksToBounds(bool masksToBounds)
549 if (m_masksToBounds == masksToBounds)
550 return;
552 m_masksToBounds = masksToBounds;
553 noteLayerPropertyChangedForSubtree();
556 void LayerImpl::setContentsOpaque(bool opaque)
558 if (m_contentsOpaque == opaque)
559 return;
561 m_contentsOpaque = opaque;
562 noteLayerPropertyChangedForSubtree();
565 void LayerImpl::setOpacity(float opacity)
567 if (m_opacity == opacity)
568 return;
570 m_opacity = opacity;
571 m_layerSurfacePropertyChanged = true;
574 bool LayerImpl::opacityIsAnimating() const
576 return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Opacity);
579 void LayerImpl::setPosition(const gfx::PointF& position)
581 if (m_position == position)
582 return;
584 m_position = position;
585 noteLayerPropertyChangedForSubtree();
588 void LayerImpl::setPreserves3D(bool preserves3D)
590 if (m_preserves3D == preserves3D)
591 return;
593 m_preserves3D = preserves3D;
594 noteLayerPropertyChangedForSubtree();
597 void LayerImpl::setSublayerTransform(const gfx::Transform& sublayerTransform)
599 if (m_sublayerTransform == sublayerTransform)
600 return;
602 m_sublayerTransform = sublayerTransform;
603 // sublayer transform does not affect the current layer; it affects only its children.
604 noteLayerPropertyChangedForDescendants();
607 void LayerImpl::setTransform(const gfx::Transform& transform)
609 if (m_transform == transform)
610 return;
612 m_transform = transform;
613 m_layerSurfacePropertyChanged = true;
616 bool LayerImpl::transformIsAnimating() const
618 return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Transform);
621 void LayerImpl::setContentBounds(const gfx::Size& contentBounds)
623 if (m_contentBounds == contentBounds)
624 return;
626 m_contentBounds = contentBounds;
627 m_layerPropertyChanged = true;
630 void LayerImpl::setContentsScale(float contentsScaleX, float contentsScaleY)
632 if (m_contentsScaleX == contentsScaleX && m_contentsScaleY == contentsScaleY)
633 return;
635 m_contentsScaleX = contentsScaleX;
636 m_contentsScaleY = contentsScaleY;
637 m_layerPropertyChanged = true;
640 void LayerImpl::setScrollOffset(gfx::Vector2d scrollOffset)
642 if (m_scrollOffset == scrollOffset)
643 return;
645 m_scrollOffset = scrollOffset;
646 noteLayerPropertyChangedForSubtree();
649 void LayerImpl::setScrollDelta(const gfx::Vector2dF& scrollDelta)
651 if (m_scrollDelta == scrollDelta)
652 return;
654 m_scrollDelta = scrollDelta;
655 noteLayerPropertyChangedForSubtree();
658 void LayerImpl::setImplTransform(const gfx::Transform& transform)
660 if (m_implTransform == transform)
661 return;
663 m_implTransform = transform;
664 noteLayerPropertyChangedForSubtree();
667 void LayerImpl::setDoubleSided(bool doubleSided)
669 if (m_doubleSided == doubleSided)
670 return;
672 m_doubleSided = doubleSided;
673 noteLayerPropertyChangedForSubtree();
676 Region LayerImpl::visibleContentOpaqueRegion() const
678 if (contentsOpaque())
679 return visibleContentRect();
680 return Region();
683 void LayerImpl::didLoseOutputSurface()
687 void LayerImpl::setMaxScrollOffset(gfx::Vector2d maxScrollOffset)
689 m_maxScrollOffset = maxScrollOffset;
691 if (!m_scrollbarAnimationController)
692 return;
693 m_scrollbarAnimationController->updateScrollOffset(this);
696 ScrollbarLayerImpl* LayerImpl::horizontalScrollbarLayer()
698 return m_scrollbarAnimationController ? m_scrollbarAnimationController->horizontalScrollbarLayer() : 0;
701 const ScrollbarLayerImpl* LayerImpl::horizontalScrollbarLayer() const
703 return m_scrollbarAnimationController ? m_scrollbarAnimationController->horizontalScrollbarLayer() : 0;
706 void LayerImpl::setHorizontalScrollbarLayer(ScrollbarLayerImpl* scrollbarLayer)
708 if (!m_scrollbarAnimationController)
709 m_scrollbarAnimationController = ScrollbarAnimationController::create(this);
710 m_scrollbarAnimationController->setHorizontalScrollbarLayer(scrollbarLayer);
711 m_scrollbarAnimationController->updateScrollOffset(this);
714 ScrollbarLayerImpl* LayerImpl::verticalScrollbarLayer()
716 return m_scrollbarAnimationController ? m_scrollbarAnimationController->verticalScrollbarLayer() : 0;
719 const ScrollbarLayerImpl* LayerImpl::verticalScrollbarLayer() const
721 return m_scrollbarAnimationController ? m_scrollbarAnimationController->verticalScrollbarLayer() : 0;
724 void LayerImpl::setVerticalScrollbarLayer(ScrollbarLayerImpl* scrollbarLayer)
726 if (!m_scrollbarAnimationController)
727 m_scrollbarAnimationController = ScrollbarAnimationController::create(this);
728 m_scrollbarAnimationController->setVerticalScrollbarLayer(scrollbarLayer);
729 m_scrollbarAnimationController->updateScrollOffset(this);
732 } // namespace cc