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
8#include "gpu/command_buffer/tests/gl_manager.h"
9#include "gpu/command_buffer/tests/gl_test_utils.h"
10#include "testing/gmock/include/gmock/gmock.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13#define SHADER(Src) #Src
14
15namespace gpu {
16
17class GLProgramTest : public testing::Test {
18 protected:
19  virtual void SetUp() {
20    gl_.Initialize(GLManager::Options());
21  }
22
23  virtual void TearDown() {
24    gl_.Destroy();
25  }
26
27  GLManager gl_;
28};
29
30TEST_F(GLProgramTest, GetSetUniform) {
31  static const char* v_shader_str = SHADER(
32      attribute vec4 a_vertex;
33      attribute vec3 a_normal;
34
35      uniform mat4 u_modelViewProjMatrix;
36
37      struct MyStruct
38      {
39        int x;
40        int y;
41      };
42
43      uniform MyStruct u_struct;
44      uniform float u_array[4];
45
46      varying vec3 v_normal;
47
48      void main()
49      {
50          v_normal = a_normal;
51          gl_Position = u_modelViewProjMatrix * a_vertex +
52              vec4(u_struct.x, u_struct.y, 0, 1) +
53              vec4(u_array[0], u_array[1], u_array[2], u_array[3]);
54      }
55  );
56  static const char* f_shader_str = SHADER(
57      varying mediump vec3 v_normal;
58
59      void main()
60      {
61          gl_FragColor = vec4(v_normal/2.0+vec3(0.5), 1);
62      }
63  );
64
65  // Load the program.
66  GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
67  glUseProgram(program);
68  // Relink program.
69  glLinkProgram(program);
70
71  // These tests will fail on NVidia if not worked around by
72  // command buffer.
73  GLint location_sx = glGetUniformLocation(program, "u_struct.x");
74  GLint location_array_0 = glGetUniformLocation(program, "u_array[0]");
75
76  glUniform1i(location_sx, 3);
77  glUniform1f(location_array_0, 123);
78
79  GLint int_value = 0;
80  GLfloat float_value = 0;
81
82  glGetUniformiv(program, location_sx, &int_value);
83  EXPECT_EQ(3, int_value);
84  glGetUniformfv(program, location_array_0, &float_value);
85  EXPECT_EQ(123.0f, float_value);
86
87  GLTestHelper::CheckGLError("no errors", __LINE__);
88}
89
90TEST_F(GLProgramTest, NewShaderInCurrentProgram) {
91  static const char* v_shader_str = SHADER(
92      attribute vec4 a_position;
93      void main()
94      {
95         gl_Position = a_position;
96      }
97  );
98  static const char* f_red_shader_str = SHADER(
99      void main()
100      {
101          gl_FragColor = vec4(1, 0, 0, 1);
102      }
103  );
104  static const char* f_blue_shader_str = SHADER(
105      void main()
106      {
107          gl_FragColor = vec4(0, 0, 1, 1);
108      }
109  );
110
111  // Load the program.
112  GLuint vs = GLTestHelper::LoadShader(GL_VERTEX_SHADER, v_shader_str);
113  GLuint fs = GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, f_red_shader_str);
114  GLuint program = GLTestHelper::SetupProgram(vs, fs);
115  glUseProgram(program);
116  glShaderSource(fs, 1, &f_blue_shader_str, NULL);
117  glCompileShader(fs);
118  glLinkProgram(program);
119  // We specifically don't call UseProgram again.
120  GLuint position_loc = glGetAttribLocation(program, "a_position");
121  GLTestHelper::SetupUnitQuad(position_loc);
122  glDrawArrays(GL_TRIANGLES, 0, 6);
123  uint8 expected_color[] = { 0, 0, 255, 255, };
124  EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color));
125  GLTestHelper::CheckGLError("no errors", __LINE__);
126}
127
128TEST_F(GLProgramTest, UniformsInCurrentProgram) {
129  static const char* v_shader_str = SHADER(
130      attribute vec4 a_position;
131      void main()
132      {
133         gl_Position = a_position;
134      }
135  );
136  static const char* f_shader_str = SHADER(
137      precision mediump float;
138      uniform vec4 u_color;
139      void main()
140      {
141          gl_FragColor = u_color;;
142      }
143  );
144
145  // Load the program.
146  GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
147  glUseProgram(program);
148
149  // Relink.
150  glLinkProgram(program);
151
152  // This test will fail on NVidia Linux if not worked around.
153  GLint color_location = glGetUniformLocation(program, "u_color");
154  glUniform4f(color_location, 0.0f, 0.0f, 1.0f, 1.0f);
155
156  // We specifically don't call UseProgram again.
157  GLuint position_loc = glGetAttribLocation(program, "a_position");
158  GLTestHelper::SetupUnitQuad(position_loc);
159  glDrawArrays(GL_TRIANGLES, 0, 6);
160  uint8 expected_color[] = { 0, 0, 255, 255, };
161  EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color));
162  GLTestHelper::CheckGLError("no errors", __LINE__);
163}
164
165}  // namespace gpu
166
167