// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file contains the ContextState class.

#ifndef GPU_COMMAND_BUFFER_SERVICE_CONTEXT_STATE_H_
#define GPU_COMMAND_BUFFER_SERVICE_CONTEXT_STATE_H_

#include <memory>
#include <vector>

#include "base/logging.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/sampler_manager.h"
#include "gpu/command_buffer/service/shader_manager.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/command_buffer/service/vertex_array_manager.h"
#include "gpu/command_buffer/service/vertex_attrib_manager.h"
#include "gpu/gpu_export.h"

namespace gpu {
namespace gles2 {

class Buffer;
class ErrorState;
class ErrorStateClient;
class FeatureInfo;
class IndexedBufferBindingHost;
class Logger;
class Program;
class Renderbuffer;
class TransformFeedback;

// State associated with each texture unit.
struct GPU_EXPORT TextureUnit {
  TextureUnit();
  TextureUnit(const TextureUnit& other);
  ~TextureUnit();

  // The last target that was bound to this texture unit.
  GLenum bind_target;

  // texture currently bound to this unit's GL_TEXTURE_2D with glBindTexture
  scoped_refptr<TextureRef> bound_texture_2d;

  // texture currently bound to this unit's GL_TEXTURE_CUBE_MAP with
  // glBindTexture
  scoped_refptr<TextureRef> bound_texture_cube_map;

  // texture currently bound to this unit's GL_TEXTURE_EXTERNAL_OES with
  // glBindTexture
  scoped_refptr<TextureRef> bound_texture_external_oes;

  // texture currently bound to this unit's GL_TEXTURE_RECTANGLE_ARB with
  // glBindTexture
  scoped_refptr<TextureRef> bound_texture_rectangle_arb;

  // texture currently bound to this unit's GL_TEXTURE_3D with glBindTexture
  scoped_refptr<TextureRef> bound_texture_3d;

  // texture currently bound to this unit's GL_TEXTURE_2D_ARRAY with
  // glBindTexture
  scoped_refptr<TextureRef> bound_texture_2d_array;

  TextureRef* GetInfoForSamplerType(GLenum type) {
    switch (type) {
      case GL_SAMPLER_2D:
      case GL_SAMPLER_2D_SHADOW:
      case GL_INT_SAMPLER_2D:
      case GL_UNSIGNED_INT_SAMPLER_2D:
        return bound_texture_2d.get();
      case GL_SAMPLER_CUBE:
      case GL_SAMPLER_CUBE_SHADOW:
      case GL_INT_SAMPLER_CUBE:
      case GL_UNSIGNED_INT_SAMPLER_CUBE:
        return bound_texture_cube_map.get();
      case GL_SAMPLER_EXTERNAL_OES:
        return bound_texture_external_oes.get();
      case GL_SAMPLER_2D_RECT_ARB:
        return bound_texture_rectangle_arb.get();
      case GL_SAMPLER_3D:
      case GL_INT_SAMPLER_3D:
      case GL_UNSIGNED_INT_SAMPLER_3D:
        return bound_texture_3d.get();
      case GL_SAMPLER_2D_ARRAY:
      case GL_SAMPLER_2D_ARRAY_SHADOW:
      case GL_INT_SAMPLER_2D_ARRAY:
      case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
        return bound_texture_2d_array.get();
      default:
        NOTREACHED();
        return nullptr;
    }
  }

  TextureRef* GetInfoForTarget(GLenum target) {
    switch (target) {
      case GL_TEXTURE_2D:
        return bound_texture_2d.get();
      case GL_TEXTURE_CUBE_MAP:
        return bound_texture_cube_map.get();
      case GL_TEXTURE_EXTERNAL_OES:
        return bound_texture_external_oes.get();
      case GL_TEXTURE_RECTANGLE_ARB:
        return bound_texture_rectangle_arb.get();
      case GL_TEXTURE_3D:
        return bound_texture_3d.get();
      case GL_TEXTURE_2D_ARRAY:
        return bound_texture_2d_array.get();
      default:
        NOTREACHED();
        return nullptr;
    }
  }

  void SetInfoForTarget(GLenum target, TextureRef* texture_ref) {
    switch (target) {
      case GL_TEXTURE_2D:
        bound_texture_2d = texture_ref;
        break;
      case GL_TEXTURE_CUBE_MAP:
        bound_texture_cube_map = texture_ref;
        break;
      case GL_TEXTURE_EXTERNAL_OES:
        bound_texture_external_oes = texture_ref;
        break;
      case GL_TEXTURE_RECTANGLE_ARB:
        bound_texture_rectangle_arb = texture_ref;
        break;
      case GL_TEXTURE_3D:
        bound_texture_3d = texture_ref;
        break;
      case GL_TEXTURE_2D_ARRAY:
        bound_texture_2d_array = texture_ref;
        break;
      default:
        NOTREACHED();
    }
  }
};

class GPU_EXPORT Vec4 {
 public:
  Vec4() {
    v_[0].float_value = 0.0f;
    v_[1].float_value = 0.0f;
    v_[2].float_value = 0.0f;
    v_[3].float_value = 1.0f;
    type_ = SHADER_VARIABLE_FLOAT;
  }

  template <typename T>
  void GetValues(T* values) const;

  template <typename T>
  void SetValues(const T* values);

  ShaderVariableBaseType type() const {
    return type_;
  }

  bool Equal(const Vec4& other) const;

 private:
  union ValueUnion {
    GLfloat float_value;
    GLint int_value;
    GLuint uint_value;
  };

  ValueUnion v_[4];
  ShaderVariableBaseType type_;
};

template <>
GPU_EXPORT void Vec4::GetValues<GLfloat>(GLfloat* values) const;
template <>
GPU_EXPORT void Vec4::GetValues<GLint>(GLint* values) const;
template <>
GPU_EXPORT void Vec4::GetValues<GLuint>(GLuint* values) const;

template <>
GPU_EXPORT void Vec4::SetValues<GLfloat>(const GLfloat* values);
template <>
GPU_EXPORT void Vec4::SetValues<GLint>(const GLint* values);
template <>
GPU_EXPORT void Vec4::SetValues<GLuint>(const GLuint* values);

struct GPU_EXPORT ContextState {
  enum Dimension {
    k2D,
    k3D
  };

  ContextState(FeatureInfo* feature_info,
               ErrorStateClient* error_state_client,
               Logger* logger);
  ~ContextState();

  void set_api(gl::GLApi* api) { api_ = api; }
  gl::GLApi* api() const { return api_; }

  void Initialize();

  void SetLineWidthBounds(GLfloat min, GLfloat max);

  void SetIgnoreCachedStateForTest(bool ignore) {
    ignore_cached_state = ignore;
  }

  void RestoreState(const ContextState* prev_state);
  void InitCapabilities(const ContextState* prev_state) const;
  void InitState(const ContextState* prev_state) const;

  void RestoreActiveTexture() const;
  void RestoreAllTextureUnitAndSamplerBindings(
      const ContextState* prev_state) const;
  void RestoreActiveTextureUnitBinding(unsigned int target) const;
  void RestoreVertexAttribValues() const;
  void RestoreVertexAttribArrays(
      const scoped_refptr<VertexAttribManager> attrib_manager) const;
  void RestoreVertexAttribs() const;
  void RestoreBufferBindings() const;
  void RestoreGlobalState(const ContextState* prev_state) const;
  void RestoreProgramSettings(const ContextState* prev_state,
                              bool restore_transform_feedback_bindings) const;
  void RestoreRenderbufferBindings();
  void RestoreIndexedUniformBufferBindings(const ContextState* prev_state);
  void RestoreTextureUnitBindings(
      GLuint unit, const ContextState* prev_state) const;
  void RestoreSamplerBinding(GLuint unit, const ContextState* prev_state) const;

  void PushTextureUnpackState() const;
  void RestoreUnpackState() const;
  void DoLineWidth(GLfloat width) const;

  // Helper for getting cached state.
  bool GetStateAsGLint(
      GLenum pname, GLint* params, GLsizei* num_written) const;
  bool GetStateAsGLfloat(
      GLenum pname, GLfloat* params, GLsizei* num_written) const;
  bool GetEnabled(GLenum cap) const;

  inline void SetDeviceColorMask(GLboolean red,
                                 GLboolean green,
                                 GLboolean blue,
                                 GLboolean alpha) {
    if (cached_color_mask_red == red && cached_color_mask_green == green &&
        cached_color_mask_blue == blue && cached_color_mask_alpha == alpha &&
        !ignore_cached_state)
      return;
    cached_color_mask_red = red;
    cached_color_mask_green = green;
    cached_color_mask_blue = blue;
    cached_color_mask_alpha = alpha;
    api()->glColorMaskFn(red, green, blue, alpha);
  }

  inline void SetDeviceDepthMask(GLboolean mask) {
    if (cached_depth_mask == mask && !ignore_cached_state)
      return;
    cached_depth_mask = mask;
    api()->glDepthMaskFn(mask);
  }

  inline void SetDeviceStencilMaskSeparate(GLenum op, GLuint mask) {
    if (op == GL_FRONT) {
      if (cached_stencil_front_writemask == mask && !ignore_cached_state)
        return;
      cached_stencil_front_writemask = mask;
    } else if (op == GL_BACK) {
      if (cached_stencil_back_writemask == mask && !ignore_cached_state)
        return;
      cached_stencil_back_writemask = mask;
    } else {
      NOTREACHED();
      return;
    }
    api()->glStencilMaskSeparateFn(op, mask);
  }

  ErrorState* GetErrorState();

  void SetBoundBuffer(GLenum target, Buffer* buffer);
  void RemoveBoundBuffer(Buffer* buffer);

  void InitGenericAttribs(GLuint max_vertex_attribs) {
    attrib_values.resize(max_vertex_attribs);

    uint32_t packed_size = max_vertex_attribs / 16;
    packed_size += (max_vertex_attribs % 16 == 0) ? 0 : 1;
    generic_attrib_base_type_mask_.resize(packed_size);
    for (uint32_t i = 0; i < packed_size; ++i) {
      // All generic attribs are float type by default.
      generic_attrib_base_type_mask_[i] = 0x55555555u * SHADER_VARIABLE_FLOAT;
    }
  }

  void SetGenericVertexAttribBaseType(GLuint index, GLenum base_type) {
    DCHECK_LT(index, attrib_values.size());
    int shift_bits = (index % 16) * 2;
    generic_attrib_base_type_mask_[index / 16] &= ~(0x3 << shift_bits);
    generic_attrib_base_type_mask_[index / 16] |= (base_type << shift_bits);
  }

  const std::vector<uint32_t>& generic_attrib_base_type_mask() const {
    return generic_attrib_base_type_mask_;
  }

  void UnbindTexture(TextureRef* texture);
  void UnbindSampler(Sampler* sampler);

  PixelStoreParams GetPackParams();
  PixelStoreParams GetUnpackParams(Dimension dimension);

  // If a buffer object is bound to PIXEL_PACK_BUFFER, set all pack parameters
  // user values; otherwise, set them to 0.
  void UpdatePackParameters() const;
  // If a buffer object is bound to PIXEL_UNPACK_BUFFER, set all unpack
  // parameters user values; otherwise, set them to 0.
  void UpdateUnpackParameters() const;

  void SetMaxWindowRectangles(size_t max);
  size_t GetMaxWindowRectangles() const;
  void SetWindowRectangles(GLenum mode,
                           size_t count,
                           const volatile GLint* box);
  template <typename T>
  void GetWindowRectangle(GLuint index, T* box) {
    for (size_t i = 0; i < 4; ++i) {
      box[i] = window_rectangles_[4 * index + i];
    }
  }
  void UpdateWindowRectangles() const;
  void UpdateWindowRectanglesForBoundDrawFramebufferClientID(GLuint client_id);

  void EnableDisableFramebufferSRGB(bool enable);

  #include "gpu/command_buffer/service/context_state_autogen.h"

  EnableFlags enable_flags;

  // Current active texture by 0 - n index.
  // In other words, if we call glActiveTexture(GL_TEXTURE2) this value would
  // be 2.
  GLuint active_texture_unit;

  // The currently bound array buffer. If this is 0 it is illegal to call
  // glVertexAttribPointer.
  scoped_refptr<Buffer> bound_array_buffer;

  scoped_refptr<Buffer> bound_copy_read_buffer;
  scoped_refptr<Buffer> bound_copy_write_buffer;
  scoped_refptr<Buffer> bound_pixel_pack_buffer;
  scoped_refptr<Buffer> bound_pixel_unpack_buffer;
  scoped_refptr<Buffer> bound_transform_feedback_buffer;
  scoped_refptr<Buffer> bound_uniform_buffer;

  // Which textures are bound to texture units through glActiveTexture.
  std::vector<TextureUnit> texture_units;

  // Which samplers are bound to each texture unit;
  std::vector<scoped_refptr<Sampler>> sampler_units;

  // We create a transform feedback as the default one per ES3 enabled context
  // instead of using GL's default one to make context switching easier.
  // For other context, we will never change the default transform feedback's
  // states, so we can just use the GL's default one.
  scoped_refptr<TransformFeedback> default_transform_feedback;

  scoped_refptr<TransformFeedback> bound_transform_feedback;

  scoped_refptr<IndexedBufferBindingHost> indexed_uniform_buffer_bindings;

  // The values for each attrib.
  std::vector<Vec4> attrib_values;

  // Class that manages vertex attribs.
  scoped_refptr<VertexAttribManager> vertex_attrib_manager;
  scoped_refptr<VertexAttribManager> default_vertex_attrib_manager;

  // The program in use by glUseProgram
  scoped_refptr<Program> current_program;

  // The currently bound renderbuffer
  scoped_refptr<Renderbuffer> bound_renderbuffer;
  bool bound_renderbuffer_valid;

  bool pack_reverse_row_order;
  bool ignore_cached_state;

  mutable bool fbo_binding_for_scissor_workaround_dirty;

  GLuint current_draw_framebuffer_client_id = 0;

 private:
  void EnableDisable(GLenum pname, bool enable) const;

  void InitStateManual(const ContextState* prev_state) const;

  // EnableDisableFramebufferSRGB is called at very high frequency. Cache the
  // true value of FRAMEBUFFER_SRGB, if we know it, to elide some of these
  // calls.
  bool framebuffer_srgb_valid_ = false;
  bool framebuffer_srgb_ = false;

  // Generic vertex attrib base types: FLOAT, INT, or UINT.
  // Each base type is encoded into 2 bits, the lowest 2 bits for location 0,
  // the highest 2 bits for location (max_vertex_attribs - 1).
  std::vector<uint32_t> generic_attrib_base_type_mask_;

  GLfloat line_width_min_ = 0.0f;
  GLfloat line_width_max_ = 1.0f;

  // Stores the list of N window rectangles as N*4 GLints, like
  // vector<[x,y,w,h]>. Always has space for MAX_WINDOW_RECTANGLES rectangles.
  std::vector<GLint> window_rectangles_;

  gl::GLApi* api_ = nullptr;
  FeatureInfo* feature_info_;
  std::unique_ptr<ErrorState> error_state_;
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_CONTEXT_STATE_H_
