// 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 "impeller/entity/contents/filters/matrix_filter_contents.h"

namespace impeller {

MatrixFilterContents::MatrixFilterContents() = default;

MatrixFilterContents::~MatrixFilterContents() = default;

void MatrixFilterContents::SetMatrix(Matrix matrix) {
  matrix_ = matrix;
}

void MatrixFilterContents::SetRenderingMode(
    Entity::RenderingMode rendering_mode) {
  rendering_mode_ = rendering_mode;
  FilterContents::SetRenderingMode(rendering_mode);
}

bool MatrixFilterContents::IsTranslationOnly() const {
  return matrix_.Basis().IsIdentity() && FilterContents::IsTranslationOnly();
}

void MatrixFilterContents::SetSamplerDescriptor(SamplerDescriptor desc) {
  sampler_descriptor_ = std::move(desc);
}

std::optional<Entity> MatrixFilterContents::RenderFilter(
    const FilterInput::Vector& inputs,
    const ContentContext& renderer,
    const Entity& entity,
    const Matrix& effect_transform,
    const Rect& coverage,
    const std::optional<Rect>& coverage_hint) const {
  auto snapshot = inputs[0]->GetSnapshot("Matrix", renderer, entity);
  if (!snapshot.has_value()) {
    return std::nullopt;
  }

  // The filter's matrix needs to be applied within the space defined by the
  // scene's current transform matrix (CTM). For example: If the CTM is
  // scaled up, then translations applied by the matrix should be magnified
  // accordingly.
  //
  // To accomplish this, we sandwich the filter's matrix within the CTM in both
  // cases. But notice that for the subpass backdrop filter case, we use the
  // "effect transform" instead of the Entity's transform!
  //
  // That's because in the subpass backdrop filter case, the Entity's transform
  // isn't actually the captured CTM of the scene like it usually is; instead,
  // it's just a screen space translation that offsets the backdrop texture (as
  // mentioned above). And so we sneak the subpass's captured CTM in through the
  // effect transform.

  auto transform = rendering_mode_ == Entity::RenderingMode::kSubpass
                       ? effect_transform
                       : entity.GetTransform();
  snapshot->transform = transform *           //
                        matrix_ *             //
                        transform.Invert() *  //
                        snapshot->transform;

  snapshot->sampler_descriptor = sampler_descriptor_;
  return Entity::FromSnapshot(snapshot, entity.GetBlendMode(),
                              entity.GetClipDepth());
}

std::optional<Rect> MatrixFilterContents::GetFilterSourceCoverage(
    const Matrix& effect_transform,
    const Rect& output_limit) const {
  auto transform = effect_transform *          //
                   matrix_ *                   //
                   effect_transform.Invert();  //
  if (transform.GetDeterminant() == 0.0) {
    return std::nullopt;
  }
  auto inverse = transform.Invert();
  return output_limit.TransformBounds(inverse);
}

std::optional<Rect> MatrixFilterContents::GetFilterCoverage(
    const FilterInput::Vector& inputs,
    const Entity& entity,
    const Matrix& effect_transform) const {
  if (inputs.empty()) {
    return std::nullopt;
  }

  auto coverage = inputs[0]->GetCoverage(entity);
  if (!coverage.has_value()) {
    return std::nullopt;
  }
  auto& m = rendering_mode_ == Entity::RenderingMode::kSubpass
                ? effect_transform
                : inputs[0]->GetTransform(entity);
  auto transform = m *          //
                   matrix_ *    //
                   m.Invert();  //
  return coverage->TransformBounds(transform);
}

}  // namespace impeller
