// 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/cacheable_layer.h"
#include "flutter/flow/layers/layer.h"
#include "flutter/flow/paint_utils.h"
#include "flutter/flow/raster_cache.h"
#include "flutter/fml/time/time_point.h"
#include "flutter/fml/trace_event.h"
#include "include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/utils/SkNWayCanvas.h"

namespace flutter {

LayerTree::LayerTree(const Config& config, const SkISize& frame_size)
    : root_layer_(config.root_layer),
      frame_size_(frame_size),
      rasterizer_tracing_threshold_(config.rasterizer_tracing_threshold),
      checkerboard_raster_cache_images_(
          config.checkerboard_raster_cache_images),
      checkerboard_offscreen_layers_(config.checkerboard_offscreen_layers) {}

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());
  frame.context().raster_cache().SetCheckboardCacheImages(
      checkerboard_raster_cache_images_);
  LayerStateStack state_stack;
  state_stack.set_preroll_delegate(cull_rect,
                                   frame.root_surface_transformation());
  RasterCache* cache =
      ignore_raster_cache ? nullptr : &frame.context().raster_cache();
  raster_cache_items_.clear();

  PrerollContext context = {
      // clang-format off
      .raster_cache                  = cache,
      .gr_context                    = frame.gr_context(),
      .view_embedder                 = frame.view_embedder(),
      .state_stack                   = state_stack,
      .dst_color_space               = 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_,
      .display_list_enabled          = frame.display_list_builder() != nullptr,
      // clang-format on
  };

  root_layer_->Preroll(&context);

  return context.surface_needs_readback;
}

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++;
  }
}

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;

  // DrawCheckerboard is not supported on Impeller.
  if (checkerboard_offscreen_layers_ && !frame.aiks_context()) {
    state_stack.set_checkerboard_func(DrawCheckerboard);
  }

  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());
  RasterCache* cache =
      ignore_raster_cache ? nullptr : &frame.context().raster_cache();
  PaintContext context = {
      // clang-format off
      .state_stack                   = state_stack,
      .canvas                        = canvas,
      .gr_context                    = frame.gr_context(),
      .dst_color_space               = 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(),
      .raster_cache                  = cache,
      .layer_snapshot_store          = snapshot_store,
      .enable_leaf_layer_tracing     = enable_leaf_layer_tracing_,
      .aiks_context                  = frame.aiks_context(),
      // clang-format on
  };

  if (cache) {
    cache->EvictUnusedCacheEntries();
    TryToRasterCache(raster_cache_items_, &context, ignore_raster_cache);
  }

  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
      .raster_cache                  = nullptr,
      .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,
      .raster_cache                  = nullptr,
      .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
