// 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);

  // 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_
