// Copyright 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CC_LAYER_IMPL_H_ #define CC_LAYER_IMPL_H_ #include #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "cc/cc_export.h" #include "cc/input_handler.h" #include "cc/layer_animation_controller.h" #include "cc/region.h" #include "cc/render_pass.h" #include "cc/render_surface_impl.h" #include "cc/resource_provider.h" #include "cc/scoped_ptr_vector.h" #include "cc/shared_quad_state.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/rect.h" #include "ui/gfx/rect_f.h" #include #include namespace cc { class LayerSorter; class LayerTreeHostImpl; class QuadSink; class Renderer; class ScrollbarAnimationController; class ScrollbarLayerImpl; class Layer; struct AppendQuadsData; class CC_EXPORT LayerImpl : public LayerAnimationControllerClient { public: static scoped_ptr create(int id) { return make_scoped_ptr(new LayerImpl(id)); } virtual ~LayerImpl(); // LayerAnimationControllerClient implementation. virtual int id() const OVERRIDE; virtual void setOpacityFromAnimation(float) OVERRIDE; virtual float opacity() const OVERRIDE; virtual void setTransformFromAnimation(const WebKit::WebTransformationMatrix&) OVERRIDE; virtual const WebKit::WebTransformationMatrix& transform() const OVERRIDE; // Tree structure. LayerImpl* parent() const { return m_parent; } const ScopedPtrVector& children() const { return m_children; } void addChild(scoped_ptr); void removeFromParent(); void removeAllChildren(); void setMaskLayer(scoped_ptr); LayerImpl* maskLayer() const { return m_maskLayer.get(); } void setReplicaLayer(scoped_ptr); LayerImpl* replicaLayer() const { return m_replicaLayer.get(); } bool hasMask() const { return m_maskLayer; } bool hasReplica() const { return m_replicaLayer; } bool replicaHasMask() const { return m_replicaLayer && (m_maskLayer || m_replicaLayer->m_maskLayer); } LayerTreeHostImpl* layerTreeHostImpl() const { return m_layerTreeHostImpl; } void setLayerTreeHostImpl(LayerTreeHostImpl* hostImpl) { m_layerTreeHostImpl = hostImpl; } scoped_ptr createSharedQuadState() const; // willDraw must be called before appendQuads. If willDraw is called, // didDraw is guaranteed to be called before another willDraw or before // the layer is destroyed. To enforce this, any class that overrides // willDraw/didDraw must call the base class version. virtual void willDraw(ResourceProvider*); virtual void appendQuads(QuadSink&, AppendQuadsData&) { } virtual void didDraw(ResourceProvider*); virtual ResourceProvider::ResourceId contentsResourceId() const; virtual bool hasContributingDelegatedRenderPasses() const; virtual RenderPass::Id firstContributingRenderPassId() const; virtual RenderPass::Id nextContributingRenderPassId(RenderPass::Id) const; // Returns true if this layer has content to draw. void setDrawsContent(bool); bool drawsContent() const { return m_drawsContent; } bool forceRenderSurface() const { return m_forceRenderSurface; } void setForceRenderSurface(bool force) { m_forceRenderSurface = force; } // Returns true if any of the layer's descendants has content to draw. virtual bool descendantDrawsContent(); void setAnchorPoint(const gfx::PointF&); const gfx::PointF& anchorPoint() const { return m_anchorPoint; } void setAnchorPointZ(float); float anchorPointZ() const { return m_anchorPointZ; } void setBackgroundColor(SkColor); SkColor backgroundColor() const { return m_backgroundColor; } void setFilters(const WebKit::WebFilterOperations&); const WebKit::WebFilterOperations& filters() const { return m_filters; } void setBackgroundFilters(const WebKit::WebFilterOperations&); const WebKit::WebFilterOperations& backgroundFilters() const { return m_backgroundFilters; } void setFilter(SkImageFilter*); SkImageFilter* filter() const { return m_filter; } void setMasksToBounds(bool); bool masksToBounds() const { return m_masksToBounds; } void setContentsOpaque(bool); bool contentsOpaque() const { return m_contentsOpaque; } void setOpacity(float); bool opacityIsAnimating() const; void setPosition(const gfx::PointF&); const gfx::PointF& position() const { return m_position; } void setIsContainerForFixedPositionLayers(bool isContainerForFixedPositionLayers) { m_isContainerForFixedPositionLayers = isContainerForFixedPositionLayers; } bool isContainerForFixedPositionLayers() const { return m_isContainerForFixedPositionLayers; } void setFixedToContainerLayer(bool fixedToContainerLayer = true) { m_fixedToContainerLayer = fixedToContainerLayer;} bool fixedToContainerLayer() const { return m_fixedToContainerLayer; } void setPreserves3D(bool); bool preserves3D() const { return m_preserves3D; } void setUseParentBackfaceVisibility(bool useParentBackfaceVisibility) { m_useParentBackfaceVisibility = useParentBackfaceVisibility; } bool useParentBackfaceVisibility() const { return m_useParentBackfaceVisibility; } void setUseLCDText(bool useLCDText) { m_useLCDText = useLCDText; } bool useLCDText() const { return m_useLCDText; } void setSublayerTransform(const WebKit::WebTransformationMatrix&); const WebKit::WebTransformationMatrix& sublayerTransform() const { return m_sublayerTransform; } // Debug layer border - visual effect only, do not change geometry/clipping/etc. void setDebugBorderColor(SkColor); SkColor debugBorderColor() const { return m_debugBorderColor; } void setDebugBorderWidth(float); float debugBorderWidth() const { return m_debugBorderWidth; } bool hasDebugBorders() const; // Debug layer name. void setDebugName(const std::string& debugName) { m_debugName = debugName; } std::string debugName() const { return m_debugName; } RenderSurfaceImpl* renderSurface() const { return m_renderSurface.get(); } void createRenderSurface(); void clearRenderSurface() { m_renderSurface.reset(); } float drawOpacity() const { return m_drawOpacity; } void setDrawOpacity(float opacity) { m_drawOpacity = opacity; } bool drawOpacityIsAnimating() const { return m_drawOpacityIsAnimating; } void setDrawOpacityIsAnimating(bool drawOpacityIsAnimating) { m_drawOpacityIsAnimating = drawOpacityIsAnimating; } LayerImpl* renderTarget() const { DCHECK(!m_renderTarget || m_renderTarget->renderSurface()); return m_renderTarget; } void setRenderTarget(LayerImpl* target) { m_renderTarget = target; } // The client should be responsible for setting bounds, contentBounds and // contentsScale to appropriate values. LayerImpl doesn't calculate any of // them from the other values. void setBounds(const gfx::Size&); const gfx::Size& bounds() const { return m_bounds; } // ContentBounds may be [0, 1) pixels larger than bounds * contentsScale. // Don't calculate scale from it. Use contentsScale instead for accuracy. void setContentBounds(const gfx::Size&); gfx::Size contentBounds() const { return m_contentBounds; } float contentsScaleX() const { return m_contentsScaleX; } float contentsScaleY() const { return m_contentsScaleY; } void setContentsScale(float contentsScaleX, float contentsScaleY); gfx::Vector2d scrollOffset() const { return m_scrollOffset; } void setScrollOffset(gfx::Vector2d); gfx::Vector2d maxScrollOffset() const {return m_maxScrollOffset; } void setMaxScrollOffset(gfx::Vector2d); const gfx::Vector2dF& scrollDelta() const { return m_scrollDelta; } void setScrollDelta(const gfx::Vector2dF&); const WebKit::WebTransformationMatrix& implTransform() const { return m_implTransform; } void setImplTransform(const WebKit::WebTransformationMatrix& transform); const gfx::Vector2d& sentScrollDelta() const { return m_sentScrollDelta; } void setSentScrollDelta(const gfx::Vector2d& sentScrollDelta) { m_sentScrollDelta = sentScrollDelta; } // Returns the delta of the scroll that was outside of the bounds of the initial scroll gfx::Vector2dF scrollBy(const gfx::Vector2dF& scroll); bool scrollable() const { return m_scrollable; } void setScrollable(bool scrollable) { m_scrollable = scrollable; } bool shouldScrollOnMainThread() const { return m_shouldScrollOnMainThread; } void setShouldScrollOnMainThread(bool shouldScrollOnMainThread) { m_shouldScrollOnMainThread = shouldScrollOnMainThread; } bool haveWheelEventHandlers() const { return m_haveWheelEventHandlers; } void setHaveWheelEventHandlers(bool haveWheelEventHandlers) { m_haveWheelEventHandlers = haveWheelEventHandlers; } const Region& nonFastScrollableRegion() const { return m_nonFastScrollableRegion; } void setNonFastScrollableRegion(const Region& region) { m_nonFastScrollableRegion = region; } const Region& touchEventHandlerRegion() const { return m_touchEventHandlerRegion; } void setTouchEventHandlerRegion(const Region& region) { m_touchEventHandlerRegion = region; } void setDrawCheckerboardForMissingTiles(bool checkerboard) { m_drawCheckerboardForMissingTiles = checkerboard; } bool drawCheckerboardForMissingTiles() const; InputHandlerClient::ScrollStatus tryScroll(const gfx::PointF& screenSpacePoint, InputHandlerClient::ScrollInputType) const; const gfx::Rect& visibleContentRect() const { return m_visibleContentRect; } void setVisibleContentRect(const gfx::Rect& visibleContentRect) { m_visibleContentRect = visibleContentRect; } bool doubleSided() const { return m_doubleSided; } void setDoubleSided(bool); void setTransform(const WebKit::WebTransformationMatrix&); bool transformIsAnimating() const; const WebKit::WebTransformationMatrix& drawTransform() const { return m_drawTransform; } void setDrawTransform(const WebKit::WebTransformationMatrix& matrix) { m_drawTransform = matrix; } const WebKit::WebTransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; } void setScreenSpaceTransform(const WebKit::WebTransformationMatrix& matrix) { m_screenSpaceTransform = matrix; } bool drawTransformIsAnimating() const { return m_drawTransformIsAnimating; } void setDrawTransformIsAnimating(bool animating) { m_drawTransformIsAnimating = animating; } bool screenSpaceTransformIsAnimating() const { return m_screenSpaceTransformIsAnimating; } void setScreenSpaceTransformIsAnimating(bool animating) { m_screenSpaceTransformIsAnimating = animating; } const gfx::Rect& drawableContentRect() const { return m_drawableContentRect; } void setDrawableContentRect(const gfx::Rect& rect) { m_drawableContentRect = rect; } const gfx::RectF& updateRect() const { return m_updateRect; } void setUpdateRect(const gfx::RectF& updateRect) { m_updateRect = updateRect; } std::string layerTreeAsText() const; void setStackingOrderChanged(bool); bool layerPropertyChanged() const { return m_layerPropertyChanged || layerIsAlwaysDamaged(); } bool layerSurfacePropertyChanged() const; void resetAllChangeTrackingForSubtree(); virtual bool layerIsAlwaysDamaged() const; LayerAnimationController* layerAnimationController() { return m_layerAnimationController.get(); } virtual Region visibleContentOpaqueRegion() const; // Indicates that the context previously used to render this layer // was lost and that a new one has been created. Won't be called // until the new context has been created successfully. virtual void didLoseContext(); ScrollbarAnimationController* scrollbarAnimationController() const { return m_scrollbarAnimationController.get(); } ScrollbarLayerImpl* horizontalScrollbarLayer() const; void setHorizontalScrollbarLayer(ScrollbarLayerImpl*); ScrollbarLayerImpl* verticalScrollbarLayer() const; void setVerticalScrollbarLayer(ScrollbarLayerImpl*); gfx::Rect layerRectToContentRect(const gfx::RectF& layerRect) const; protected: explicit LayerImpl(int); void appendDebugBorderQuad(QuadSink&, const SharedQuadState*, AppendQuadsData&) const; virtual void dumpLayerProperties(std::string*, int indent) const; static std::string indentString(int indent); private: void setParent(LayerImpl* parent) { m_parent = parent; } friend class TreeSynchronizer; void clearChildList(); // Warning: This does not preserve tree structure invariants and so is only exposed to the tree synchronizer. void noteLayerPropertyChangedForSubtree(); // Note carefully this does not affect the current layer. void noteLayerPropertyChangedForDescendants(); virtual const char* layerTypeAsString() const; void dumpLayer(std::string*, int indent) const; // Properties internal to LayerImpl LayerImpl* m_parent; ScopedPtrVector m_children; // m_maskLayer can be temporarily stolen during tree sync, we need this ID to confirm newly assigned layer is still the previous one int m_maskLayerId; scoped_ptr m_maskLayer; int m_replicaLayerId; // ditto scoped_ptr m_replicaLayer; int m_layerId; LayerTreeHostImpl* m_layerTreeHostImpl; // Properties synchronized from the associated Layer. gfx::PointF m_anchorPoint; float m_anchorPointZ; gfx::Size m_bounds; gfx::Size m_contentBounds; float m_contentsScaleX; float m_contentsScaleY; gfx::Vector2d m_scrollOffset; bool m_scrollable; bool m_shouldScrollOnMainThread; bool m_haveWheelEventHandlers; Region m_nonFastScrollableRegion; Region m_touchEventHandlerRegion; SkColor m_backgroundColor; // Whether the "back" of this layer should draw. bool m_doubleSided; // Tracks if drawing-related properties have changed since last redraw. bool m_layerPropertyChanged; // Indicates that a property has changed on this layer that would not // affect the pixels on its target surface, but would require redrawing // but would require redrawing the targetSurface onto its ancestor targetSurface. // For layers that do not own a surface this flag acts as m_layerPropertyChanged. bool m_layerSurfacePropertyChanged; // Uses layer's content space. gfx::Rect m_visibleContentRect; bool m_masksToBounds; bool m_contentsOpaque; float m_opacity; gfx::PointF m_position; bool m_preserves3D; bool m_useParentBackfaceVisibility; bool m_drawCheckerboardForMissingTiles; WebKit::WebTransformationMatrix m_sublayerTransform; WebKit::WebTransformationMatrix m_transform; bool m_useLCDText; bool m_drawsContent; bool m_forceRenderSurface; // Set for the layer that other layers are fixed to. bool m_isContainerForFixedPositionLayers; // This is true if the layer should be fixed to the closest ancestor container. bool m_fixedToContainerLayer; gfx::Vector2dF m_scrollDelta; gfx::Vector2d m_sentScrollDelta; gfx::Vector2d m_maxScrollOffset; WebKit::WebTransformationMatrix m_implTransform; // The layer whose coordinate space this layer draws into. This can be // either the same layer (m_renderTarget == this) or an ancestor of this // layer. LayerImpl* m_renderTarget; // The global depth value of the center of the layer. This value is used // to sort layers from back to front. float m_drawDepth; float m_drawOpacity; bool m_drawOpacityIsAnimating; // Debug borders. SkColor m_debugBorderColor; float m_debugBorderWidth; // Debug layer name. std::string m_debugName; WebKit::WebFilterOperations m_filters; WebKit::WebFilterOperations m_backgroundFilters; SkImageFilter* m_filter; WebKit::WebTransformationMatrix m_drawTransform; WebKit::WebTransformationMatrix m_screenSpaceTransform; bool m_drawTransformIsAnimating; bool m_screenSpaceTransformIsAnimating; #ifndef NDEBUG bool m_betweenWillDrawAndDidDraw; #endif // Render surface associated with this layer. The layer and its descendants // will render to this surface. scoped_ptr m_renderSurface; // Hierarchical bounding rect containing the layer and its descendants. // Uses target surface's space. gfx::Rect m_drawableContentRect; // Rect indicating what was repainted/updated during update. // Note that plugin layers bypass this and leave it empty. // Uses layer's content space. gfx::RectF m_updateRect; // Manages animations for this layer. scoped_ptr m_layerAnimationController; // Manages scrollbars for this layer scoped_ptr m_scrollbarAnimationController; DISALLOW_COPY_AND_ASSIGN(LayerImpl); }; void sortLayers(std::vector::iterator first, std::vector::iterator end, LayerSorter*); } #endif // CC_LAYER_IMPL_H_