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

#ifndef COBALT_RENDERER_RASTERIZER_EGL_DRAW_OBJECT_H_
#define COBALT_RENDERER_RASTERIZER_EGL_DRAW_OBJECT_H_

#include <GLES2/gl2.h>

#include "base/callback.h"
#include "base/optional.h"
#include "cobalt/base/type_id.h"
#include "cobalt/math/matrix3_f.h"
#include "cobalt/math/rect.h"
#include "cobalt/render_tree/color_rgba.h"
#include "cobalt/render_tree/rounded_corners.h"
#include "cobalt/renderer/backend/egl/texture.h"
#include "cobalt/renderer/rasterizer/egl/graphics_state.h"
#include "cobalt/renderer/rasterizer/egl/shader_program_manager.h"

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

// Base type to rasterize various objects via GL commands.
class DrawObject {
 public:
  typedef base::optional<render_tree::RoundedCorners> OptionalRoundedCorners;

  // Callback to get a scratch "1D" texture of the given |size|. If such a
  // request was previously fulfilled for the relevant render tree node, then
  // the cached |texture| and |region| will be returned, and |is_new| will be
  // false; this is a hint as to whether the texture region needs to be
  // initialized. If the request succeeded, then |texture| will point to a 2D
  // texture whose |region| is a row meeting the size requirement; otherwise,
  // |texture| will be nullptr.
  struct TextureInfo {
    const backend::TextureEGL* texture;
    math::RectF region;
    bool is_new;
  };
  typedef base::Callback<void(float size, TextureInfo* out_texture_info)>
      GetScratchTextureFunction;

  // Structure containing the common attributes for all DrawObjects.
  struct BaseState {
    BaseState();
    BaseState(const BaseState& other);

    math::Matrix3F transform;
    math::Rect scissor;

    // |rounded_scissor_rect| is only relevant when |rounded_scissor_corners|
    // exists.
    math::RectF rounded_scissor_rect;
    OptionalRoundedCorners rounded_scissor_corners;

    float opacity;
  };

  virtual ~DrawObject() {}

  // Certain draw objects can be merged with others to reduce the number of
  // draw calls issued. If TryMerge returns true, then |other| can be discarded.
  base::TypeId GetMergeTypeId() const { return merge_type_; }
  virtual bool TryMerge(DrawObject* other) { return false; }

  // This stage is used to update the vertex buffer for the rasterize
  // stage. Vertex data is handled by the GraphicsState to minimize the number
  // of vertex buffers needed. Once this stage is executed, the rasterizer will
  // then notify the GraphicsState to send all vertex data from all draw
  // objects to the GPU.
  virtual void ExecuteUpdateVertexBuffer(GraphicsState* graphics_state,
      ShaderProgramManager* program_manager) = 0;

  // This stage is responsible for issuing the GPU commands to do the actual
  // rendering.
  virtual void ExecuteRasterize(GraphicsState* graphics_state,
      ShaderProgramManager* program_manager) = 0;

  // Return a TypeId that can be used to sort draw objects in order to minimize
  // state changes. This may be the class' TypeId, or the TypeId of the shader
  // program which the class uses.
  virtual base::TypeId GetTypeId() const = 0;

 protected:
  // Structures describing vertex data for rendering rounded rectangles.
  struct RCorner {
    // Constructor to transform a RCorner value into a format which the
    // shader function IsOutsideRCorner() expects. This expresses the current
    // vertex position as a scaled offset relevant for the corner, and provides
    // scalars to assist in calculating the antialiased edge. For more details,
    // see function_is_outside_rcorner.inc.
    RCorner(const float (&position)[2], const RCorner& init);
    RCorner() {}
    float x, y;
    float rx, ry;
  };
  struct RRectAttributes {
    math::RectF bounds;   // The region in which to use the rcorner data.
    RCorner rcorner;
  };

  DrawObject();
  explicit DrawObject(const BaseState& base_state);

  // Extract the scale vector from this object's transform.
  math::Vector2dF GetScale() const;

  // Remove scale from the transform, and return the scale vector.
  math::Vector2dF RemoveScaleFromTransform();

  // Utility function to get the render color for the blend modes that will
  // be used. These modes expect alpha to be pre-multiplied.
  static render_tree::ColorRGBA GetDrawColor(
      const render_tree::ColorRGBA& color) {
    return render_tree::ColorRGBA(color.r() * color.a(), color.g() * color.a(),
                                  color.b() * color.a(), color.a());
  }

  // Return a uint32_t suitable to be transferred as 4 unsigned bytes
  // representing color to a GL shader.
  static uint32_t GetGLRGBA(float r, float g, float b, float a);
  static uint32_t GetGLRGBA(const render_tree::ColorRGBA& color) {
    return GetGLRGBA(color.r(), color.g(), color.b(), color.a());
  }

  // Get the vertex attributes to use to draw the given rounded rect. Each
  // corner uses a different attribute. These RCorner values must be transformed
  // before being passed to the shader. (See RCorner constructor.)
  static void GetRRectAttributes(const math::RectF& bounds,
      math::RectF rect, render_tree::RoundedCorners corners,
      RRectAttributes (&out_attributes)[4]);

  // Get the vertex attributes to draw the given rounded rect excluding the
  // inscribed rect. These RCorner values must be transformed before being
  // passed to the shader. (See RCorner constructor.)
  static void GetRRectAttributes(const math::RectF& bounds,
      math::RectF rect, render_tree::RoundedCorners corners,
      RRectAttributes (&out_attributes)[8]);

  BaseState base_state_;

  // Provide type information for use with TryMerge. Only DrawObjects that may
  // be merged need to set this.
  base::TypeId merge_type_;

 private:
  // Return the RCorner values for the given rounded rect, and the normalized
  // rect and corner values used.
  static void GetRCornerValues(math::RectF* rect,
      render_tree::RoundedCorners* corners,
      RRectAttributes out_rcorners[4]);
};

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

#endif  // COBALT_RENDERER_RASTERIZER_EGL_DRAW_OBJECT_H_
