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

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

#include "flutter/display_list/skia/dl_sk_canvas.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/flow/frame_timings.h"
#include "flutter/flow/layer_snapshot_store.h"
#include "flutter/flow/layers/layer.h"
#include "flutter/flow/paint_utils.h"
#include "flutter/flow/raster_cache.h"
#include "flutter/flow/raster_cache_item.h"
#include "flutter/fml/time/time_point.h"
#include "flutter/fml/trace_event.h"
#include "include/core/SkColorSpace.h"

namespace flutter {

LayerTree::LayerTree(const std::shared_ptr<Layer>& root_layer,
                     const SkISize& frame_size)
    : root_layer_(root_layer), frame_size_(frame_size) {}

inline SkColorSpace* GetColorSpace(DlCanvas* canvas) {
  return canvas ? canvas->GetImageInfo().colorSpace() : nullptr;
}

bool LayerTree::Preroll(CompositorContext::ScopedFrame& frame,
                        bool ignore_raster_cache,
                        SkRect cull_rect) {
  TRACE_EVENT0("flutter", "LayerTree::Preroll");

  if (!root_layer_) {
    FML_LOG(ERROR) << "The scene did not specify any layers.";
    return false;
  }

  SkColorSpace* color_space = GetColorSpace(frame.canvas());
  LayerStateStack state_stack;
  state_stack.set_preroll_delegate(cull_rect,
                                   frame.root_surface_transformation());

  raster_cache_items_.clear();

  PrerollContext context = {
#if !SLIMPELLER
      .raster_cache =
          ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
#endif  //  !SLIMPELLER
      .gr_context = frame.gr_context(),
      .view_embedder = frame.view_embedder(),
      .state_stack = state_stack,
      .dst_color_space = sk_ref_sp<SkColorSpace>(color_space),
      .surface_needs_readback = false,
      .raster_time = frame.context().raster_time(),
      .ui_time = frame.context().ui_time(),
      .texture_registry = frame.context().texture_registry(),
      .raster_cached_entries = &raster_cache_items_,
  };

  root_layer_->Preroll(&context);

  return context.surface_needs_readback;
}

#if !SLIMPELLER
void LayerTree::TryToRasterCache(
    const std::vector<RasterCacheItem*>& raster_cached_items,
    const PaintContext* paint_context,
    bool ignore_raster_cache) {
  unsigned i = 0;
  const auto item_size = raster_cached_items.size();
  while (i < item_size) {
    auto* item = raster_cached_items[i];
    if (item->need_caching()) {
      // try to cache current layer
      // If parent failed to cache, just proceed to the next entry
      // cache current entry, this entry's parent must not cache
      if (item->TryToPrepareRasterCache(*paint_context, false)) {
        // if parent cached, then foreach child layer to touch them.
        for (unsigned j = 0; j < item->child_items(); j++) {
          auto* child_item = raster_cached_items[i + j + 1];
          if (child_item->need_caching()) {
            child_item->TryToPrepareRasterCache(*paint_context, true);
          }
        }
        i += item->child_items() + 1;
        continue;
      }
    }
    i++;
  }
}
#endif  //  !SLIMPELLER

void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
                      bool ignore_raster_cache) const {
  TRACE_EVENT0("flutter", "LayerTree::Paint");

  if (!root_layer_) {
    FML_LOG(ERROR) << "The scene did not specify any layers to paint.";
    return;
  }

  LayerStateStack state_stack;

  DlCanvas* canvas = frame.canvas();
  state_stack.set_delegate(canvas);

  // clear the previous snapshots.
  LayerSnapshotStore* snapshot_store = nullptr;
  if (enable_leaf_layer_tracing_) {
    frame.context().snapshot_store().Clear();
    snapshot_store = &frame.context().snapshot_store();
  }

  SkColorSpace* color_space = GetColorSpace(frame.canvas());

#if !SLIMPELLER
  RasterCache* cache =
      ignore_raster_cache ? nullptr : &frame.context().raster_cache();
#endif  //  !SLIMPELLER

  PaintContext context = {
      // clang-format off
      .state_stack                   = state_stack,
      .canvas                        = canvas,
      .gr_context                    = frame.gr_context(),
      .dst_color_space               = sk_ref_sp(color_space),
      .view_embedder                 = frame.view_embedder(),
      .raster_time                   = frame.context().raster_time(),
      .ui_time                       = frame.context().ui_time(),
      .texture_registry              = frame.context().texture_registry(),
#if !SLIMPELLER
      .raster_cache                  = cache,
#endif  //  !SLIMPELLER
      .layer_snapshot_store          = snapshot_store,
      .enable_leaf_layer_tracing     = enable_leaf_layer_tracing_,
      .impeller_enabled              = !!frame.aiks_context(),
      .aiks_context                  = frame.aiks_context(),
      // clang-format on
  };

#if !SLIMPELLER
  if (cache) {
    cache->EvictUnusedCacheEntries();
    TryToRasterCache(raster_cache_items_, &context, ignore_raster_cache);
  }
#endif  //  !SLIMPELLER

  if (root_layer_->needs_painting(context)) {
    root_layer_->Paint(context);
  }
}

sk_sp<DisplayList> LayerTree::Flatten(
    const SkRect& bounds,
    const std::shared_ptr<TextureRegistry>& texture_registry,
    GrDirectContext* gr_context) {
  TRACE_EVENT0("flutter", "LayerTree::Flatten");

  DisplayListBuilder builder(bounds);

  const FixedRefreshRateStopwatch unused_stopwatch;

  LayerStateStack preroll_state_stack;
  // No root surface transformation. So assume identity.
  preroll_state_stack.set_preroll_delegate(bounds);
  PrerollContext preroll_context{
  // clang-format off
#if !SLIMPELLER
      .raster_cache                  = nullptr,
#endif  //  !SLIMPELLER
      .gr_context                    = gr_context,
      .view_embedder                 = nullptr,
      .state_stack                   = preroll_state_stack,
      .dst_color_space               = nullptr,
      .surface_needs_readback        = false,
      .raster_time                   = unused_stopwatch,
      .ui_time                       = unused_stopwatch,
      .texture_registry              = texture_registry,
      // clang-format on
  };

  LayerStateStack paint_state_stack;
  paint_state_stack.set_delegate(&builder);
  PaintContext paint_context = {
      // clang-format off
      .state_stack                   = paint_state_stack,
      .canvas                        = &builder,
      .gr_context                    = gr_context,
      .dst_color_space               = nullptr,
      .view_embedder                 = nullptr,
      .raster_time                   = unused_stopwatch,
      .ui_time                       = unused_stopwatch,
      .texture_registry              = texture_registry,
#if !SLIMPELLER
      .raster_cache                  = nullptr,
#endif  //  !SLIMPELLER
      .layer_snapshot_store          = nullptr,
      .enable_leaf_layer_tracing     = false,
      // clang-format on
  };

  // Even if we don't have a root layer, we still need to create an empty
  // picture.
  if (root_layer_) {
    root_layer_->Preroll(&preroll_context);

    // The needs painting flag may be set after the preroll. So check it after.
    if (root_layer_->needs_painting(paint_context)) {
      root_layer_->Paint(paint_context);
    }
  }

  return builder.Build();
}

}  // namespace flutter
