// 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/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();

  // 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);

  // 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 id,
                      const cc::SurfaceLayer::SatisfyCallback& satisfy_callback,
                      const cc::SurfaceLayer::RequireCallback& require_callback,
                      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::GraphicsContextStatus gc_status) 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::debug::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_
