// Copyright 2017 The Cobalt Authors. 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/egl/draw_rect_radial_gradient.h"

#include <algorithm>

#include "base/logging.h"
#include "cobalt/renderer/backend/egl/utils.h"
#include "cobalt/renderer/egl_and_gles.h"
#include "egl/generated_shader_impl.h"
#include "starboard/memory.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace egl {

namespace {
const int kVertexCount = 4;
}  // namespace

DrawRectRadialGradient::DrawRectRadialGradient(
    GraphicsState* graphics_state, const BaseState& base_state,
    const math::RectF& rect, const render_tree::RadialGradientBrush& brush,
    const GetScratchTextureFunction& get_scratch_texture)
    : DrawObject(base_state),
      lookup_texture_(nullptr),
      vertex_buffer_(nullptr) {
  // Calculate the number of pixels needed for the color lookup texture. There
  // should be enough so that each color stop has a pixel with the color
  // blended at 100%. However, since the lookup texture will be used with
  // linear filtering, reducing the texture size will only impact accuracy at
  // the color stops (but not between them).
  const float kLookupSizes[] = {
      // These represent breakpoints that are likely to be used.
      1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 8.0f, 10.0f, 20.0f, 50.0f, 100.0f,
  };
  const render_tree::ColorStopList& color_stops = brush.color_stops();

  int lookup_size_index = 0;
  for (int i = 0; i < color_stops.size();) {
    float scaled = color_stops[i].position * kLookupSizes[lookup_size_index];
    float fraction = scaled - std::floor(scaled);
    if (fraction > 0.001f && lookup_size_index < arraysize(kLookupSizes) - 1) {
      ++lookup_size_index;
      i = 0;
    } else {
      ++i;
    }
  }

  // Create and initialize the lookup texture if needed. Reserve an additional
  // pixel to represent color stop position 1.0 blended to 100%.
  float lookup_size = kLookupSizes[lookup_size_index] + 1.0f;
  TextureInfo texture_info;
  get_scratch_texture.Run(lookup_size, &texture_info);
  lookup_texture_ = texture_info.texture;
  lookup_region_ = texture_info.region;

  // Add the geometry if a lookup texture was available.
  if (lookup_texture_) {
    if (texture_info.is_new) {
      InitializeLookupTexture(brush);
    }

    attributes_.reserve(kVertexCount);
    math::PointF offset_center(brush.center());
    math::PointF offset_scale(1.0f / std::max(brush.radius_x(), 0.001f),
                              1.0f / std::max(brush.radius_y(), 0.001f));
    AddVertex(rect.x(), rect.y(), offset_center, offset_scale);
    AddVertex(rect.right(), rect.y(), offset_center, offset_scale);
    AddVertex(rect.right(), rect.bottom(), offset_center, offset_scale);
    AddVertex(rect.x(), rect.bottom(), offset_center, offset_scale);
    graphics_state->ReserveVertexData(attributes_.size() *
                                      sizeof(VertexAttributes));
  }
}

void DrawRectRadialGradient::ExecuteUpdateVertexBuffer(
    GraphicsState* graphics_state, ShaderProgramManager* program_manager) {
  if (attributes_.size() > 0) {
    vertex_buffer_ = graphics_state->AllocateVertexData(
        attributes_.size() * sizeof(VertexAttributes));
    SbMemoryCopy(vertex_buffer_, &attributes_[0],
                 attributes_.size() * sizeof(VertexAttributes));
  }
}

void DrawRectRadialGradient::ExecuteRasterize(
    GraphicsState* graphics_state, ShaderProgramManager* program_manager) {
  if (attributes_.size() > 0) {
    ShaderProgram<ShaderVertexOffset, ShaderFragmentOpacityTexcoord1d>* program;
    program_manager->GetProgram(&program);
    graphics_state->UseProgram(program->GetHandle());
    graphics_state->UpdateClipAdjustment(
        program->GetVertexShader().u_clip_adjustment());
    graphics_state->UpdateTransformMatrix(
        program->GetVertexShader().u_view_matrix(), base_state_.transform);
    graphics_state->Scissor(base_state_.scissor.x(), base_state_.scissor.y(),
                            base_state_.scissor.width(),
                            base_state_.scissor.height());
    graphics_state->VertexAttribPointer(
        program->GetVertexShader().a_position(), 2, GL_FLOAT, GL_FALSE,
        sizeof(VertexAttributes),
        vertex_buffer_ + offsetof(VertexAttributes, position));
    graphics_state->VertexAttribPointer(
        program->GetVertexShader().a_offset(), 2, GL_FLOAT, GL_FALSE,
        sizeof(VertexAttributes),
        vertex_buffer_ + offsetof(VertexAttributes, offset));
    graphics_state->VertexAttribFinish();

    // Map radial length [0, 1] to texture coordinates for the lookup texture.
    // |u_texcoord_transform| represents (u-scale, u-add, u-max, v-center).
    const float kTextureWidthScale = 1.0f / lookup_texture_->GetSize().width();
    GL_CALL(glUniform4f(
        program->GetFragmentShader().u_texcoord_transform(),
        (lookup_region_.width() - 1.0f) * kTextureWidthScale,
        (lookup_region_.x() + 0.5f) * kTextureWidthScale,
        (lookup_region_.right() - 0.5f) * kTextureWidthScale,
        (lookup_region_.y() + 0.5f) / lookup_texture_->GetSize().height()));
    GL_CALL(glUniform1f(program->GetFragmentShader().u_opacity(),
                        base_state_.opacity));
    graphics_state->ActiveBindTexture(
        program->GetFragmentShader().u_texture_texunit(),
        lookup_texture_->GetTarget(), lookup_texture_->gl_handle());
    GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, attributes_.size()));
  }
}

base::TypeId DrawRectRadialGradient::GetTypeId() const {
  return ShaderProgram<ShaderVertexColorOffset,
                       ShaderFragmentOpacityTexcoord1d>::GetTypeId();
}

void DrawRectRadialGradient::InitializeLookupTexture(
    const render_tree::RadialGradientBrush& brush) {
  const render_tree::ColorStopList& color_stops = brush.color_stops();

  // The lookup texture is a row of RGBA pixels. Ensure the last pixel contains
  // the last color stop blended to 100%.
  // NOTE: The base_state_.opacity should not be baked into the lookup texture
  //       as opacity can be animated.
  const float kTexelToStop = 1.0f / (lookup_region_.width() - 1.0f);
  const float kStopToTexel = lookup_region_.width() - 1.0f;
  uint8_t* lookup_buffer =
      new uint8_t[static_cast<int>(lookup_region_.width()) * 4];

  size_t color_index = 0;
  float position_prev = 0.0f;
  float position_next = color_stops[color_index].position * kStopToTexel;
  float position_scale = 1.0f / std::max(position_next - position_prev, 1.0f);
  render_tree::ColorRGBA color_prev =
      GetDrawColor(color_stops[color_index].color);
  render_tree::ColorRGBA color_next = color_prev;
  uint8_t* pixel = lookup_buffer;

  // Fill in the blended colors according to the color stops.
  for (float texel = 0.0f; texel < lookup_region_.width(); texel += 1.0f) {
    while (texel > position_next) {
      position_prev = position_next;
      color_prev = color_next;
      if (color_index + 1 < color_stops.size()) {
        // Advance to the next color stop.
        ++color_index;
        position_next = color_stops[color_index].position * kStopToTexel;
        color_next = GetDrawColor(color_stops[color_index].color);
      } else {
        // Persist the current color stop to the end.
        position_next = lookup_region_.width();
      }
      position_scale = 1.0f / std::max(position_next - position_prev, 1.0f);
    }

    // Write the blended color to the lookup texture buffer.
    float blend_ratio = (texel - position_prev) * position_scale;
    render_tree::ColorRGBA color =
        color_prev * (1.0f - blend_ratio) + color_next * blend_ratio;
    pixel[0] = color.rgb8_r();
    pixel[1] = color.rgb8_g();
    pixel[2] = color.rgb8_b();
    pixel[3] = color.rgb8_a();
    pixel += 4;
  }

  // Update the lookup texture.
  DCHECK_EQ(lookup_texture_->GetFormat(), GL_RGBA);
  GL_CALL(glBindTexture(lookup_texture_->GetTarget(),
                        lookup_texture_->gl_handle()));
  GL_CALL(glTexSubImage2D(
      lookup_texture_->GetTarget(), 0, static_cast<GLint>(lookup_region_.x()),
      static_cast<GLint>(lookup_region_.y()),
      static_cast<GLsizei>(lookup_region_.width()), 1,
      lookup_texture_->GetFormat(), GL_UNSIGNED_BYTE, lookup_buffer));
  GL_CALL(glBindTexture(lookup_texture_->GetTarget(), 0));

  delete[] lookup_buffer;
}

void DrawRectRadialGradient::AddVertex(float x, float y,
                                       const math::PointF& offset_center,
                                       const math::PointF& offset_scale) {
  VertexAttributes attributes = {
      {x, y},
      {(x - offset_center.x()) * offset_scale.x(),
       (y - offset_center.y()) * offset_scale.y()},
  };
  attributes_.push_back(attributes);
}

}  // namespace egl
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt
