1// Copyright (c) 2012 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 <GLES2/gl2.h>
6#include <GLES2/gl2ext.h>
7#include <GLES2/gl2extchromium.h>
8
9#include "gpu/command_buffer/tests/gl_manager.h"
10#include "gpu/command_buffer/tests/gl_test_utils.h"
11#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14#define SHADER(Src) #Src
15
16namespace gpu {
17
18class BindUniformLocationTest : public testing::Test {
19 protected:
20  static const GLsizei kResolution = 4;
21  virtual void SetUp() {
22    GLManager::Options options;
23    options.size = gfx::Size(kResolution, kResolution);
24    gl_.Initialize(options);
25  }
26
27  virtual void TearDown() {
28    gl_.Destroy();
29  }
30
31  GLManager gl_;
32};
33
34TEST_F(BindUniformLocationTest, Basic) {
35  ASSERT_TRUE(
36      GLTestHelper::HasExtension("GL_CHROMIUM_bind_uniform_location"));
37
38  static const char* v_shader_str = SHADER(
39      attribute vec4 a_position;
40      void main()
41      {
42         gl_Position = a_position;
43      }
44  );
45  static const char* f_shader_str = SHADER(
46      precision mediump float;
47      uniform vec4 u_colorC;
48      uniform vec4 u_colorB[2];
49      uniform vec4 u_colorA;
50      void main()
51      {
52        gl_FragColor = u_colorA + u_colorB[0] + u_colorB[1] + u_colorC;
53      }
54  );
55
56  GLint color_a_location = 3;
57  GLint color_b_location = 10;
58  GLint color_c_location = 5;
59
60  GLuint vertex_shader = GLTestHelper::LoadShader(
61      GL_VERTEX_SHADER, v_shader_str);
62  GLuint fragment_shader = GLTestHelper::LoadShader(
63      GL_FRAGMENT_SHADER, f_shader_str);
64
65  GLuint program = glCreateProgram();
66
67  glBindUniformLocationCHROMIUM(program, color_a_location, "u_colorA");
68  glBindUniformLocationCHROMIUM(program, color_b_location, "u_colorB[0]");
69  glBindUniformLocationCHROMIUM(program, color_c_location, "u_colorC");
70
71  glAttachShader(program, vertex_shader);
72  glAttachShader(program, fragment_shader);
73  // Link the program
74  glLinkProgram(program);
75  // Check the link status
76  GLint linked = 0;
77  glGetProgramiv(program, GL_LINK_STATUS, &linked);
78  EXPECT_EQ(1, linked);
79
80  GLint position_loc = glGetAttribLocation(program, "a_position");
81
82  GLTestHelper::SetupUnitQuad(position_loc);
83
84  glUseProgram(program);
85
86  static const float color_b[] = {
87    0.0f, 0.50f, 0.0f, 0.0f,
88    0.0f, 0.0f, 0.75f, 0.0f,
89  };
90
91  glUniform4f(color_a_location, 0.25f, 0.0f, 0.0f, 0.0f);
92  glUniform4fv(color_b_location, 2, color_b);
93  glUniform4f(color_c_location, 0.0f, 0.0f, 0.0f, 1.0f);
94
95  glDrawArrays(GL_TRIANGLES, 0, 6);
96
97  static const uint8 expected[] = { 64, 128, 192, 255 };
98  EXPECT_TRUE(
99      GLTestHelper::CheckPixels(0, 0, kResolution, kResolution, 1, expected));
100
101  GLTestHelper::CheckGLError("no errors", __LINE__);
102}
103
104TEST_F(BindUniformLocationTest, Compositor) {
105  ASSERT_TRUE(
106      GLTestHelper::HasExtension("GL_CHROMIUM_bind_uniform_location"));
107
108  static const char* v_shader_str = SHADER(
109      attribute vec4 a_position;
110      attribute vec2 a_texCoord;
111      uniform mat4 matrix;
112      uniform vec2 color_a[4];
113      uniform vec4 color_b;
114      varying vec4 v_color;
115      void main()
116      {
117          v_color.xy = color_a[0] + color_a[1];
118          v_color.zw = color_a[2] + color_a[3];
119          v_color += color_b;
120          gl_Position = matrix * a_position;
121      }
122  );
123
124  static const char* f_shader_str =  SHADER(
125      precision mediump float;
126      varying vec4 v_color;
127      uniform float alpha;
128      uniform vec4 multiplier;
129      uniform vec3 color_c[8];
130      void main()
131      {
132          vec4 color_c_sum = vec4(0.0);
133          color_c_sum.xyz += color_c[0];
134          color_c_sum.xyz += color_c[1];
135          color_c_sum.xyz += color_c[2];
136          color_c_sum.xyz += color_c[3];
137          color_c_sum.xyz += color_c[4];
138          color_c_sum.xyz += color_c[5];
139          color_c_sum.xyz += color_c[6];
140          color_c_sum.xyz += color_c[7];
141          color_c_sum.w = alpha;
142          color_c_sum *= multiplier;
143          gl_FragColor = v_color + color_c_sum;
144      }
145  );
146
147  int counter = 0;
148  int matrix_location = counter++;
149  int color_a_location = counter++;
150  int color_b_location = counter++;
151  int alpha_location = counter++;
152  int multiplier_location = counter++;
153  int color_c_location = counter++;
154
155  GLuint vertex_shader = GLTestHelper::LoadShader(
156      GL_VERTEX_SHADER, v_shader_str);
157  GLuint fragment_shader = GLTestHelper::LoadShader(
158      GL_FRAGMENT_SHADER, f_shader_str);
159
160  GLuint program = glCreateProgram();
161
162  glBindUniformLocationCHROMIUM(program, matrix_location, "matrix");
163  glBindUniformLocationCHROMIUM(program, color_a_location, "color_a");
164  glBindUniformLocationCHROMIUM(program, color_b_location, "color_b");
165  glBindUniformLocationCHROMIUM(program, alpha_location, "alpha");
166  glBindUniformLocationCHROMIUM(program, multiplier_location, "multiplier");
167  glBindUniformLocationCHROMIUM(program, color_c_location, "color_c");
168
169  glAttachShader(program, vertex_shader);
170  glAttachShader(program, fragment_shader);
171  // Link the program
172  glLinkProgram(program);
173  // Check the link status
174  GLint linked = 0;
175  glGetProgramiv(program, GL_LINK_STATUS, &linked);
176  EXPECT_EQ(1, linked);
177
178  GLint position_loc = glGetAttribLocation(program, "a_position");
179
180  GLTestHelper::SetupUnitQuad(position_loc);
181
182  glUseProgram(program);
183
184  static const float color_a[] = {
185    0.1f, 0.1f, 0.1f, 0.1f,
186    0.1f, 0.1f, 0.1f, 0.1f,
187  };
188
189  static const float color_c[] = {
190    0.1f, 0.1f, 0.1f,
191    0.1f, 0.1f, 0.1f,
192    0.1f, 0.1f, 0.1f,
193    0.1f, 0.1f, 0.1f,
194    0.1f, 0.1f, 0.1f,
195    0.1f, 0.1f, 0.1f,
196    0.1f, 0.1f, 0.1f,
197    0.1f, 0.1f, 0.1f,
198  };
199
200  static const float identity[] = {
201    1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
202  };
203
204  glUniformMatrix4fv(matrix_location, 1, false, identity);
205  glUniform2fv(color_a_location, 4, color_a);
206  glUniform4f(color_b_location, 0.2f, 0.2f, 0.2f, 0.2f);
207  glUniform1f(alpha_location, 0.8f);
208  glUniform4f(multiplier_location, 0.5f, 0.5f, 0.5f, 0.5f);
209  glUniform3fv(color_c_location, 8, color_c);
210
211  glDrawArrays(GL_TRIANGLES, 0, 6);
212
213  static const uint8 expected[] = { 204, 204, 204, 204 };
214  EXPECT_TRUE(
215      GLTestHelper::CheckPixels(0, 0, kResolution, kResolution, 1, expected));
216
217  GLTestHelper::CheckGLError("no errors", __LINE__);
218
219}
220
221}  // namespace gpu
222
223
224
225