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

#include "cc/output/geometry_binding.h"

#include "cc/output/gl_renderer.h"  // For the GLC() macro.
#include "gpu/command_buffer/client/gles2_interface.h"
#include "ui/gfx/geometry/rect_f.h"

namespace cc {

GeometryBinding::GeometryBinding(gpu::gles2::GLES2Interface* gl,
                                 const gfx::RectF& quad_vertex_rect)
    : gl_(gl), quad_vertices_vbo_(0), quad_elements_vbo_(0) {
  struct Vertex {
    float a_position[3];
    float a_texCoord[2];
    // Index of the vertex, divide by 4 to have the matrix for this quad.
    float a_index;
  };
  struct Quad {
    Vertex v0, v1, v2, v3;
  };
  struct QuadIndex {
    uint16 data[6];
  };

  COMPILE_ASSERT(sizeof(Quad) == 24 * sizeof(float), struct_is_densely_packed);
  COMPILE_ASSERT(sizeof(QuadIndex) == 6 * sizeof(uint16_t),
                 struct_is_densely_packed);

  Quad quad_list[8];
  QuadIndex quad_index_list[8];
  for (int i = 0; i < 8; i++) {
    Vertex v0 = {{quad_vertex_rect.x(), quad_vertex_rect.bottom(), 0.0f, },
                 {0.0f, 1.0f, }, i * 4.0f + 0.0f};
    Vertex v1 = {{quad_vertex_rect.x(), quad_vertex_rect.y(), 0.0f, },
                 {0.0f, 0.0f, }, i * 4.0f + 1.0f};
    Vertex v2 = {{quad_vertex_rect.right(), quad_vertex_rect.y(), 0.0f, },
                 {1.0f, .0f, }, i * 4.0f + 2.0f};
    Vertex v3 = {{quad_vertex_rect.right(), quad_vertex_rect.bottom(), 0.0f, },
                 {1.0f, 1.0f, }, i * 4.0f + 3.0f};
    Quad x = {v0, v1, v2, v3};
    quad_list[i] = x;
    QuadIndex y = {
        {static_cast<uint16>(0 + 4 * i), static_cast<uint16>(1 + 4 * i),
         static_cast<uint16>(2 + 4 * i), static_cast<uint16>(3 + 4 * i),
         static_cast<uint16>(0 + 4 * i), static_cast<uint16>(2 + 4 * i)}};
    quad_index_list[i] = y;
  }

  gl_->GenBuffers(1, &quad_vertices_vbo_);
  gl_->GenBuffers(1, &quad_elements_vbo_);
  GLC(gl_, gl_->BindBuffer(GL_ARRAY_BUFFER, quad_vertices_vbo_));
  GLC(gl_,
      gl_->BufferData(
          GL_ARRAY_BUFFER, sizeof(quad_list), quad_list, GL_STATIC_DRAW));
  GLC(gl_, gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_elements_vbo_));
  GLC(gl_,
      gl_->BufferData(GL_ELEMENT_ARRAY_BUFFER,
                      sizeof(quad_index_list),
                      quad_index_list,
                      GL_STATIC_DRAW));
}

GeometryBinding::~GeometryBinding() {
  gl_->DeleteBuffers(1, &quad_vertices_vbo_);
  gl_->DeleteBuffers(1, &quad_elements_vbo_);
}

void GeometryBinding::PrepareForDraw() {
  GLC(gl_, gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_elements_vbo_));

  GLC(gl_, gl_->BindBuffer(GL_ARRAY_BUFFER, quad_vertices_vbo_));
  // OpenGL defines the last parameter to VertexAttribPointer as type
  // "const GLvoid*" even though it is actually an offset into the buffer
  // object's data store and not a pointer to the client's address space.
  const void* offsets[3] = {
      0,
      reinterpret_cast<const void*>(3 * sizeof(float)),
      reinterpret_cast<const void*>(5 * sizeof(float)),
  };

  GLC(gl_, gl_->VertexAttribPointer(PositionAttribLocation(), 3, GL_FLOAT,
                                    false, 6 * sizeof(float), offsets[0]));
  GLC(gl_, gl_->VertexAttribPointer(TexCoordAttribLocation(), 2, GL_FLOAT,
                                    false, 6 * sizeof(float), offsets[1]));
  GLC(gl_, gl_->VertexAttribPointer(TriangleIndexAttribLocation(), 1, GL_FLOAT,
                                    false, 6 * sizeof(float), offsets[2]));
  GLC(gl_, gl_->EnableVertexAttribArray(PositionAttribLocation()));
  GLC(gl_, gl_->EnableVertexAttribArray(TexCoordAttribLocation()));
  GLC(gl_, gl_->EnableVertexAttribArray(TriangleIndexAttribLocation()));
}

}  // namespace cc
