// Copyright 2010 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_LAYERS_LAYER_H_
#define CC_LAYERS_LAYER_H_

#include <stddef.h>
#include <stdint.h>

#include <array>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "cc/base/region.h"
#include "cc/benchmarks/micro_benchmark.h"
#include "cc/cc_export.h"
#include "cc/input/input_handler.h"
#include "cc/input/overscroll_behavior.h"
#include "cc/input/scroll_snap_data.h"
#include "cc/layers/layer_collections.h"
#include "cc/layers/layer_position_constraint.h"
#include "cc/layers/touch_action_region.h"
#include "cc/paint/filter_operations.h"
#include "cc/paint/paint_record.h"
#include "cc/trees/element_id.h"
#include "cc/trees/property_tree.h"
#include "cc/trees/target_property.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/rrect_f.h"
#include "ui/gfx/transform.h"

namespace base {
namespace trace_event {
class TracedValue;
}
}

namespace viz {
class CopyOutputRequest;
}

namespace cc {

class LayerClient;
class LayerImpl;
class LayerTreeHost;
class LayerTreeHostCommon;
class LayerTreeImpl;
class PictureLayer;

// Base class for composited layers. Special layer types are derived from
// this class. Each layer is an independent unit in the compositor, be that
// for transforming or for content. If a layer has content it can be
// transformed efficiently without requiring the content to be recreated.
// Layers form a tree, with each layer having 0 or more children, and a single
// parent (or none at the root). Layers within the tree, other than the root
// layer, are kept alive by that tree relationship, with refpointer ownership
// from parents to children.
class CC_EXPORT Layer : public base::RefCounted<Layer> {
 public:
  // An invalid layer id, as all layer ids are positive.
  enum LayerIdLabels {
    INVALID_ID = -1,
  };

  // A layer can be attached to another layer as a mask for it. These
  // describe how the mask would be generated as a texture in that case.
  enum LayerMaskType {
    NOT_MASK = 0,
    MULTI_TEXTURE_MASK,
    SINGLE_TEXTURE_MASK,
  };

  // Factory to create a new Layer, with a unique id.
  static scoped_refptr<Layer> Create();

  Layer(const Layer&) = delete;
  Layer& operator=(const Layer&) = delete;

  // Sets an optional client on this layer, that will be called when relevant
  // events happen. The client is a WeakPtr so it can be destroyed without
  // unsetting itself as the client.
  void SetLayerClient(base::WeakPtr<LayerClient> client);
  LayerClient* GetLayerClientForTesting() const { return inputs_.client.get(); }

  // A unique and stable id for the Layer. Ids are always positive.
  int id() const { return inputs_.layer_id; }

  // Returns a pointer to the highest ancestor of this layer, or itself.
  Layer* RootLayer();
  // Returns a pointer to the direct ancestor of this layer if it exists,
  // or null.
  Layer* parent() { return parent_; }
  const Layer* parent() const { return parent_; }
  // Appends |child| to the list of children of this layer, and maintains
  // ownership of a reference to that |child|.
  void AddChild(scoped_refptr<Layer> child);
  // Inserts |child| into the list of children of this layer, before position
  // |index| (0 based) and maintains ownership of a reference to that |child|.
  void InsertChild(scoped_refptr<Layer> child, size_t index);
  // Removes an existing child |reference| from this layer's list of children,
  // and inserts |new_layer| it its place in the list. This layer maintains
  // ownership of a reference to the |new_layer|. The |new_layer| may be null,
  // in which case |reference| is simply removed from the list of children,
  // which ends this layers ownership of the child.
  void ReplaceChild(Layer* reference, scoped_refptr<Layer> new_layer);
  // Removes this layer from the list of children in its parent, removing the
  // parent's ownership of this layer.
  void RemoveFromParent();
  // Removes all children from this layer's list of children, removing ownership
  // of those children.
  void RemoveAllChildren();
  // Sets the children while minimizing changes to layers that are already
  // children of this layer.
  void SetChildLayerList(LayerList children);
  // Returns true if |ancestor| is this layer's parent or higher ancestor.
  bool HasAncestor(const Layer* ancestor) const;

  // The list of children of this layer.
  const LayerList& children() const { return inputs_.children; }

  // Gets the LayerTreeHost that this layer is attached to, or null if not.
  // A layer is attached to a LayerTreeHost if it or an ancestor layer is set as
  // the root layer of a LayerTreeHost (while noting only a layer without a
  // parent may be set as the root layer).
  LayerTreeHost* layer_tree_host() const { return layer_tree_host_; }

  // This requests the layer and its subtree be rendered and given to the
  // callback. If the copy is unable to be produced (the layer is destroyed
  // first), then the callback is called with a nullptr/empty result. If the
  // request's source property is set, any prior uncommitted requests having the
  // same source will be aborted.
  void RequestCopyOfOutput(std::unique_ptr<viz::CopyOutputRequest> request);
  // True if a copy request has been inserted on this layer and a commit has not
  // occured yet.
  bool HasCopyRequest() const { return !inputs_.copy_requests.empty(); }

  // Set and get the background color for the layer. This color is not used by
  // basic Layers, but subclasses may make use of it.
  virtual void SetBackgroundColor(SkColor background_color);
  SkColor background_color() const { return inputs_.background_color; }

  // Internal to property tree generation. Sets an opaque background color for
  // the layer, to be used in place of the background_color() if the layer says
  // contents_opaque() is true.
  void SetSafeOpaqueBackgroundColor(SkColor background_color);
  // Returns a background color with opaque-ness equal to the value of
  // contents_opaque().
  // If the layer says contents_opaque() is true, this returns the value set by
  // SetSafeOpaqueBackgroundColor() which should be an opaque color. Otherwise,
  // it returns something non-opaque. It prefers to return the
  // background_color(), but if the background_color() is opaque (and this layer
  // claims to not be), then SK_ColorTRANSPARENT is returned.
  SkColor SafeOpaqueBackgroundColor() const;
  // For testing, return the actual stored value.
  SkColor ActualSafeOpaqueBackgroundColorForTesting() const {
    return safe_opaque_background_color_;
  }

  // Set and get the position of this layer, relative to its parent. This is
  // specified in layer space, which excludes device scale and page scale
  // factors, and ignoring transforms for this layer or ancestor layers. The
  // root layer's position is not used as it always appears at the origin of
  // the viewport. When property trees are built by cc (when IsUsingLayerLists
  // is false), position is used to update |offset_to_transform_parent|.
  void SetPosition(const gfx::PointF& position);
  const gfx::PointF& position() const { return inputs_.position; }

  // Reorder the entirety of the children() vector to follow new_children_order.
  // All elements inside new_children_order must be inside children(), and vice
  // versa. Will empty the |new_children_order| LayerList passed into this
  // method.
  void ReorderChildren(LayerList* new_children_order);

  // Set and get the layers bounds. This is specified in layer space, which
  // excludes device scale and page scale factors, and ignoring transforms for
  // this layer or ancestor layers.
  //
  // The root layer in the tree has bounds in viewport space, which includes
  // the device scale factor.
  void SetBounds(const gfx::Size& bounds);
  const gfx::Size& bounds() const { return inputs_.bounds; }

  // Set and get the behaviour to be applied for compositor-thread scrolling of
  // this layer beyond the beginning or end of the layer's content.
  // TODO(bokan): With blink-gen-property-trees this is stored on the
  // ScrollNode and can be removed here.
  void SetOverscrollBehavior(const OverscrollBehavior& behavior);
  OverscrollBehavior overscroll_behavior() const {
    return inputs_.overscroll_behavior;
  }

  // Set and get the snapping behaviour for compositor-thread scrolling of
  // this layer. The default value of null means there is no snapping for the
  // layer.
  // TODO(crbug.com/836884) With blink-gen-property-trees this is stored on the
  // ScrollNode and can be removed here.
  void SetSnapContainerData(base::Optional<SnapContainerData> data);
  const base::Optional<SnapContainerData>& snap_container_data() const {
    return inputs_.snap_container_data;
  }

  // Set or get that this layer clips its subtree to within its bounds. Content
  // of children will be intersected with the bounds of this layer when true.
  void SetMasksToBounds(bool masks_to_bounds);
  bool masks_to_bounds() const { return inputs_.masks_to_bounds; }

  // Set or get a layer that is not an ancestor of this layer, but which should
  // be clipped to this layer's bounds if SetMasksToBounds() is set to true.
  // The parent layer does *not* retain ownership of a reference on this layer.
  void SetClipParent(Layer* ancestor);
  Layer* clip_parent() { return inputs_.clip_parent; }

  // The set of layers which are not in this layers subtree but which should be
  // clipped to only appear within this layer's bounds.
  std::set<Layer*>* clip_children() { return clip_children_.get(); }
  const std::set<Layer*>* clip_children() const { return clip_children_.get(); }

  // Set or get a layer that will mask the contents of this layer. The alpha
  // channel of the mask layer's content is used as an alpha mask of this
  // layer's content. IOW the mask's alpha is multiplied by this layer's alpha
  // for each matching pixel.
  void SetMaskLayer(PictureLayer* mask_layer);
  PictureLayer* mask_layer() { return inputs_.mask_layer.get(); }

  // Marks the |dirty_rect| as being changed, which will cause a commit and
  // the compositor to submit a new frame with a damage rect that includes the
  // layer's dirty area. This rect is in layer space, the same as bounds().
  virtual void SetNeedsDisplayRect(const gfx::Rect& dirty_rect);
  // Marks the entire layer's bounds as being changed, which will cause a commit
  // and the compositor to submit a new frame with a damage rect that includes
  // the entire layer. Note that if the layer resizes afterward, but before
  // commit, the dirty rect would not cover the layer, however then the layer
  // bounds change would implicitly damage the full layer.
  void SetNeedsDisplay() { SetNeedsDisplayRect(gfx::Rect(bounds())); }
  // Returns the union of previous calls to SetNeedsDisplayRect() and
  // SetNeedsDisplay() that have not been committed to the compositor thread.
  const gfx::Rect& update_rect() const { return inputs_.update_rect; }

  // Set or get the rounded corner radii which is applied to the layer and its
  // subtree (as if they are together as a single composited entity) when
  // blitting into their target. Setting this makes the layer masked to bounds.
  void SetRoundedCorner(const gfx::RoundedCornersF& corner_radii);
  const gfx::RoundedCornersF& corner_radii() const {
    return inputs_.corner_radii;
  }

  // Returns true if any of the corner has a non-zero radius set.
  bool HasRoundedCorner() const { return !corner_radii().IsEmpty(); }

  // Set or get the flag that disables the requirement of a render surface for
  // this layer due to it having rounded corners. This improves performance at
  // the cost of maybe having some blending artifacts. Not having a render
  // surface is not guaranteed however.
  void SetIsFastRoundedCorner(bool enable);
  bool is_fast_rounded_corner() const { return inputs_.is_fast_rounded_corner; }

  // Set or get the opacity which should be applied to the contents of the layer
  // and its subtree (together as a single composited entity) when blending them
  // into their target. Note that this does not speak to the contents of this
  // layer, which may be opaque or not (see contents_opaque()). Note that the
  // opacity is cumulative since it applies to the layer's subtree.
  virtual void SetOpacity(float opacity);
  float opacity() const { return inputs_.opacity; }
  // Gets the true opacity that will be used for blending the contents of this
  // layer and its subtree into its target during composite. This value is the
  // same as the user-specified opacity() unless the layer should not be visible
  // at all for other reasons, in which case the opacity here becomes 0.
  float EffectiveOpacity() const;

  // Set or get the blend mode to be applied when blending the contents of the
  // layer and its subtree (together as a single composited entity) when
  // blending them into their target.
  void SetBlendMode(SkBlendMode blend_mode);
  SkBlendMode blend_mode() const { return inputs_.blend_mode; }

  // A layer is root for an isolated group when it and all its descendants are
  // drawn over a black and fully transparent background, creating an isolated
  // group. It should be used along with SetBlendMode(), in order to restrict
  // layers within the group to blend with layers outside this group.
  void SetIsRootForIsolatedGroup(bool root);
  bool is_root_for_isolated_group() const {
    return inputs_.is_root_for_isolated_group;
  }

  // Set or get the list of filter effects to be applied to the contents of the
  // layer and its subtree (together as a single composited entity) when
  // drawing them into their target.
  void SetFilters(const FilterOperations& filters);
  const FilterOperations& filters() const { return inputs_.filters; }

  // Set or get the origin to be used when applying the filters given to
  // SetFilters(). By default the origin is at the origin of this layer, but
  // may be moved positively or negatively relative to that. The origin effects
  // any filters which do not apply uniformly to the entire layer and its
  // subtree.
  void SetFiltersOrigin(const gfx::PointF& origin);
  gfx::PointF filters_origin() const { return inputs_.filters_origin; }

  // Set or get the list of filters that should be applied to the content this
  // layer and its subtree will be drawn into. The effect is clipped by
  // backdrop_filter_bounds.
  void SetBackdropFilters(const FilterOperations& filters);
  const FilterOperations& backdrop_filters() const {
    return inputs_.backdrop_filters;
  }

  void SetBackdropFilterBounds(const gfx::RRectF& backdrop_filter_bounds);
  void ClearBackdropFilterBounds();
  const base::Optional<gfx::RRectF>& backdrop_filter_bounds() const {
    return inputs_.backdrop_filter_bounds;
  }

  void SetBackdropFilterQuality(const float quality);
  float backdrop_filter_quality() const {
    return inputs_.backdrop_filter_quality;
  }

  // Set or get an optimization hint that the contents of this layer are fully
  // opaque or not. If true, every pixel of content inside the layer's bounds
  // must be opaque or visual errors can occur. This applies only to this layer
  // and not to children, and does not imply the layer should be composited
  // opaquely, as effects may be applied such as opacity() or filters().
  void SetContentsOpaque(bool opaque);
  bool contents_opaque() const { return inputs_.contents_opaque; }

  // Set or get whether this layer should be a hit test target
  void SetHitTestable(bool should_hit_test);
  bool HitTestable() const;

  // Set or gets if this layer is a container for fixed position layers in its
  // subtree. Such layers will be positioned and transformed relative to this
  // layer instead of their direct parent.
  //
  // A layer that is a container for fixed position layers cannot be both
  // scrollable and have a non-identity transform.
  void SetIsContainerForFixedPositionLayers(bool container);
  bool IsContainerForFixedPositionLayers() const;

  // Set or get constraints applied to the layer's position, where it may be
  // in a fixed position relative to the nearest ancestor that returns true for
  // IsContainerForFixedPositionLayers(). This may also specify which edges
  // of the layer are fixed to the same edges of the container ancestor. When
  // fixed position, this layer's transform will be appended to the container
  // ancestor's transform instead of to this layer's direct parent's.
  // Position constraints are only used by the cc property tree builder to build
  // property trees and are not needed when using layer lists.
  void SetPositionConstraint(const LayerPositionConstraint& constraint);
  const LayerPositionConstraint& position_constraint() const {
    return inputs_.position_constraint;
  }

  // Set or get constraints applied to the layer's position, where it may act
  // like a normal layer until, during scroll, its position triggers it to
  // become fixed position relative to its scroller. See CSS position: sticky
  // for more details.
  void SetStickyPositionConstraint(
      const LayerStickyPositionConstraint& constraint);
  const LayerStickyPositionConstraint& sticky_position_constraint() const {
    return inputs_.sticky_position_constraint;
  }

  // On some platforms (Android renderer) the viewport may resize during scroll
  // on the compositor thread. During this resize and until the main thread
  // matches, position fixed layers may need to have their position adjusted on
  // the compositor thread to keep them fixed in place.  If
  // IsContainerForFixedPositionLayers() is true for this layer, these set and
  // get whether fixed position descendants of this layer should have this
  // adjustment to their position applied during such a viewport resize.
  // This value is only used by the cc property tree builder to build property
  // trees and is not needed when using layer lists.
  void SetIsResizedByBrowserControls(bool resized);
  bool IsResizedByBrowserControls() const;

  // Set or get the transform to be used when compositing this layer into its
  // target. The transform is inherited by this layers children.
  void SetTransform(const gfx::Transform& transform);
  const gfx::Transform& transform() const { return inputs_.transform; }

  // Gets the transform, including transform origin and position, of this layer
  // and its ancestors, device scale and page scale factors, into the device
  // viewport.
  gfx::Transform ScreenSpaceTransform() const;

  // Set or get the origin to be used when applying the transform. The value is
  // a position in layer space, relative to the top left corner of this layer.
  // For instance, if set to the center of the layer, with a transform to rotate
  // 180deg around the X axis, it would flip the layer vertically around the
  // center of the layer, leaving it occupying the same space. Whereas set to
  // the top left of the layer, the rotation wouldoccur around the top of the
  // layer, moving it vertically while flipping it.
  void SetTransformOrigin(const gfx::Point3F&);
  const gfx::Point3F& transform_origin() const {
    return inputs_.transform_origin;
  }

  // Set or get a scroll parent layer. It is not an ancestor of this layer, but
  // this layer will be moved by the scroll parent's scroll offset.
  void SetScrollParent(Layer* parent);
  Layer* scroll_parent() { return inputs_.scroll_parent; }

  // Set or get the scroll offset of the layer. The content of the layer, and
  // position of its subtree, as well as other layers for which this layer is
  // their scroll parent, and their subtrees) is moved up by the amount of
  // offset specified here.
  void SetScrollOffset(const gfx::ScrollOffset& scroll_offset);
  // Accessor named to match LayerImpl for templated code.
  const gfx::ScrollOffset& CurrentScrollOffset() const {
    return inputs_.scroll_offset;
  }

  // Called internally during commit to update the layer with state from the
  // compositor thread. Not to be called externally by users of this class.
  void SetScrollOffsetFromImplSide(const gfx::ScrollOffset& scroll_offset);

  // Marks this layer as being scrollable and needing an associated scroll node,
  // and specifies the total size of the content to be scrolled (ie the max
  // scroll offsets. The size should be a union of the layer and its subtree, as
  // well as any layers for whom this layer is their scroll parent, and their
  // subtrees, when they are transformed into this layer's space. Thus
  // transforms of children affect the size of the |scroll_container_bounds|.
  // Once scrollable, a Layer cannot become un-scrollable.
  void SetScrollable(const gfx::Size& scroll_container_bounds);
  bool scrollable() const { return inputs_.scrollable; }
  const gfx::Size& scroll_container_bounds() const {
    return inputs_.scroll_container_bounds;
  }

  void SetIsScrollbar(bool is_scrollbar);
  bool is_scrollbar() const { return inputs_.is_scrollbar; }

  // Set or get if this layer is able to be scrolled along each axis. These are
  // independent of the scrollable state, or size of the scrollable area
  // specified in SetScrollable(), as these may be enabled or disabled
  // dynamically, while SetScrollable() defines what would be possible if these
  // are enabled.
  // When disabled, overscroll elasticity will not be used if the scroll offset
  // ends up past the maximum range. And when enabled, with overlay scrollbars,
  // the scrollbars will be shown when the scroll offset changes if these are
  // set to true.
  void SetUserScrollable(bool horizontal, bool vertical);
  bool GetUserScrollableHorizontal() const;
  bool GetUserScrollableVertical() const;

  // Set or get if this layer is able to be scrolled on the compositor thread.
  // This only applies for layers that are marked as scrollable, not for layers
  // that are moved by a scroll parent. When any reason is present, the layer
  // will not be scrolled on the compositor thread. The reasons are a set of
  // bitflags from MainThreadScrollingReason, used to track the reason for
  // debugging and reporting.
  // AddMainThreadScrollingReasons() is used to add flags to the current set,
  // and ClearMainThreadScrollingReasons() removes flags from the current set.
  void AddMainThreadScrollingReasons(uint32_t main_thread_scrolling_reasons);
  void ClearMainThreadScrollingReasons(
      uint32_t main_thread_scrolling_reasons_to_clear);
  uint32_t GetMainThreadScrollingReasons() const;

  // Set or get an area of this layer within which initiating a scroll can not
  // be done from the compositor thread. Within this area, if the user attempts
  // to start a scroll, the events must be sent to the main thread and processed
  // there.
  void SetNonFastScrollableRegion(const Region& non_fast_scrollable_region);
  const Region& non_fast_scrollable_region() const {
    return inputs_.non_fast_scrollable_region;
  }

  // Set or get the set of touch actions allowed across each point of this
  // layer. The |touch_action_region| can specify, for any number of areas,
  // which touch actions are allowed in each area. The result is the
  // intersection of overlapping areas. These allowed actions control if
  // a touch event can initiate a scroll or zoom on the compositor thread.
  void SetTouchActionRegion(TouchActionRegion touch_action_region);
  const TouchActionRegion& touch_action_region() const {
    return inputs_.touch_action_region;
  }

  // Sets a RepeatingCallback that is run during a main frame, before layers are
  // asked to prepare content with Update(), if the scroll offset for the layer
  // was changed by the InputHandlerClient, on the compositor thread (or on the
  // main thread in single-thread mode). It may be set to a null callback, in
  // which case nothing is called.
  void set_did_scroll_callback(
      base::RepeatingCallback<void(const gfx::ScrollOffset&, const ElementId&)>
          callback) {
    inputs_.did_scroll_callback = std::move(callback);
  }

  // Set or get if the layer and its subtree should be cached as a texture in
  // the display compositor. This is used as an optimization when it is known
  // that the layer will be animated without changing its content, or any of its
  // subtree.
  //
  // Note that this also disables occlusion culling, as the entire texture will
  // be drawn so that it is not left with incomplete areas. This should only be
  // used when paying the cost of creating an intermediate texture is worth it,
  // even when the layer's subtree may be occluded, or not visible in the final
  // output.
  void SetCacheRenderSurface(bool cache_render_surface);
  bool cache_render_surface() const { return cache_render_surface_; }

  // Set or get if the layer and its subtree will be drawn through an
  // intermediate texture, called a RenderSurface. This mimics the need
  // for a RenderSurface that is caused by compositing effects such as masks
  // without needing to set up such effects.
  void SetForceRenderSurfaceForTesting(bool force_render_surface);
  bool force_render_surface_for_testing() const {
    return force_render_surface_for_testing_;
  }

  // Set or get if this layer should continue to be visible when rotated such
  // that its back face is facing toward the camera. If false, the layer will
  // disappear when its back face is visible, but if true, the mirror image of
  // its front face will be shown. For instance, with a 180deg rotation around
  // the middle of the layer on the Y axis, if this is false then nothing is
  // visible. But if true, the layer is seen with its contents flipped along the
  // Y axis. Being single-sided applies transitively to the subtree of this
  // layer. If it is hidden because of its back face being visible, then its
  // subtree will be too (even if a subtree layer's front face would have been
  // visible).
  //
  // Note that should_check_backface_visibility() is the final computed value
  // for back face visibility, which is only for internal use.
  void SetDoubleSided(bool double_sided);
  bool double_sided() const { return inputs_.double_sided; }

  // Set or get if SetDoubleSided() for this layer should be ignored and
  // inherited directly from this layer's parent instead. Used to attach this
  // layer's backface visibility to the value of its parent.
  //
  // Note that should_check_backface_visibility() is the final computed value
  // for back face visibility, which is only for internal use.
  void SetUseParentBackfaceVisibility(bool use);
  bool use_parent_backface_visibility() const {
    return inputs_.use_parent_backface_visibility;
  }

  // Set or get if the subtree of this layer is composited in 3d-space, or if
  // the layers are flattened into the plane of this layer. This supports the
  // transform-style CSS property.
  void SetShouldFlattenTransform(bool flatten);
  bool should_flatten_transform() const {
    return inputs_.should_flatten_transform;
  }

  // Set or get a 3d sorting context for this layer, where adjacent layers (in a
  // pre-order traversal) with the same id are sorted as a group and may occlude
  // each other based on their z-position, including intersecting each other and
  // each occluding the other layer partially. Layers in different sorting
  // contexts will be composited and occlude in tree order (children occlude
  // ancestors and earlier siblings in the children list). If the |id| is 0,
  // then the layer is not part of any sorting context, and is always composited
  // in tree order.
  void Set3dSortingContextId(int id);
  int sorting_context_id() const { return inputs_.sorting_context_id; }

  // When true the layer may contribute to the compositor's output. When false,
  // it does not. This property does not apply to children of the layer, they
  // may contribute while this layer does not. The layer itself will determine
  // if it has content to contribute, but when false, this prevents it from
  // doing so.
  void SetIsDrawable(bool is_drawable);
  // Is true if the layer will contribute content to the compositor's output.
  // Will be false if SetIsDrawable(false) is called. But will also be false if
  // the layer itself has no content to contribute, even though the layer was
  // given SetIsDrawable(true).
  bool DrawsContent() const;

  // Returns the number of layers in this layers subtree (excluding itself) for
  // which DrawsContent() is true.
  int NumDescendantsThatDrawContent() const;

  // Set or get if this layer and its subtree should be part of the compositor's
  // output to the screen. When set to true, the layer's subtree does not appear
  // to the user, but still remains part of the tree with all its normal drawing
  // properties. This can be used to execute a CopyOutputRequest on this layer
  // or another in its subtree, since the layers are still able to be drawn by
  // the compositor, while not being composed into the result shown to the user.
  void SetHideLayerAndSubtree(bool hide);
  bool hide_layer_and_subtree() const { return inputs_.hide_layer_and_subtree; }

  // The index of this layer's node in the various property trees. These are
  // only valid after a main frame, when Update() is called on the layer, and
  // remain valid and in in the same state until the next main frame, or until
  // the layer is removed from its LayerTreeHost. Otherwise kInvalidNodeId is
  // returned.
  int transform_tree_index() const;
  int clip_tree_index() const;
  int effect_tree_index() const;
  int scroll_tree_index() const;

  // While all layers have an index into the transform tree, this value
  // indicates whether the transform tree node was created for this layer.
  void SetHasTransformNode(bool val) { has_transform_node_ = val; }
  bool has_transform_node() { return has_transform_node_; }

  // Sets that the content shown in this layer may be a video. This may be used
  // by the system compositor to distinguish between animations updating the
  // screen and video, which the user would be watching. This allows
  // optimizations like turning off the display when video is not playing,
  // without interfering with video playback.
  void SetMayContainVideo(bool yes);

  // Stable identifier for clients. See comment in cc/trees/element_id.h.
  void SetElementId(ElementId id);
  ElementId element_id() const { return inputs_.element_id; }

  // Sets or gets a hint that the transform on this layer (including its
  // position) may be changed often in the future. The layer may change its
  // strategy for generating content as a result. PictureLayers will not attempt
  // to raster crisply as the transform changes, allowing the client to trade
  // off crisp content at each scale for a smoother visual and cheaper
  // animation.
  void SetHasWillChangeTransformHint(bool has_will_change);
  bool has_will_change_transform_hint() const {
    return inputs_.has_will_change_transform_hint;
  }

  // Sets or gets if trilinear filtering should be used to scaling the contents
  // of this layer and its subtree. When set the layer and its subtree will be
  // composited together as a single unit, mip maps will be generated of the
  // subtree together, and trilinear filtering applied when supported, if
  // scaling during composite of the content from this layer and its subtree
  // into the target.
  void SetTrilinearFiltering(bool trilinear_filtering);
  bool trilinear_filtering() const { return inputs_.trilinear_filtering; }

  // Called on the scroll layer to trigger showing the overlay scrollbars.
  void ShowScrollbars() { needs_show_scrollbars_ = true; }

  // Captures text content within the given |rect| and returns the associated
  // NodeHolder in content.
  virtual void CaptureContent(const gfx::Rect& rect,
                              std::vector<NodeHolder>* content);

  // For tracing. Gets a recorded rasterization of this layer's contents that
  // can be displayed inside representations of this layer. May return null, in
  // which case the layer won't be shown with any content in the tracing
  // display.
  virtual sk_sp<SkPicture> GetPicture() const;

  // For tracing. Calls out to the LayerClient to get tracing data that will
  // be attached to this layer's tracing outputs under the 'debug_info' key.
  void UpdateDebugInfo();

  // For telemetry testing. Runs a given test behaviour implemented in
  // |benchmark| for this layer. The base class does nothing as benchmarks
  // only exist for subclass layer types. For each subclass that the
  // MicroBenchmark supports, the class should override this method and run the
  // |benchmark| against this layer.
  virtual void RunMicroBenchmark(MicroBenchmark* benchmark);

  // Internal method to create the compositor thread type for this Layer.
  // Subclasses should override this method if they want to return their own
  // subclass of LayerImpl instead.
  virtual std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl);

  // Internal method to copy all state from this Layer to the compositor thread.
  // Should be overridden by any subclass that has additional state, to copy
  // that state as well. The |layer| passed in will be of the type created by
  // CreateLayerImpl(), so can be safely down-casted if the subclass uses a
  // different type for the compositor thread.
  virtual void PushPropertiesTo(LayerImpl* layer);

  // Internal method to be overridden by Layer subclasses that need to do work
  // during a main frame. The method should compute any state that will need to
  // propogated to the compositor thread for the next commit, and return true
  // if there is anything new to commit. If all layers return false, the commit
  // may be aborted.
  virtual bool Update();
  // Internal method to be overriden by Layer subclasses that override Update()
  // and require rasterization. After Update() is called, this is immediately
  // called, and should return whether the layer will require rasterization of
  // paths that will be difficult/slow to raster. Only layers that do
  // rasterization via TileManager need to override this, other layers that have
  // content generated in other ways may leave it as the default.
  virtual bool HasSlowPaths() const;
  // Internal method to be overriden by Layer subclasses that override Update()
  // and require rasterization. After Update() is called, this is immediately
  // called, and should return whether the layer will require rasterization of a
  // drawing operation that must not be anti-aliased. In this case using MSAA to
  // antialias the entire layer's content would produce an incorrect result.
  // This result is considered sticky, once a layer returns true, so false
  // positives should be avoided. Only layers that do rasterization via
  // TileManager need to override this, other layers that have content generated
  // in other ways may leave it as the default.
  virtual bool HasNonAAPaint() const;

  // Internal to property tree construction. This allows a layer to request that
  // its transform should be snapped such that the layer aligns with the pixel
  // grid in its rendering target. This ensures that the layer is not fuzzy
  // (unless it is being scaled). Layers may override this to return true, by
  // default layers are not snapped.
  virtual bool IsSnappedToPixelGridInTarget();

  // Internal method that is called when a Layer is attached to a LayerTreeHost.
  // This would happen when
  // a) the Layer is added to an existing Layer tree that is attached to a
  // LayerTreeHost.
  // b) the Layer is made the root layer of a LayerTreeHost.
  // c) the Layer is part of a Layer tree, and an ancestor is attached to a
  // LayerTreeHost via a) or b).
  // The |host| is the new LayerTreeHost which the Layer is now attached to.
  // Subclasses may override this if they have data or resources which are
  // specific to a LayerTreeHost that should be updated or reset. After this
  // returns the Layer will hold a pointer to the new LayerTreeHost.
  virtual void SetLayerTreeHost(LayerTreeHost* host);

  // Internal method to mark this layer as needing to push its state to the
  // compositor thread during the next commit. The PushPropertiesTo() method
  // will be called for this layer during the next commit only if this method
  // was called before it.
  void SetNeedsPushProperties();

  // Internal method to call the LayerClient, if there is one, to inform it when
  // overlay scrollbars have been completely hidden (due to lack of scrolling by
  // the user).
  void SetScrollbarsHiddenFromImplSide(bool hidden);

  // Internal to property tree construction. A generation number for the
  // property trees, to verify the layer's indices are pointers into the trees
  // currently held by the LayerTreeHost. The number is updated when property
  // trees are built from the Layer tree.
  void set_property_tree_sequence_number(int sequence_number) {
    property_tree_sequence_number_ = sequence_number;
  }
  int property_tree_sequence_number() const {
    return property_tree_sequence_number_;
  }

  // Internal to property tree construction. Sets the index for this Layer's
  // node in each property tree.
  void SetTransformTreeIndex(int index);
  void SetClipTreeIndex(int index);
  void SetEffectTreeIndex(int index);
  void SetScrollTreeIndex(int index);

  // The position of this layer after transforming by the layer's transform
  // node. When property trees are built by cc (when IsUsingLayerLists is false)
  // this is set by property_tree_builder.cc.
  void SetOffsetToTransformParent(gfx::Vector2dF offset);
  gfx::Vector2dF offset_to_transform_parent() const {
    return offset_to_transform_parent_;
  }

  // Internal to property tree construction. Indicates that a property changed
  // on this layer that may affect the position or content of all layers in this
  // layer's subtree, including itself. This causes the layer's subtree to be
  // considered damaged and re-displayed to the user.
  void SetSubtreePropertyChanged();
  bool subtree_property_changed() const { return subtree_property_changed_; }

  // Internal to property tree construction. Returns ElementListType::ACTIVE
  // as main thread layers do not have a pending/active tree split, and
  // animations should run normally on the main thread layer tree.
  ElementListType GetElementTypeForAnimation() const;

  // Internal to property tree construction. Whether this layer may animate its
  // opacity on the compositor thread. Layer subclasses may override this to
  // report true. If true, assumptions about opacity can not be made on the main
  // thread.
  virtual bool OpacityCanAnimateOnImplThread() const;

  // Internal to property tree construction. Set to true if this layer or any
  // layer below it in the tree has a CopyOutputRequest pending commit.
  void SetSubtreeHasCopyRequest(bool subtree_has_copy_request);
  // Internal to property tree construction. Returns true if this layer or any
  // layer below it in the tree has a CopyOutputRequest pending commit.
  bool SubtreeHasCopyRequest() const;
  // Internal to property tree construction. Removes all CopyOutputRequests from
  // this layer, moving them into |requests|.
  void TakeCopyRequests(
      std::vector<std::unique_ptr<viz::CopyOutputRequest>>* requests);

  // Internal to property tree construction. Set if the layer should not be
  // shown when its back face is visible to the user. This is a derived value
  // from SetDoubleSided() and SetUseParentBackfaceVisibility().
  void SetShouldCheckBackfaceVisibility(bool should_check_backface_visibility);
  bool should_check_backface_visibility() const {
    return should_check_backface_visibility_;
  }

  // Internal to property tree construction. The value here derives from
  // should_flatten_transform() along with other state, and is for internal use
  // in order to flatten the layer's ScreenSpaceTransform() in cases where the
  // property tree did not handle it.
  void SetShouldFlattenScreenSpaceTransformFromPropertyTree(bool should);
  bool should_flatten_screen_space_transform_from_property_tree() const {
    return should_flatten_screen_space_transform_from_property_tree_;
  }

  std::string ToString() const;

  // Called when a property has been modified in a way that the layer knows
  // immediately that a commit is required.  This implies SetNeedsPushProperties
  // to push that property.
  // This is public, so that it can be called directly when needed, for example
  // in PropertyTreeManager when handling scroll offsets.
  void SetNeedsCommit();

  // The following data are for profiling and debugging. They will be displayed
  // e.g. in the Layers panel of DevTools.

  // The compositing reasons of the layer. The values are defined in
  // third_party/blink/renderer/platform/graphics/compositing_reasons.h.
  void set_compositing_reasons(uint64_t compositing_reasons) {
    compositing_reasons_ = compositing_reasons;
  }
  uint64_t compositing_reasons() const { return compositing_reasons_; }

  // The id of the DOM node that owns this layer.
  void set_owner_node_id(int node_id) { owner_node_id_ = node_id; }
  int owner_node_id() const { return owner_node_id_; }

  // How many times this layer has been repainted.
  int paint_count() const { return paint_count_; }

  // End of data for profiling and debugging.

 protected:
  friend class LayerImpl;
  friend class TreeSynchronizer;

  Layer();
  virtual ~Layer();

  // These SetNeeds functions are in order of severity of update:

  // See SetNeedsCommit() above - it belongs here in the order of severity.

  // Called when there's been a change in layer structure.  Implies
  // SetNeedsCommit and property tree rebuld, but not SetNeedsPushProperties
  // (the full tree is synced over).
  void SetNeedsFullTreeSync();

  // Called when the next commit should wait until the pending tree is activated
  // before finishing the commit and unblocking the main thread. Used to ensure
  // unused resources on the impl thread are returned before commit completes.
  void SetNextCommitWaitsForActivation();

  // Will recalculate whether the layer draws content and set draws_content_
  // appropriately.
  void UpdateDrawsContent(bool has_drawable_content);
  // May be overridden by subclasses if they have optional content, to return
  // false if there is no content to be displayed. If they do have content, then
  // they should return the value from this base class method.
  virtual bool HasDrawableContent() const;

  // Called when the layer's number of drawable descendants changes.
  void AddDrawableDescendants(int num);

  // For debugging. Returns false if the LayerTreeHost this layer is attached to
  // is in the process of updating layers for a BeginMainFrame. Layer properties
  // should be changed by the client before the BeginMainFrame, and should not
  // be changed while the frame is being generated for commit.
  bool IsPropertyChangeAllowed() const;

  // When true, the layer is about to perform an update. Any commit requests
  // will be handled implicitly after the update completes.
  bool ignore_set_needs_commit_;

  int paint_count_;

 private:
  friend class base::RefCounted<Layer>;
  friend class LayerTreeHostCommon;
  friend class LayerTreeHost;

  // Interactions with attached animations.
  void OnFilterAnimated(const FilterOperations& filters);
  void OnOpacityAnimated(float opacity);
  void OnTransformAnimated(const gfx::Transform& transform);

  void AddClipChild(Layer* child);
  void RemoveClipChild(Layer* child);

  void SetParent(Layer* layer);
  bool DescendantIsFixedToContainerLayer() const;

  // This should only be called from RemoveFromParent().
  void RemoveChildOrDependent(Layer* child);

  // If this layer has a clip parent, it removes |this| from its list of clip
  // children.
  void RemoveFromClipTree();

  // When we detach or attach layer to new LayerTreeHost, all property trees'
  // indices becomes invalid.
  void InvalidatePropertyTreesIndices();

  // This is set whenever a property changed on layer that affects whether this
  // layer should own a property tree node or not.
  void SetPropertyTreesNeedRebuild();

  // Fast-path for |SetScrollOffset| and |SetScrollOffsetFromImplSide| to
  // directly update scroll offset values in the property tree without needing a
  // full property tree update. If property trees do not exist yet, ensures
  // they are marked as needing to be rebuilt.
  void UpdateScrollOffset(const gfx::ScrollOffset&);

  // Encapsulates all data, callbacks or interfaces received from the embedder.
  struct Inputs {
    explicit Inputs(int layer_id);
    ~Inputs();

    int layer_id;

    LayerList children;

    gfx::Rect update_rect;

    gfx::Size bounds;
    bool masks_to_bounds;

    scoped_refptr<PictureLayer> mask_layer;

    float opacity;
    SkBlendMode blend_mode;

    bool is_root_for_isolated_group : 1;

    // Hit testing depends on this bit.
    bool hit_testable : 1;

    bool contents_opaque : 1;

    gfx::PointF position;
    gfx::Transform transform;
    gfx::Point3F transform_origin;

    bool is_drawable : 1;

    bool double_sided : 1;
    bool should_flatten_transform : 1;

    // Layers that share a sorting context id will be sorted together in 3d
    // space.  0 is a special value that means this layer will not be sorted
    // and will be drawn in paint order.
    int sorting_context_id;

    bool use_parent_backface_visibility : 1;

    SkColor background_color;

    FilterOperations filters;
    FilterOperations backdrop_filters;
    base::Optional<gfx::RRectF> backdrop_filter_bounds;
    gfx::PointF filters_origin;
    float backdrop_filter_quality;

    // Corner clip radius for the 4 corners of the layer in the following order:
    //     top left, top right, bottom right, bottom left
    gfx::RoundedCornersF corner_radii;

    // If set, disables this layer's rounded corner from triggering a render
    // surface on itself if possible.
    bool is_fast_rounded_corner : 1;

    gfx::ScrollOffset scroll_offset;

    // Size of the scroll container that this layer scrolls in.
    gfx::Size scroll_container_bounds;

    // Indicates that this layer will need a scroll property node and that this
    // layer's bounds correspond to the scroll node's bounds (both |bounds| and
    // |scroll_container_bounds|).
    bool scrollable : 1;

    // Indicates that this layer is a scrollbar.
    bool is_scrollbar : 1;

    bool user_scrollable_horizontal : 1;
    bool user_scrollable_vertical : 1;

    uint32_t main_thread_scrolling_reasons;
    Region non_fast_scrollable_region;

    TouchActionRegion touch_action_region;

    // When set, position: fixed children of this layer will be affected by URL
    // bar movement. bottom-fixed element will be pushed down as the URL bar
    // hides (and the viewport expands) so that the element stays fixed to the
    // viewport bottom. This will always be set on the outer viewport scroll
    // layer. In the case of a non-default rootScroller, all iframes in the
    // rootScroller ancestor chain will also have it set on their scroll
    // layers.
    // TODO(pdr): These values are only used by blink and only when blink does
    // not generate property trees. Remove these values when
    // BlinkGenPropertyTrees ships.
    bool is_resized_by_browser_controls : 1;
    bool is_container_for_fixed_position_layers : 1;
    LayerPositionConstraint position_constraint;

    LayerStickyPositionConstraint sticky_position_constraint;

    ElementId element_id;

    Layer* scroll_parent;
    Layer* clip_parent;

    bool has_will_change_transform_hint : 1;

    bool trilinear_filtering : 1;

    bool hide_layer_and_subtree : 1;

    // The following elements can not and are not serialized.
    base::WeakPtr<LayerClient> client;
    std::unique_ptr<base::trace_event::TracedValue> debug_info;

    base::RepeatingCallback<void(const gfx::ScrollOffset&, const ElementId&)>
        did_scroll_callback;
    std::vector<std::unique_ptr<viz::CopyOutputRequest>> copy_requests;

    OverscrollBehavior overscroll_behavior;

    base::Optional<SnapContainerData> snap_container_data;
  };

  Layer* parent_;

  // Layer instances have a weak pointer to their LayerTreeHost.
  // This pointer value is nil when a Layer is not in a tree and is
  // updated via SetLayerTreeHost() if a layer moves between trees.
  LayerTreeHost* layer_tree_host_;

  Inputs inputs_;

  int num_descendants_that_draw_content_;
  int transform_tree_index_;
  int effect_tree_index_;
  int clip_tree_index_;
  int scroll_tree_index_;
  int property_tree_sequence_number_;
  gfx::Vector2dF offset_to_transform_parent_;
  bool should_flatten_screen_space_transform_from_property_tree_ : 1;
  bool draws_content_ : 1;
  bool should_check_backface_visibility_ : 1;
  // Force use of and cache render surface.
  bool cache_render_surface_ : 1;
  bool force_render_surface_for_testing_ : 1;
  bool subtree_property_changed_ : 1;
  bool may_contain_video_ : 1;
  bool needs_show_scrollbars_ : 1;
  bool has_transform_node_ : 1;
  // This value is valid only when LayerTreeHost::has_copy_request() is true
  bool subtree_has_copy_request_ : 1;
  SkColor safe_opaque_background_color_;
  uint64_t compositing_reasons_;
  int owner_node_id_;

  std::unique_ptr<std::set<Layer*>> clip_children_;
};

}  // namespace cc

#endif  // CC_LAYERS_LAYER_H_
