// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/renderer/rasterizer/common/offscreen_render_coordinate_mapping.h"

#include "cobalt/math/transform_2d.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace common {

using math::Matrix3F;
using math::Rect;
using math::RectF;
using math::Vector2dF;
using math::Vector3dF;
using math::TranslateMatrix;
using math::ScaleMatrix;

namespace {
float GetFractionalComponent(float value) { return value - std::floor(value); }
}  // namespace

OffscreenRenderCoordinateMapping GetOffscreenRenderCoordinateMapping(
    const RectF& local_bounds, const Matrix3F& transform,
    const base::optional<Rect>& viewport_bounds) {
  bool has_rotation_or_skew =
      transform.Get(0, 1) != 0 || transform.Get(1, 0) != 0;

  // We decide at this point whether to attempt to align the fractional value of
  // our content's translation within the offscreen surface such that it would
  // be equal to what it would be in the outer surface.  If we are rotating
  // or skewing, it is not useful to do this so we don't bother in that case.
  bool align_translate = !has_rotation_or_skew;

  // We extract the scale from the transform and let that affect the size of our
  // output bounding box so that our offscreen render is in the same resolution
  // as its outer surface area.
  Vector3dF column_0(transform.column(0));
  Vector3dF column_1(transform.column(1));
  Vector2dF scale(column_0.Length(), column_1.Length());

  // If we're aligning translate, bring the fractional component of the
  // translation into the offscreen render so that we can ensure that we are
  // sub-pixel aligned when rendering it.
  Vector2dF translate;
  if (align_translate) {
    translate.SetVector(GetFractionalComponent(transform.Get(0, 2)),
                        GetFractionalComponent(transform.Get(1, 2)));
  }

  // |scaled_local_bounds| represents |local_bounds| transformed into a hybrid
  // local/viewport space where only scale (and possibly translate) components
  // of |transform| are applied.  This is the space in which we will rasterize
  // to the offscreen surface.
  RectF scaled_local_bounds = local_bounds;
  scaled_local_bounds.Scale(scale.x(), scale.y());
  scaled_local_bounds += translate;

  // Since our offscreen render is already taking into account scale (and
  // possibly translation), we communicate to the caller that they should not
  // apply these components of the transformation when rendering the offscreen
  // surface.
  Vector2dF output_pre_translate(-translate.x(), -translate.y());
  Vector2dF output_post_scale(1.0f / scale.x(), 1.0f / scale.y());

  // To avoid rendering anything we don't need to render, intersect the
  // bounding box with our current viewport bounds.  We do this in the scaled
  // local bounds space since that is where our rendering will occur, thus
  // we must take the inverse of the components of the transform not reflected
  // in scaled local bounds space.
  RectF clipped_scaled_local_bounds;
  if (viewport_bounds) {
    Matrix3F inverse_transform = (TranslateMatrix(output_pre_translate) *
                                  transform * ScaleMatrix(output_post_scale))
                                     .Inverse();
    clipped_scaled_local_bounds = IntersectRects(
        inverse_transform.MapRect(*viewport_bounds), scaled_local_bounds);
  } else {
    clipped_scaled_local_bounds = scaled_local_bounds;
  }

  // Round out our RectF to a Rect here to get integer coordinates that can
  // be used to define offscreen surface dimensions.
  Rect output_bounds = math::RoundOut(clipped_scaled_local_bounds);

  // Now determine the offscreen transform that should be used when rendering
  // the offscreen render tree to an offscreen surface.
  // The |translate| component is already present in |output_bounds|, so
  // we remove it here.  Ultimately we will be left with only the fractional
  // part of the |translate| component.
  float offscreen_translate_x = translate.x() - output_bounds.origin().x();
  float offscreen_translate_y = translate.y() - output_bounds.origin().y();

  Matrix3F offscreen_transform =
      Matrix3F::FromValues(scale.x(), 0, offscreen_translate_x, 0, scale.y(),
                           offscreen_translate_y, 0, 0, 1);

  return OffscreenRenderCoordinateMapping(output_bounds, output_pre_translate,
                                          output_post_scale,
                                          offscreen_transform);
}

}  // namespace common
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt
