// 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 <stddef.h>

#include <memory>
#include <string>
#include <vector>

#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/observer_list.h"
#include "cc/base/region.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 "components/viz/common/resources/transferable_resource.h"
#include "components/viz/common/surfaces/sequence_surface_reference_factory.h"
#include "third_party/skia/include/core/SkColor.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/image/image_skia.h"
#include "ui/gfx/transform.h"

namespace cc {
class Layer;
class NinePatchLayer;
class SolidColorLayer;
class SurfaceLayer;
class TextureLayer;
}

namespace viz {
class CopyOutputRequest;
struct TransferableResource;
}

namespace ui {

class Compositor;
class LayerAnimator;
class LayerObserver;
class LayerOwner;
class LayerThreadedAnimationDelegate;

// 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,
                                public cc::ContentLayerClient,
                                public cc::TextureLayerClient,
                                public cc::LayerClient {
 public:
  using ShapeRects = std::vector<gfx::Rect>;
  Layer();
  explicit Layer(LayerType type);
  ~Layer() override;

  // Note that only solid color and surface content is copied.
  std::unique_ptr<Layer> Clone() const;

  // Returns a new layer that mirrors this layer and is optionally synchronized
  // with the bounds thereof. Note that children are not mirrored, and that the
  // content is only mirrored if painted by a delegate or backed by a surface.
  std::unique_ptr<Layer> Mirror();

  void set_sync_bounds(bool sync_bounds) { sync_bounds_ = sync_bounds; }

  // 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,
                     scoped_refptr<cc::Layer> root_layer);
  void ResetCompositor();

  LayerDelegate* delegate() { return delegate_; }
  void set_delegate(LayerDelegate* delegate) { delegate_ = delegate; }

  LayerOwner* owner() { return owner_; }

  void AddObserver(LayerObserver* observer);
  void RemoveObserver(LayerObserver* observer);

  // 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);
  const gfx::Transform& transform() const { return cc_layer_->transform(); }

  gfx::PointF position() const { return cc_layer_->position(); }

  // 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_; }
  const gfx::Size& size() const { return bounds_.size(); }

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

  // Returns the target color temperature if animator is running, or the current
  // temperature otherwise.
  float GetTargetTemperature() const;

  // Blur pixels by 3 * this amount in anything below the layer and visible
  // through the layer.
  float background_blur() const { return background_blur_sigma_; }
  void SetBackgroundBlur(float blur_sigma);

  // Blur pixels of this layer by 3 * this amount.
  float layer_blur() const { return layer_blur_sigma_; }
  void SetLayerBlur(float blur_sigma);

  // 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.
  const ShapeRects* alpha_shape() const { return alpha_shape_.get(); }
  void SetAlphaShape(std::unique_ptr<ShapeRects> shape);

  // 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::PointF* 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;

  // Note: Setting a layer non-opaque has significant performance impact,
  // especially on low-end Chrome OS devices. Please ensure you are not
  // adding unnecessary overdraw. When in doubt, talk to the graphics team.
  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 TransferableResource for this layer. Note that |resource| may hold
  // a handle for a shared memory resource or a gpu texture.
  void SetTransferableResource(
      const viz::TransferableResource& resource,
      std::unique_ptr<viz::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 content from a surface with a particular ID.
  void SetShowPrimarySurface(
      const viz::SurfaceId& surface_id,
      const gfx::Size& frame_size_in_dip,
      SkColor default_background_color,
      scoped_refptr<viz::SurfaceReferenceFactory> surface_ref);

  // In the event that the primary surface is not yet available in the
  // display compositor, the fallback surface will be used.
  void SetFallbackSurfaceId(const viz::SurfaceId& surface_id);

  // Returns the primary SurfaceId set by SetShowPrimarySurface.
  const viz::SurfaceId* GetPrimarySurfaceId() const;

  // Returns the fallback SurfaceId set by SetFallbackSurfaceId.
  const viz::SurfaceId* GetFallbackSurfaceId() const;

  bool has_external_content() {
    return texture_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);
  SkColor GetTargetColor() const;
  SkColor background_color() const;

  // Updates the nine patch layer's image, aperture and border. May only be
  // called for LAYER_NINE_PATCH.
  void UpdateNinePatchLayerImage(const gfx::ImageSkia& image);
  void UpdateNinePatchLayerAperture(const gfx::Rect& aperture_in_dip);
  void UpdateNinePatchLayerBorder(const gfx::Rect& border);
  // Updates the area completely occluded by another layer, this can be an
  // empty rectangle if nothing is occluded.
  void UpdateNinePatchOcclusion(const gfx::Rect& occlusion);

  // 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 cc::Region& 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);

  // Requets a copy of the layer's output as a texture or bitmap.
  void RequestCopyOfOutput(std::unique_ptr<viz::CopyOutputRequest> request);

  // Invoked when scrolling performed by the cc::InputHandler is committed. This
  // will only occur if the Layer has set scroll container bounds.
  void SetDidScrollCallback(
      base::Callback<void(const gfx::ScrollOffset&, const cc::ElementId&)>
          callback);

  cc::ElementId element_id() const { return cc_layer_->element_id(); }

  // Marks this layer as scrollable inside the provided bounds. This size only
  // affects scrolling so if clipping is desired, a separate clipping layer
  // needs to be created.
  void SetScrollable(const gfx::Size& container_bounds);

  // Gets and sets the current scroll offset of the layer.
  gfx::ScrollOffset CurrentScrollOffset() const;
  void SetScrollOffset(const gfx::ScrollOffset& offset);

  // ContentLayerClient implementation.
  gfx::Rect PaintableRegion() override;
  scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList(
      ContentLayerClient::PaintingControlSetting painting_control) override;
  bool FillsBoundsCompletely() const override;
  size_t GetApproximateUnsharedMemoryUsage() const override;

  cc::Layer* cc_layer_for_testing() { return cc_layer_; }

  // TextureLayerClient implementation.
  bool PrepareTransferableResource(
      viz::TransferableResource* resource,
      std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override;

  float device_scale_factor() const { return device_scale_factor_; }

  // LayerClient implementation.
  std::unique_ptr<base::trace_event::ConvertableToTraceFormat> TakeDebugInfo(
      cc::Layer* layer) override;
  void didUpdateMainThreadScrollingReasons() override;
  void didChangeScrollbarsHidden(bool) override;

  // Triggers a call to SwitchToLayer.
  void SwitchCCLayerForTest();

  const cc::Region& damaged_region_for_testing() const {
    return damaged_region_;
  }

  const gfx::Size& frame_size_in_dip_for_testing() const {
    return frame_size_in_dip_;
  }

  // Force use of and cache render surface. Note that this also disables
  // occlusion culling in favor of efficient caching. This should
  // only be used when paying the cost of creating a render
  // surface even if layer is invisible is not a problem.
  void AddCacheRenderSurfaceRequest();
  void RemoveCacheRenderSurfaceRequest();

  // Request deferring painting for layer.
  void AddDeferredPaintRequest();
  void RemoveDeferredPaintRequest();

  bool IsPaintDeferredForTesting() const { return deferred_paint_requests_; }

  // Request trilinear filtering for layer.
  void AddTrilinearFilteringRequest();
  void RemoveTrilinearFilteringRequest();

  // 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.
  const Layer* layer_mask_back_link() const { return layer_mask_back_link_; }

 private:
  friend class LayerOwner;
  class LayerMirror;

  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::PointF* point) const;
  bool ConvertPointFromAncestor(const Layer* ancestor,
                                gfx::PointF* point) const;

  // Implementation of LayerAnimatorDelegate
  void SetBoundsFromAnimation(const gfx::Rect& bounds,
                              PropertyChangeReason reason) override;
  void SetTransformFromAnimation(const gfx::Transform& transform,
                                 PropertyChangeReason reason) override;
  void SetOpacityFromAnimation(float opacity,
                               PropertyChangeReason reason) override;
  void SetVisibilityFromAnimation(bool visibility,
                                  PropertyChangeReason reason) override;
  void SetBrightnessFromAnimation(float brightness,
                                  PropertyChangeReason reason) override;
  void SetGrayscaleFromAnimation(float grayscale,
                                 PropertyChangeReason reason) override;
  void SetColorFromAnimation(SkColor color,
                             PropertyChangeReason reason) 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;
  ui::Layer* GetLayer() override;
  cc::Layer* GetCcLayer() const override;
  LayerThreadedAnimationDelegate* GetThreadedAnimationDelegate() override;
  LayerAnimatorCollection* GetLayerAnimatorCollection() override;
  int GetFrameNumber() const override;
  float GetRefreshRate() const 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);

  void SetCompositorForAnimatorsInTree(Compositor* compositor);
  void ResetCompositorForAnimatorsInTree(Compositor* compositor);

  void OnMirrorDestroyed(LayerMirror* mirror);

  const LayerType type_;

  Compositor* compositor_;

  Layer* parent_;

  // This layer's children, in bottom-to-top stacking order.
  std::vector<Layer*> children_;

  std::vector<std::unique_ptr<LayerMirror>> mirrors_;

  // If true, changes to the bounds of this layer are propagated to mirrors.
  bool sync_bounds_ = false;

  gfx::Rect bounds_;
  gfx::Vector2dF subpixel_position_offset_;

  // Visibility of this layer. See SetVisible/IsDrawn for more details.
  bool visible_;

  // See SetFillsBoundsOpaquely(). Defaults to true.
  bool fills_bounds_opaquely_;

  bool fills_bounds_completely_;

  // Union of damaged rects, in layer space, that SetNeedsDisplayRect should
  // be called on.
  cc::Region damaged_region_;

  // Union of damaged rects, in layer space, to be used when compositor is ready
  // to paint the content.
  cc::Region paint_region_;

  float background_blur_sigma_;

  // Several variables which will change the visible representation of
  // the layer.
  float layer_saturation_;
  float layer_brightness_;
  float layer_grayscale_;
  bool layer_inverted_;
  float layer_blur_sigma_;

  // 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.
  std::unique_ptr<ShapeRects> alpha_shape_;

  std::string name_;

  LayerDelegate* delegate_;

  base::ObserverList<LayerObserver> observer_list_;

  LayerOwner* owner_;

  scoped_refptr<LayerAnimator> animator_;

  // 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::SurfaceLayer> surface_layer_;
  cc::Layer* cc_layer_;

  // A cached copy of |Compositor::device_scale_factor()|.
  float device_scale_factor_;

  // A cached copy of the nine patch layer's image and aperture.
  // These are required for device scale factor change.
  gfx::ImageSkia nine_patch_layer_image_;
  gfx::Rect nine_patch_layer_aperture_;

  // The external resource used by texture_layer_.
  viz::TransferableResource transfer_resource_;

  // The callback to release the mailbox. This is only set after
  // SetTransferableResource() is called, before we give it to the TextureLayer.
  std::unique_ptr<viz::SingleReleaseCallback> transfer_release_callback_;

  // The size of the frame or texture in DIP, set when SetShowDelegatedContent
  // or SetTransferableResource() was called.
  gfx::Size frame_size_in_dip_;

  // The counter to maintain how many cache render surface requests we have. If
  // the value > 0, means we need to cache the render surface. If the value
  // == 0, means we should not cache the render surface.
  unsigned cache_render_surface_requests_;

  // The counter to maintain how many deferred paint requests we have. If the
  // value > 0, means we need to defer painting the layer. If the value == 0,
  // means we should paint the layer.
  unsigned deferred_paint_requests_;

  // The counter to maintain how many trilinear filtering requests we have. If
  // the value > 0, means we need to perform trilinear filtering on the layer.
  // If the value == 0, means we should not perform trilinear filtering on the
  // layer.
  unsigned trilinear_filtering_request_;

  DISALLOW_COPY_AND_ASSIGN(Layer);
};

}  // namespace ui

#endif  // UI_COMPOSITOR_LAYER_H_
