// Copyright 2013 The Flutter 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 FLUTTER_FLOW_LAYERS_CONTAINER_LAYER_H_
#define FLUTTER_FLOW_LAYERS_CONTAINER_LAYER_H_

#include <vector>

#include "flutter/flow/layers/layer.h"

namespace flutter {

class ContainerLayer : public Layer {
 public:
  ContainerLayer();

#ifdef FLUTTER_ENABLE_DIFF_CONTEXT

  void Diff(DiffContext* context, const Layer* old_layer) override;
  void PreservePaintRegion(DiffContext* context) override;

#endif  // FLUTTER_ENABLE_DIFF_CONTEXT

  virtual void Add(std::shared_ptr<Layer> layer);

  void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
  void Paint(PaintContext& context) const override;
#if defined(LEGACY_FUCHSIA_EMBEDDER)
  void CheckForChildLayerBelow(PrerollContext* context) override;
  void UpdateScene(std::shared_ptr<SceneUpdateContext> context) override;
#endif

  const std::vector<std::shared_ptr<Layer>>& layers() const { return layers_; }

 protected:
#ifdef FLUTTER_ENABLE_DIFF_CONTEXT

  void DiffChildren(DiffContext* context, const ContainerLayer* old_layer);

#endif  // FLUTTER_ENABLE_DIFF_CONTEXT

  void PrerollChildren(PrerollContext* context,
                       const SkMatrix& child_matrix,
                       SkRect* child_paint_bounds);
  void PaintChildren(PaintContext& context) const;

#if defined(LEGACY_FUCHSIA_EMBEDDER)
  void UpdateSceneChildren(std::shared_ptr<SceneUpdateContext> context);
#endif

  // Try to prepare the raster cache for a given layer.
  //
  // The raster cache would fail if either of the followings is true:
  // 1. The context has a platform view.
  // 2. The context does not have a valid raster cache.
  // 3. The layer's paint bounds does not intersect with the cull rect.
  //
  // We make this a static function instead of a member function that directly
  // uses the "this" pointer as the layer because we sometimes need to raster
  // cache a child layer and one can't access its child's protected method.
  static void TryToPrepareRasterCache(PrerollContext* context,
                                      Layer* layer,
                                      const SkMatrix& matrix);

 private:
  std::vector<std::shared_ptr<Layer>> layers_;

  FML_DISALLOW_COPY_AND_ASSIGN(ContainerLayer);
};

//------------------------------------------------------------------------------
/// Some ContainerLayer objects perform a rendering operation or filter on
/// the rendered output of their children. Often that operation is changed
/// slightly from frame to frame as part of an animation. During such an
/// animation, the children can be cached if they are stable to avoid having
/// to render them on every frame. Even if the children are not stable,
/// rendering them into the raster cache during a Preroll operation will save
/// an extra change of rendering surface during the Paint phase as compared
/// to using the SaveLayer that would otherwise be needed with no caching.
///
/// Typically the Flutter Widget objects that lead to the creation of these
/// layers will try to enforce only a single child Widget by their design.
/// Unfortunately, the process of turning Widgets eventually into engine
/// layers is not a 1:1 process so this layer might end up with multiple
/// child layers even if the Widget only had a single child Widget.
///
/// When such a layer goes to cache the output of its children, it will
/// need to supply a single layer to the cache mechanism since the raster
/// cache uses a layer unique_id() as part of the cache key. If this layer
/// ended up with multiple children, then it must first collect them into
/// one layer for the cache mechanism. In order to provide a single layer
/// for all of the children, this utility class will implicitly collect
/// the children into a secondary ContainerLayer called the child container.
///
/// A by-product of creating a hidden child container, though, is that the
/// child container is created new every time this layer is created with
/// different properties, such as during an animation. In that scenario,
/// it would be best to cache the single real child of this layer if it
/// is unique and if it is stable from frame to frame. To facilitate this
/// optimal caching strategy, this class implements two accessor methods
/// to be used for different purposes:
///
/// When the layer needs to recurse to perform some operation on its children,
/// it can call GetChildContainer() to return the hidden container containing
/// all of the real children.
///
/// When the layer wants to cache the rendered contents of its children, it
/// should call GetCacheableChild() for best performance. This method may
/// end up returning the same layer as GetChildContainer(), but only if the
/// conditions for optimal caching of a single child are not met.
///
class MergedContainerLayer : public ContainerLayer {
 public:
  MergedContainerLayer();

  void AssignOldLayer(Layer* old_layer) override;

  void Add(std::shared_ptr<Layer> layer) override;

 protected:
  /**
   * @brief Returns the ContainerLayer used to hold all of the children of the
   * MergedContainerLayer. Note that this may not be the best layer to use
   * for caching the children.
   *
   * @see GetCacheableChild()
   * @return the ContainerLayer child used to hold the children
   */
  ContainerLayer* GetChildContainer() const;

  /**
   * @brief Returns the best choice for a Layer object that can be used
   * in RasterCache operations to cache the children.
   *
   * The returned Layer must represent all children and try to remain stable
   * if the MergedContainerLayer is reconstructed in subsequent frames of
   * the scene.
   *
   * @see GetChildContainer()
   * @return the best candidate Layer for caching the children
   */
  Layer* GetCacheableChild() const;

 private:
  FML_DISALLOW_COPY_AND_ASSIGN(MergedContainerLayer);
};

}  // namespace flutter

#endif  // FLUTTER_FLOW_LAYERS_CONTAINER_LAYER_H_
