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

#include "services/gfx/compositor/graph/snapshot.h"

#include "base/logging.h"
#include "mojo/skia/type_converters.h"
#include "services/gfx/compositor/graph/scene_content.h"
#include "services/gfx/compositor/graph/scene_def.h"
#include "services/gfx/compositor/render/render_frame.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/utils/SkMatrix44.h"

namespace compositor {

Snapshot::Snapshot() {}

Snapshot::~Snapshot() {}

bool Snapshot::HasDependency(const SceneDef* scene) const {
  return dependencies_.find(scene->label().token()) != dependencies_.end();
}

std::shared_ptr<RenderFrame> Snapshot::CreateFrame(
    const mojo::Rect& viewport,
    const mojo::gfx::composition::FrameInfo& frame_info) const {
  DCHECK(!is_blocked());
  DCHECK(root_scene_content_);

  SkIRect sk_viewport = viewport.To<SkIRect>();

  SkPictureRecorder recorder;
  recorder.beginRecording(SkRect::Make(sk_viewport));
  root_scene_content_->RecordPicture(this, recorder.getRecordingCanvas());
  return RenderFrame::Create(skia::AdoptRef(recorder.endRecordingAsPicture()),
                             sk_viewport, frame_info);
}

void Snapshot::HitTest(const mojo::PointF& point,
                       mojo::gfx::composition::HitTestResult* result) const {
  DCHECK(result);
  DCHECK(!is_blocked());
  DCHECK(root_scene_content_);

  root_scene_content_->HitTest(this, point.To<SkPoint>(), SkMatrix44::I(),
                               &result->root);
}

bool Snapshot::IsNodeBlocked(const NodeDef* node) const {
  DCHECK(!is_blocked());

  auto it = node_dispositions_.find(node);
  DCHECK(it != node_dispositions_.end());
  DCHECK(it->second == Disposition::kSuccess ||
         it->second == Disposition::kBlocked);
  return it->second == Disposition::kBlocked;
}

const SceneContent* Snapshot::GetResolvedSceneContent(
    const SceneNodeDef* scene_node) const {
  DCHECK(!is_blocked());

  auto it = resolved_scene_contents_.find(scene_node);
  DCHECK(it != resolved_scene_contents_.end());
  return it->second.get();
}

SnapshotBuilder::SnapshotBuilder(std::ostream* block_log)
    : block_log_(block_log), snapshot_(new Snapshot()) {}

SnapshotBuilder::~SnapshotBuilder() {}

Snapshot::Disposition SnapshotBuilder::SnapshotNode(
    const NodeDef* node,
    const SceneContent* content) {
  DCHECK(snapshot_);
  DCHECK(node);
  DCHECK(content);
  DCHECK(node != content->GetRootNodeIfExists());

  auto it = snapshot_->node_dispositions_.find(node);
  if (it != snapshot_->node_dispositions_.end())
    return it->second;

  Snapshot::Disposition disposition = node->RecordSnapshot(content, this);
  snapshot_->node_dispositions_[node] = disposition;
  return disposition;
}

Snapshot::Disposition SnapshotBuilder::SnapshotRootAndDetectCycles(
    const NodeDef* node,
    const SceneContent* content) {
  DCHECK(snapshot_);
  DCHECK(node);
  DCHECK(content);
  DCHECK(node == content->GetRootNodeIfExists());

  auto storage = snapshot_->node_dispositions_.emplace(
      node, Snapshot::Disposition::kCycle);
  if (!storage.second) {
    if (storage.first->second == Snapshot::Disposition::kCycle)
      cycle_ = content;  // start unwinding, remember where to stop
    return storage.first->second;
  }

  Snapshot::Disposition disposition = node->RecordSnapshot(content, this);
  if (disposition == Snapshot::Disposition::kSuccess) {
    snapshot_->node_dispositions_[node] = disposition;
    return disposition;
  }

  // We cannot reuse the iterator in |storage.first| because it may have
  // been invalidated by the call to |RecordSnapshot| due to rehashing so
  // we must look up the node again just in case.
  snapshot_->node_dispositions_[node] = Snapshot::Disposition::kBlocked;

  if (disposition == Snapshot::Disposition::kCycle) {
    DCHECK(cycle_);
    if (block_log_) {
      *block_log_ << "Scene blocked because it is part of a cycle: "
                  << content->FormattedLabel() << std::endl;
    }
    if (cycle_ == content) {
      cycle_ = nullptr;  // found the ouroboros tail, stop unwinding
      disposition = Snapshot::Disposition::kBlocked;
    }
  }
  return disposition;
}
Snapshot::Disposition SnapshotBuilder::SnapshotScene(
    const SceneDef* scene,
    uint32_t version,
    const SceneNodeDef* referrer_node,
    const SceneContent* referrer_content) {
  DCHECK(snapshot_);
  DCHECK(scene);
  DCHECK(referrer_node);
  DCHECK(referrer_content);

  // This function should only ever be called once when snapshotting the
  // referring |SceneNodeDef| at which point the result will be memoized
  // by |SnapshotNode| as usual so reentrance should not occur.
  DCHECK(snapshot_->resolved_scene_contents_.find(referrer_node) ==
         snapshot_->resolved_scene_contents_.end());

  snapshot_->dependencies_.insert(scene->label().token());

  const SceneContent* content = scene->FindContent(version);
  if (!content) {
    if (block_log_) {
      *block_log_ << "Scene node blocked because its referenced scene is not "
                     "available with the requested version: "
                  << referrer_node->FormattedLabel(referrer_content)
                  << ", scene " << scene->label().FormattedLabel()
                  << ", requested version " << version << ", current version "
                  << scene->version() << std::endl;
    }
    return Snapshot::Disposition::kBlocked;
  }

  const NodeDef* root = content->GetRootNodeIfExists();
  if (!root) {
    if (block_log_) {
      *block_log_ << "Scene node blocked because its referenced scene has no "
                     "root node: "
                  << referrer_node->FormattedLabel(referrer_content)
                  << ", scene " << content->FormattedLabel() << std::endl;
    }
    return Snapshot::Disposition::kBlocked;
  }

  snapshot_->resolved_scene_contents_[referrer_node] = content;
  return SnapshotRootAndDetectCycles(root, content);
}

Snapshot::Disposition SnapshotBuilder::SnapshotRenderer(const SceneDef* scene) {
  DCHECK(!snapshot_->root_scene_content_);

  snapshot_->dependencies_.insert(scene->label().token());

  const SceneContent* content =
      scene->FindContent(mojo::gfx::composition::kSceneVersionNone);
  if (!content) {
    if (block_log_) {
      *block_log_ << "Rendering blocked because the root scene has no content: "
                  << scene->label().FormattedLabel() << std::endl;
    }
    return Snapshot::Disposition::kBlocked;
  }

  const NodeDef* root = content->GetRootNodeIfExists();
  if (!root) {
    if (block_log_) {
      *block_log_ << "Rendering blocked the root scene has no root node: "
                  << content->FormattedLabel() << std::endl;
    }
    return Snapshot::Disposition::kBlocked;
  }

  snapshot_->root_scene_content_ = content;
  return SnapshotRootAndDetectCycles(root, content);
}

scoped_refptr<const Snapshot> SnapshotBuilder::Build(
    const SceneDef* root_scene) {
  DCHECK(snapshot_);
  DCHECK(root_scene);

  snapshot_->disposition_ = SnapshotRenderer(root_scene);
  DCHECK(!cycle_);  // must have properly unwound any cycles by now

  if (snapshot_->is_blocked()) {
    snapshot_->root_scene_content_ = nullptr;
    snapshot_->resolved_scene_contents_.clear();
    snapshot_->node_dispositions_.clear();
  }
  return std::move(snapshot_);
}

}  // namespace compositor
