| // Copyright (c) 2012 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 UI_COMPOSITOR_LAYER_H_ |
| #define UI_COMPOSITOR_LAYER_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/compiler_specific.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop/message_loop.h" |
| #include "cc/animation/animation_events.h" |
| #include "cc/animation/layer_animation_event_observer.h" |
| #include "cc/base/scoped_ptr_vector.h" |
| #include "cc/layers/content_layer_client.h" |
| #include "cc/layers/layer_client.h" |
| #include "cc/layers/surface_layer.h" |
| #include "cc/layers/texture_layer_client.h" |
| #include "cc/resources/texture_mailbox.h" |
| #include "cc/surfaces/surface_id.h" |
| #include "third_party/skia/include/core/SkColor.h" |
| #include "third_party/skia/include/core/SkRegion.h" |
| #include "ui/compositor/compositor.h" |
| #include "ui/compositor/layer_animation_delegate.h" |
| #include "ui/compositor/layer_delegate.h" |
| #include "ui/compositor/layer_type.h" |
| #include "ui/gfx/geometry/rect.h" |
| #include "ui/gfx/transform.h" |
| |
| class SkCanvas; |
| |
| namespace cc { |
| class ContentLayer; |
| class CopyOutputRequest; |
| class DelegatedFrameProvider; |
| class DelegatedRendererLayer; |
| class Layer; |
| class NinePatchLayer; |
| class ResourceUpdateQueue; |
| class SolidColorLayer; |
| class SurfaceLayer; |
| class TextureLayer; |
| struct ReturnedResource; |
| typedef std::vector<ReturnedResource> ReturnedResourceArray; |
| } |
| |
| namespace ui { |
| |
| class Compositor; |
| class LayerAnimator; |
| class LayerOwner; |
| |
| // Layer manages a texture, transform and a set of child Layers. Any View that |
| // has enabled layers ends up creating a Layer to manage the texture. |
| // A Layer can also be created without a texture, in which case it renders |
| // nothing and is simply used as a node in a hierarchy of layers. |
| // Coordinate system used in layers is DIP (Density Independent Pixel) |
| // coordinates unless explicitly mentioned as pixel coordinates. |
| // |
| // NOTE: Unlike Views, each Layer does *not* own its child Layers. If you |
| // delete a Layer and it has children, the parent of each child Layer is set to |
| // NULL, but the children are not deleted. |
| class COMPOSITOR_EXPORT Layer |
| : public LayerAnimationDelegate, |
| NON_EXPORTED_BASE(public cc::ContentLayerClient), |
| NON_EXPORTED_BASE(public cc::TextureLayerClient), |
| NON_EXPORTED_BASE(public cc::LayerClient), |
| NON_EXPORTED_BASE(public cc::LayerAnimationEventObserver) { |
| public: |
| Layer(); |
| explicit Layer(LayerType type); |
| ~Layer() override; |
| |
| static bool UsingPictureLayer(); |
| |
| // Retrieves the Layer's compositor. The Layer will walk up its parent chain |
| // to locate it. Returns NULL if the Layer is not attached to a compositor. |
| Compositor* GetCompositor() { |
| return const_cast<Compositor*>( |
| const_cast<const Layer*>(this)->GetCompositor()); |
| } |
| const Compositor* GetCompositor() const; |
| |
| // Called by the compositor when the Layer is set as its root Layer. This can |
| // only ever be called on the root layer. |
| void SetCompositor(Compositor* compositor); |
| |
| LayerDelegate* delegate() { return delegate_; } |
| void set_delegate(LayerDelegate* delegate) { delegate_ = delegate; } |
| |
| LayerOwner* owner() { return owner_; } |
| |
| // Adds a new Layer to this Layer. |
| void Add(Layer* child); |
| |
| // Removes a Layer from this Layer. |
| void Remove(Layer* child); |
| |
| // Stacks |child| above all other children. |
| void StackAtTop(Layer* child); |
| |
| // Stacks |child| directly above |other|. Both must be children of this |
| // layer. Note that if |child| is initially stacked even higher, calling this |
| // method will result in |child| being lowered in the stacking order. |
| void StackAbove(Layer* child, Layer* other); |
| |
| // Stacks |child| below all other children. |
| void StackAtBottom(Layer* child); |
| |
| // Stacks |child| directly below |other|. Both must be children of this |
| // layer. |
| void StackBelow(Layer* child, Layer* other); |
| |
| // Returns the child Layers. |
| const std::vector<Layer*>& children() const { return children_; } |
| |
| // The parent. |
| const Layer* parent() const { return parent_; } |
| Layer* parent() { return parent_; } |
| |
| LayerType type() const { return type_; } |
| |
| // Returns true if this Layer contains |other| somewhere in its children. |
| bool Contains(const Layer* other) const; |
| |
| // The layer's animator is responsible for causing automatic animations when |
| // properties are set. It also manages a queue of pending animations and |
| // handles blending of animations. The layer takes ownership of the animator. |
| void SetAnimator(LayerAnimator* animator); |
| |
| // Returns the layer's animator. Creates a default animator of one has not |
| // been set. Will not return NULL. |
| LayerAnimator* GetAnimator(); |
| |
| // The transform, relative to the parent. |
| void SetTransform(const gfx::Transform& transform); |
| gfx::Transform transform() const; |
| |
| // Return the target transform if animator is running, or the current |
| // transform otherwise. |
| gfx::Transform GetTargetTransform() const; |
| |
| // The bounds, relative to the parent. |
| void SetBounds(const gfx::Rect& bounds); |
| const gfx::Rect& bounds() const { return bounds_; } |
| |
| // The offset from our parent (stored in bounds.origin()) is an integer but we |
| // may need to be at a fractional pixel offset to align properly on screen. |
| void SetSubpixelPositionOffset(const gfx::Vector2dF offset); |
| const gfx::Vector2dF& subpixel_position_offset() const { |
| return subpixel_position_offset_; |
| } |
| |
| // Return the target bounds if animator is running, or the current bounds |
| // otherwise. |
| gfx::Rect GetTargetBounds() const; |
| |
| // Sets/gets whether or not drawing of child layers should be clipped to the |
| // bounds of this layer. |
| void SetMasksToBounds(bool masks_to_bounds); |
| bool GetMasksToBounds() const; |
| |
| // The opacity of the layer. The opacity is applied to each pixel of the |
| // texture (resulting alpha = opacity * alpha). |
| float opacity() const; |
| void SetOpacity(float opacity); |
| |
| // Returns the actual opacity, which the opacity of this layer multipled by |
| // the combined opacity of the parent. |
| float GetCombinedOpacity() const; |
| |
| // Blur pixels by this amount in anything below the layer and visible through |
| // the layer. |
| int background_blur() const { return background_blur_radius_; } |
| void SetBackgroundBlur(int blur_radius); |
| |
| // Saturate all pixels of this layer by this amount. |
| // This effect will get "combined" with the inverted, |
| // brightness and grayscale setting. |
| float layer_saturation() const { return layer_saturation_; } |
| void SetLayerSaturation(float saturation); |
| |
| // Change the brightness of all pixels from this layer by this amount. |
| // This effect will get "combined" with the inverted, saturate |
| // and grayscale setting. |
| float layer_brightness() const { return layer_brightness_; } |
| void SetLayerBrightness(float brightness); |
| |
| // Return the target brightness if animator is running, or the current |
| // brightness otherwise. |
| float GetTargetBrightness() const; |
| |
| // Change the grayscale of all pixels from this layer by this amount. |
| // This effect will get "combined" with the inverted, saturate |
| // and brightness setting. |
| float layer_grayscale() const { return layer_grayscale_; } |
| void SetLayerGrayscale(float grayscale); |
| |
| // Return the target grayscale if animator is running, or the current |
| // grayscale otherwise. |
| float GetTargetGrayscale() const; |
| |
| // Zoom the background by a factor of |zoom|. The effect is blended along the |
| // edge across |inset| pixels. |
| void SetBackgroundZoom(float zoom, int inset); |
| |
| // Set the shape of this layer. |
| SkRegion* alpha_shape() const { return alpha_shape_.get(); } |
| void SetAlphaShape(scoped_ptr<SkRegion> region); |
| |
| // Invert the layer. |
| bool layer_inverted() const { return layer_inverted_; } |
| void SetLayerInverted(bool inverted); |
| |
| // Return the target opacity if animator is running, or the current opacity |
| // otherwise. |
| float GetTargetOpacity() const; |
| |
| // Set a layer mask for a layer. |
| // Note the provided layer mask can neither have a layer mask itself nor can |
| // it have any children. The ownership of |layer_mask| will not be |
| // transferred with this call. |
| // Furthermore: A mask layer can only be set to one layer. |
| void SetMaskLayer(Layer* layer_mask); |
| Layer* layer_mask_layer() { return layer_mask_; } |
| |
| // Sets the visibility of the Layer. A Layer may be visible but not |
| // drawn. This happens if any ancestor of a Layer is not visible. |
| void SetVisible(bool visible); |
| bool visible() const { return visible_; } |
| |
| // Returns the target visibility if the animator is running. Otherwise, it |
| // returns the current visibility. |
| bool GetTargetVisibility() const; |
| |
| // Returns true if this Layer is drawn. A Layer is drawn only if all ancestors |
| // are visible. |
| bool IsDrawn() const; |
| |
| // Returns true if this layer can have a texture (has_texture_ is true) |
| // and is not completely obscured by a child. |
| bool ShouldDraw() const; |
| |
| // Converts a point from the coordinates of |source| to the coordinates of |
| // |target|. Necessarily, |source| and |target| must inhabit the same Layer |
| // tree. |
| static void ConvertPointToLayer(const Layer* source, |
| const Layer* target, |
| gfx::Point* point); |
| |
| // Converts a transform to be relative to the given |ancestor|. Returns |
| // whether success (that is, whether the given ancestor was really an |
| // ancestor of this layer). |
| bool GetTargetTransformRelativeTo(const Layer* ancestor, |
| gfx::Transform* transform) const; |
| |
| // See description in View for details |
| void SetFillsBoundsOpaquely(bool fills_bounds_opaquely); |
| bool fills_bounds_opaquely() const { return fills_bounds_opaquely_; } |
| |
| // Set to true if this layer always paints completely within its bounds. If so |
| // we can omit an unnecessary clear, even if the layer is transparent. |
| void SetFillsBoundsCompletely(bool fills_bounds_completely); |
| |
| const std::string& name() const { return name_; } |
| void set_name(const std::string& name) { name_ = name; } |
| |
| // Set new TextureMailbox for this layer. Note that |mailbox| may hold a |
| // shared memory resource or an actual mailbox for a texture. |
| void SetTextureMailbox(const cc::TextureMailbox& mailbox, |
| scoped_ptr<cc::SingleReleaseCallback> release_callback, |
| gfx::Size texture_size_in_dip); |
| void SetTextureSize(gfx::Size texture_size_in_dip); |
| void SetTextureFlipped(bool flipped); |
| bool TextureFlipped() const; |
| |
| // Begins showing delegated frames from the |frame_provider|. |
| void SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider, |
| gfx::Size frame_size_in_dip); |
| |
| // Begins showing content from a surface with a particular id. |
| void SetShowSurface(cc::SurfaceId surface_id, |
| const cc::SurfaceLayer::SatisfyCallback& satisfy_callback, |
| const cc::SurfaceLayer::RequireCallback& require_callback, |
| gfx::Size surface_size, |
| float scale, |
| gfx::Size frame_size_in_dip); |
| |
| bool has_external_content() { |
| return texture_layer_.get() || delegated_renderer_layer_.get() || |
| surface_layer_.get(); |
| } |
| |
| // Show a solid color instead of delegated or surface contents. |
| void SetShowSolidColorContent(); |
| |
| // Sets the layer's fill color. May only be called for LAYER_SOLID_COLOR. |
| void SetColor(SkColor color); |
| |
| // Updates the nine patch layer's bitmap, aperture and border. May only be |
| // called for LAYER_NINE_PATCH. |
| void UpdateNinePatchLayerBitmap(const SkBitmap& bitmap); |
| void UpdateNinePatchLayerAperture(const gfx::Rect& aperture); |
| void UpdateNinePatchLayerBorder(const gfx::Rect& border); |
| |
| // Adds |invalid_rect| to the Layer's pending invalid rect and calls |
| // ScheduleDraw(). Returns false if the paint request is ignored. |
| bool SchedulePaint(const gfx::Rect& invalid_rect); |
| |
| // Schedules a redraw of the layer tree at the compositor. |
| // Note that this _does not_ invalidate any region of this layer; use |
| // SchedulePaint() for that. |
| void ScheduleDraw(); |
| |
| // Uses damaged rectangles recorded in |damaged_region_| to invalidate the |
| // |cc_layer_|. |
| void SendDamagedRects(); |
| |
| const SkRegion& damaged_region() const { return damaged_region_; } |
| |
| void CompleteAllAnimations(); |
| |
| // Suppresses painting the content by disconnecting |delegate_|. |
| void SuppressPaint(); |
| |
| // Notifies the layer that the device scale factor has changed. |
| void OnDeviceScaleFactorChanged(float device_scale_factor); |
| |
| // Notifies the layer that one of its children has received a new |
| // delegated frame. |
| void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip); |
| |
| // Requets a copy of the layer's output as a texture or bitmap. |
| void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request); |
| |
| // ContentLayerClient |
| void PaintContents( |
| SkCanvas* canvas, |
| const gfx::Rect& clip, |
| ContentLayerClient::PaintingControlSetting painting_control) override; |
| scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList( |
| const gfx::Rect& clip, |
| ContentLayerClient::PaintingControlSetting painting_control) override; |
| bool FillsBoundsCompletely() const override; |
| |
| cc::Layer* cc_layer() { return cc_layer_; } |
| |
| // TextureLayerClient |
| bool PrepareTextureMailbox( |
| cc::TextureMailbox* mailbox, |
| scoped_ptr<cc::SingleReleaseCallback>* release_callback, |
| bool use_shared_memory) override; |
| |
| float device_scale_factor() const { return device_scale_factor_; } |
| |
| // Forces a render surface to be used on this layer. This has no positive |
| // impact, and is only used for benchmarking/testing purpose. |
| void SetForceRenderSurface(bool force); |
| bool force_render_surface() const { return force_render_surface_; } |
| |
| // LayerClient |
| scoped_refptr<base::trace_event::ConvertableToTraceFormat> TakeDebugInfo() |
| override; |
| |
| // LayerAnimationEventObserver |
| void OnAnimationStarted(const cc::AnimationEvent& event) override; |
| |
| // Whether this layer has animations waiting to get sent to its cc::Layer. |
| bool HasPendingThreadedAnimations() { |
| return pending_threaded_animations_.size() != 0; |
| } |
| |
| // Triggers a call to SwitchToLayer. |
| void SwitchCCLayerForTest(); |
| |
| private: |
| friend class LayerOwner; |
| |
| void CollectAnimators(std::vector<scoped_refptr<LayerAnimator> >* animators); |
| |
| // Stacks |child| above or below |other|. Helper method for StackAbove() and |
| // StackBelow(). |
| void StackRelativeTo(Layer* child, Layer* other, bool above); |
| |
| bool ConvertPointForAncestor(const Layer* ancestor, gfx::Point* point) const; |
| bool ConvertPointFromAncestor(const Layer* ancestor, gfx::Point* point) const; |
| |
| // Implementation of LayerAnimatorDelegate |
| void SetBoundsFromAnimation(const gfx::Rect& bounds) override; |
| void SetTransformFromAnimation(const gfx::Transform& transform) override; |
| void SetOpacityFromAnimation(float opacity) override; |
| void SetVisibilityFromAnimation(bool visibility) override; |
| void SetBrightnessFromAnimation(float brightness) override; |
| void SetGrayscaleFromAnimation(float grayscale) override; |
| void SetColorFromAnimation(SkColor color) override; |
| void ScheduleDrawForAnimation() override; |
| const gfx::Rect& GetBoundsForAnimation() const override; |
| gfx::Transform GetTransformForAnimation() const override; |
| float GetOpacityForAnimation() const override; |
| bool GetVisibilityForAnimation() const override; |
| float GetBrightnessForAnimation() const override; |
| float GetGrayscaleForAnimation() const override; |
| SkColor GetColorForAnimation() const override; |
| float GetDeviceScaleFactor() const override; |
| void AddThreadedAnimation(scoped_ptr<cc::Animation> animation) override; |
| void RemoveThreadedAnimation(int animation_id) override; |
| LayerAnimatorCollection* GetLayerAnimatorCollection() override; |
| |
| // Creates a corresponding composited layer for |type_|. |
| void CreateCcLayer(); |
| |
| // Recomputes and sets to |cc_layer_|. |
| void RecomputeDrawsContentAndUVRect(); |
| void RecomputePosition(); |
| |
| // Set all filters which got applied to the layer. |
| void SetLayerFilters(); |
| |
| // Set all filters which got applied to the layer background. |
| void SetLayerBackgroundFilters(); |
| |
| // Cleanup |cc_layer_| and replaces it with |new_layer|. |
| void SwitchToLayer(scoped_refptr<cc::Layer> new_layer); |
| |
| // We cannot send animations to our cc_layer_ until we have been added to a |
| // layer tree. Instead, we hold on to these animations in |
| // pending_threaded_animations_, and expect SendPendingThreadedAnimations to |
| // be called once we have been added to a tree. |
| void SendPendingThreadedAnimations(); |
| |
| void AddAnimatorsInTreeToCollection(LayerAnimatorCollection* collection); |
| void RemoveAnimatorsInTreeFromCollection(LayerAnimatorCollection* collection); |
| |
| // Returns whether the layer has an animating LayerAnimator. |
| bool IsAnimating() const; |
| |
| const LayerType type_; |
| |
| Compositor* compositor_; |
| |
| Layer* parent_; |
| |
| // This layer's children, in bottom-to-top stacking order. |
| std::vector<Layer*> children_; |
| |
| gfx::Rect bounds_; |
| gfx::Vector2dF subpixel_position_offset_; |
| |
| // Visibility of this layer. See SetVisible/IsDrawn for more details. |
| bool visible_; |
| |
| bool force_render_surface_; |
| |
| bool fills_bounds_opaquely_; |
| bool fills_bounds_completely_; |
| |
| // Union of damaged rects, in pixel coordinates, to be used when |
| // compositor is ready to paint the content. |
| SkRegion damaged_region_; |
| |
| int background_blur_radius_; |
| |
| // Several variables which will change the visible representation of |
| // the layer. |
| float layer_saturation_; |
| float layer_brightness_; |
| float layer_grayscale_; |
| bool layer_inverted_; |
| |
| // The associated mask layer with this layer. |
| Layer* layer_mask_; |
| // The back link from the mask layer to it's associated masked layer. |
| // We keep this reference for the case that if the mask layer gets deleted |
| // while attached to the main layer before the main layer is deleted. |
| Layer* layer_mask_back_link_; |
| |
| // The zoom factor to scale the layer by. Zooming is disabled when this is |
| // set to 1. |
| float zoom_; |
| |
| // Width of the border in pixels, where the scaling is blended. |
| int zoom_inset_; |
| |
| // Shape of the window. |
| scoped_ptr<SkRegion> alpha_shape_; |
| |
| std::string name_; |
| |
| LayerDelegate* delegate_; |
| |
| LayerOwner* owner_; |
| |
| scoped_refptr<LayerAnimator> animator_; |
| |
| // Animations that are passed to AddThreadedAnimation before this layer is |
| // added to a tree. |
| cc::ScopedPtrVector<cc::Animation> pending_threaded_animations_; |
| |
| // Ownership of the layer is held through one of the strongly typed layer |
| // pointers, depending on which sort of layer this is. |
| scoped_refptr<cc::Layer> content_layer_; |
| scoped_refptr<cc::NinePatchLayer> nine_patch_layer_; |
| scoped_refptr<cc::TextureLayer> texture_layer_; |
| scoped_refptr<cc::SolidColorLayer> solid_color_layer_; |
| scoped_refptr<cc::DelegatedRendererLayer> delegated_renderer_layer_; |
| scoped_refptr<cc::SurfaceLayer> surface_layer_; |
| cc::Layer* cc_layer_; |
| |
| // A cached copy of |Compositor::device_scale_factor()|. |
| float device_scale_factor_; |
| |
| // The mailbox used by texture_layer_. |
| cc::TextureMailbox mailbox_; |
| |
| // The callback to release the mailbox. This is only set after |
| // SetTextureMailbox is called, before we give it to the TextureLayer. |
| scoped_ptr<cc::SingleReleaseCallback> mailbox_release_callback_; |
| |
| // The size of the frame or texture in DIP, set when SetShowDelegatedContent |
| // or SetTextureMailbox was called. |
| gfx::Size frame_size_in_dip_; |
| |
| DISALLOW_COPY_AND_ASSIGN(Layer); |
| }; |
| |
| } // namespace ui |
| |
| #endif // UI_COMPOSITOR_LAYER_H_ |