// 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_GRAPHICS_STATE_H_
#define COBALT_RENDERER_RASTERIZER_EGL_GRAPHICS_STATE_H_

#include <GLES2/gl2.h>

#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "cobalt/math/matrix3_f.h"
#include "cobalt/math/rect.h"
#include "cobalt/math/size.h"
#include "cobalt/renderer/backend/render_target.h"

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

// Class representing all the GL graphics states pertinent to rendering. This
// caches the state information and helps reduce redundant GL calls.
class GraphicsState {
 public:
  GraphicsState();
  ~GraphicsState();

  // Mark all cached states as dirty. GL commands to reset the state will be
  // executed on the next call to Clear or UseProgram.
  void SetDirty();

  // Specify the beginning of a new render frame.
  void BeginFrame();

  // Specify the end of the current render frame.
  void EndFrame();

  // Clear the color and depth buffers.
  void Clear();
  void Clear(float r, float g, float b, float a);

  // Set the current shader program to be used.
  void UseProgram(GLuint program);
  GLuint GetProgram() const { return program_; }

  // Bind the specified framebuffer. This only goes through glBindFramebuffer
  // and does not call eglMakeCurrent. This also SetClipAdjustment() to the
  // render target's dimensions.
  // |render_target| may be null to unbind the current framebuffer.
  // NOTE: Be sure to call Viewport() and Scissor() after binding a new
  //       framebuffer.
  void BindFramebuffer(const backend::RenderTarget* render_target);

  // Set the viewport. If changing render targets, then be sure to
  // BindFramebuffer() before calling this.
  void Viewport(int x, int y, int width, int height);
  const math::Rect& GetViewport() const { return viewport_; }

  // Set the scissor box. If changing render targets, then be sure to
  // BindFramebuffer() before calling this.
  void Scissor(int x, int y, int width, int height);
  const math::Rect& GetScissor() const { return scissor_; }

  // Control blending state.
  // Default = disabled.
  void EnableBlend();
  void DisableBlend();
  bool IsBlendEnabled() const { return blend_enabled_; }

  // Bind a texture to a given texture unit. Combines glActiveTexture and
  // glBindTexture.
  void ActiveBindTexture(GLenum texture_unit, GLenum target, GLuint texture);

  // Bind a texture to the specified texture unit and set its texture wrap
  // mode.
  void ActiveBindTexture(GLenum texture_unit, GLenum target, GLuint texture,
                         GLint texture_wrap_mode);

  // Update the GPU with the current clip adjustment settings.
  void UpdateClipAdjustment(GLint handle);

  // Update the GPU with the specified transform matrix.
  void UpdateTransformMatrix(GLint handle, const math::Matrix3F& transform);

  // Reserve the specified number of bytes for vertex data in the upcoming
  // frame. This must be called outside of a render frame (i.e. before
  // BeginFrame / after EndFrame).
  void ReserveVertexData(size_t bytes);

  // Returns a client-side pointer to the specified number of bytes in the
  // vertex data buffer. The number of bytes allocated for any given frame
  // should be less than or equal to the number of bytes reserved. This must
  // be done after all calls to ReserveVertexData for a given render frame.
  uint8_t* AllocateVertexData(size_t bytes);

  // Reserve the specified number of vertex indices for the upcoming frame.
  // This must be called outside of a render frame.
  void ReserveVertexIndices(size_t count);

  // Returns a client-side pointer to the specified number of vertex indices.
  // These indices should have been reserved using ReserveVertexIndices.
  // Allocations can only be made after all calls to reserve indices for a
  // given frame.
  uint16_t* AllocateVertexIndices(size_t count);

  // Return a pointer to a previously allocated vertex index buffer. The return
  // value is suitable for use with glDrawElements.
  const GLvoid* GetVertexIndexPointer(const uint16_t* client_pointer);

  // Update the GPU with the current contents of the vertex data and index
  // buffers. This should only be called once, after BeginFrame().
  void UpdateVertexBuffers();

  // Specify vertex attribute data that the current program will use.
  // |client_pointer| should be within the range of addresses returned by
  // AllocateVertexData.
  void VertexAttribPointer(GLint index, GLint size, GLenum type,
      GLboolean normalized, GLsizei stride, const void* client_pointer);

  // Disable any vertex attrib arrays that the previous program used (via
  // VertexAttribPointer), but the current program does not.
  void VertexAttribFinish();

 private:
  void Reset();

  // Set the clip adjustment to be used with vertex shaders. This transforms
  // the vertex coordinates from view space to clip space.
  void SetClipAdjustment();

  math::Rect viewport_;
  math::Rect scissor_;

  math::Size render_target_size_;
  GLuint render_target_handle_;
  int32_t render_target_serial_;

  GLuint program_;
  GLuint array_buffer_handle_;
  GLuint index_buffer_handle_;
  GLenum texture_unit_;
  uint32_t enabled_vertex_attrib_array_mask_;
  uint32_t disable_vertex_attrib_array_mask_;
  float clip_adjustment_[4];

  bool clip_adjustment_dirty_;
  bool state_dirty_;
  bool blend_enabled_;

  static const int kNumTextureUnitsCached = 8;
  GLenum texunit_target_[kNumTextureUnitsCached];
  GLuint texunit_texture_[kNumTextureUnitsCached];

  static const int kNumFramesBuffered = 3;
  int frame_index_;

  static const size_t kVertexDataAlignment = 4;
  scoped_array<uint8_t> vertex_data_buffer_;
  size_t vertex_data_capacity_;
  size_t vertex_data_reserved_;
  size_t vertex_data_allocated_;
  GLuint vertex_data_buffer_handle_[kNumFramesBuffered];
  scoped_array<uint16_t> vertex_index_buffer_;
  size_t vertex_index_capacity_;
  size_t vertex_index_reserved_;
  size_t vertex_index_allocated_;
  GLuint vertex_index_buffer_handle_[kNumFramesBuffered];
  bool vertex_buffers_updated_;
};

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

#endif  // COBALT_RENDERER_RASTERIZER_EGL_GRAPHICS_STATE_H_
