1// Copyright 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "cc/output/geometry_binding.h"
6
7#include "cc/output/gl_renderer.h"  // For the GLC() macro.
8#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
9#include "third_party/khronos/GLES2/gl2.h"
10#include "ui/gfx/rect_f.h"
11
12namespace cc {
13
14GeometryBinding::GeometryBinding(WebKit::WebGraphicsContext3D* context,
15                                 const gfx::RectF& quad_vertex_rect)
16    : context_(context),
17      quad_vertices_vbo_(0),
18      quad_elements_vbo_(0) {
19  struct Vertex {
20    float a_position[3];
21    float a_texCoord[2];
22    // Index of the vertex, divide by 4 to have the matrix for this quad.
23    float a_index;
24  };
25  struct Quad {
26    Vertex v0, v1, v2, v3;
27  };
28  struct QuadIndex {
29    uint16 data[6];
30  };
31
32  COMPILE_ASSERT(
33      sizeof(Quad) == 24 * sizeof(float),  // NOLINT(runtime/sizeof)
34      struct_is_densely_packed);
35  COMPILE_ASSERT(
36      sizeof(QuadIndex) == 6 * sizeof(uint16_t),  // NOLINT(runtime/sizeof)
37      struct_is_densely_packed);
38
39  Quad quad_list[8];
40  QuadIndex quad_index_list[8];
41  for (int i = 0; i < 8; i++) {
42    Vertex v0 = { { quad_vertex_rect.x(), quad_vertex_rect.bottom(), 0.0f, },
43                  { 0.0f, 1.0f, },
44                  i * 4.0f + 0.0f };
45    Vertex v1 = { { quad_vertex_rect.x(), quad_vertex_rect.y(), 0.0f, },
46                  { 0.0f, 0.0f, },
47                  i * 4.0f + 1.0f };
48    Vertex v2 = { { quad_vertex_rect.right(), quad_vertex_rect.y(), 0.0f, },
49                  { 1.0f, .0f, },
50                  i * 4.0f + 2.0f };
51    Vertex v3 = { { quad_vertex_rect.right(),
52                    quad_vertex_rect.bottom(),
53                    0.0f, },
54                  { 1.0f, 1.0f, },
55                  i * 4.0f + 3.0f };
56    Quad x = { v0, v1, v2, v3 };
57    quad_list[i] = x;
58    QuadIndex y = { { static_cast<uint16>(0 + 4 * i),
59                      static_cast<uint16>(1 + 4 * i),
60                      static_cast<uint16>(2 + 4 * i),
61                      static_cast<uint16>(3 + 4 * i),
62                      static_cast<uint16>(0 + 4 * i),
63                      static_cast<uint16>(2 + 4 * i) } };
64    quad_index_list[i] = y;
65  }
66
67  GLC(context_, quad_vertices_vbo_ = context_->createBuffer());
68  GLC(context_, quad_elements_vbo_ = context_->createBuffer());
69  GLC(context_, context_->bindBuffer(GL_ARRAY_BUFFER, quad_vertices_vbo_));
70  GLC(context_,
71      context_->bufferData(
72          GL_ARRAY_BUFFER, sizeof(quad_list), quad_list, GL_STATIC_DRAW));
73  GLC(context_,
74      context_->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_elements_vbo_));
75  GLC(context_,
76      context_->bufferData(GL_ELEMENT_ARRAY_BUFFER,
77                           sizeof(quad_index_list),
78                           quad_index_list,
79                           GL_STATIC_DRAW));
80}
81
82GeometryBinding::~GeometryBinding() {
83  GLC(context_, context_->deleteBuffer(quad_vertices_vbo_));
84  GLC(context_, context_->deleteBuffer(quad_elements_vbo_));
85}
86
87void GeometryBinding::PrepareForDraw() {
88  GLC(context_,
89      context_->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_elements_vbo_));
90
91  GLC(context_, context_->bindBuffer(GL_ARRAY_BUFFER, quad_vertices_vbo_));
92  GLC(context_,
93      context_->vertexAttribPointer(
94          PositionAttribLocation(),
95          3,
96          GL_FLOAT,
97          false,
98          6 * sizeof(float),  // NOLINT(runtime/sizeof)
99          0));
100  GLC(context_,
101      context_->vertexAttribPointer(
102          TexCoordAttribLocation(),
103          2,
104          GL_FLOAT,
105          false,
106          6 * sizeof(float),  // NOLINT(runtime/sizeof)
107          3 * sizeof(float)));  // NOLINT(runtime/sizeof)
108  GLC(context_,
109      context_->vertexAttribPointer(
110          TriangleIndexAttribLocation(),
111          1,
112          GL_FLOAT,
113          false,
114          6 * sizeof(float),  // NOLINT(runtime/sizeof)
115          5 * sizeof(float)));  // NOLINT(runtime/sizeof)
116  GLC(context_, context_->enableVertexAttribArray(PositionAttribLocation()));
117  GLC(context_, context_->enableVertexAttribArray(TexCoordAttribLocation()));
118  GLC(context_,
119      context_->enableVertexAttribArray(TriangleIndexAttribLocation()));
120}
121
122}  // namespace cc
123