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.
5 #include "gpu/command_buffer/tests/gl_test_utils.h"
8 #include "base/basictypes.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 // GCC requires these declarations, but MSVC requires they not be present.
15 const uint8
GLTestHelper::kCheckClearValue
;
18 bool GLTestHelper::HasExtension(const char* extension
) {
19 std::string
extensions(
20 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS
)));
21 return extensions
.find(extension
) != std::string::npos
;
24 bool GLTestHelper::CheckGLError(const char* msg
, int line
) {
26 GLenum error
= GL_NO_ERROR
;
27 while ((error
= glGetError()) != GL_NO_ERROR
) {
29 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), error
)
30 << "GL ERROR in " << msg
<< " at line " << line
<< " : " << error
;
35 GLuint
GLTestHelper::LoadShader(GLenum type
, const char* shaderSrc
) {
36 GLuint shader
= glCreateShader(type
);
37 // Load the shader source
38 glShaderSource(shader
, 1, &shaderSrc
, NULL
);
40 glCompileShader(shader
);
41 // Check the compile status
43 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &value
);
47 glGetShaderInfoLog(shader
, sizeof(buffer
), &length
, buffer
);
48 std::string
log(buffer
, length
);
49 EXPECT_EQ(1, value
) << "Error compiling shader: " << log
;
50 glDeleteShader(shader
);
56 GLuint
GLTestHelper::SetupProgram(
57 GLuint vertex_shader
, GLuint fragment_shader
) {
58 // Create the program object
59 GLuint program
= glCreateProgram();
60 glAttachShader(program
, vertex_shader
);
61 glAttachShader(program
, fragment_shader
);
63 glLinkProgram(program
);
64 // Check the link status
66 glGetProgramiv(program
, GL_LINK_STATUS
, &linked
);
70 glGetProgramInfoLog(program
, sizeof(buffer
), &length
, buffer
);
71 std::string
log(buffer
, length
);
72 EXPECT_EQ(1, linked
) << "Error linking program: " << log
;
73 glDeleteProgram(program
);
79 GLuint
GLTestHelper::LoadProgram(
80 const char* vertex_shader_source
,
81 const char* fragment_shader_source
) {
82 GLuint vertex_shader
= LoadShader(
83 GL_VERTEX_SHADER
, vertex_shader_source
);
84 GLuint fragment_shader
= LoadShader(
85 GL_FRAGMENT_SHADER
, fragment_shader_source
);
86 if (!vertex_shader
|| !fragment_shader
) {
89 return SetupProgram(vertex_shader
, fragment_shader
);
92 GLuint
GLTestHelper::SetupUnitQuad(GLint position_location
) {
94 glGenBuffers(1, &vbo
);
95 glBindBuffer(GL_ARRAY_BUFFER
, vbo
);
96 static float vertices
[] = {
104 glBufferData(GL_ARRAY_BUFFER
, sizeof(vertices
), vertices
, GL_STATIC_DRAW
);
105 glEnableVertexAttribArray(position_location
);
106 glVertexAttribPointer(position_location
, 2, GL_FLOAT
, GL_FALSE
, 0, 0);
111 GLuint
GLTestHelper::SetupColorsForUnitQuad(
112 GLint location
, const GLfloat color
[4], GLenum usage
) {
114 glGenBuffers(1, &vbo
);
115 glBindBuffer(GL_ARRAY_BUFFER
, vbo
);
116 GLfloat vertices
[6 * 4];
117 for (int ii
= 0; ii
< 6; ++ii
) {
118 for (int jj
= 0; jj
< 4; ++jj
) {
119 vertices
[ii
* 4 + jj
] = color
[jj
];
122 glBufferData(GL_ARRAY_BUFFER
, sizeof(vertices
), vertices
, usage
);
123 glEnableVertexAttribArray(location
);
124 glVertexAttribPointer(location
, 4, GL_FLOAT
, GL_FALSE
, 0, 0);
129 bool GLTestHelper::CheckPixels(
130 GLint x
, GLint y
, GLsizei width
, GLsizei height
, GLint tolerance
,
131 const uint8
* color
) {
132 GLsizei size
= width
* height
* 4;
133 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
134 memset(pixels
.get(), kCheckClearValue
, size
);
135 glReadPixels(x
, y
, width
, height
, GL_RGBA
, GL_UNSIGNED_BYTE
, pixels
.get());
137 for (GLint yy
= 0; yy
< height
; ++yy
) {
138 for (GLint xx
= 0; xx
< width
; ++xx
) {
139 int offset
= yy
* width
* 4 + xx
* 4;
140 for (int jj
= 0; jj
< 4; ++jj
) {
141 uint8 actual
= pixels
[offset
+ jj
];
142 uint8 expected
= color
[jj
];
143 int diff
= actual
- expected
;
144 diff
= diff
< 0 ? -diff
: diff
;
145 if (diff
> tolerance
) {
146 EXPECT_EQ(expected
, actual
) << " at " << (xx
+ x
) << ", " << (yy
+ y
)
147 << " channel " << jj
;
149 // Exit early just so we don't spam the log but we print enough
150 // to hopefully make it easy to diagnose the issue.
151 if (bad_count
> 16) {
158 return bad_count
== 0;
163 void Set16BitValue(uint8 dest
[2], uint16 value
) {
164 dest
[0] = value
& 0xFFu
;
165 dest
[1] = value
>> 8;
168 void Set32BitValue(uint8 dest
[4], uint32 value
) {
169 dest
[0] = (value
>> 0) & 0xFFu
;
170 dest
[1] = (value
>> 8) & 0xFFu
;
171 dest
[2] = (value
>> 16) & 0xFFu
;
172 dest
[3] = (value
>> 24) & 0xFFu
;
175 struct BitmapHeaderFile
{
182 struct BitmapInfoHeader
{
188 uint8 compression
[4];
190 uint8 x_pels_per_meter
[4];
191 uint8 y_pels_per_meter
[4];
193 uint8 clr_important
[4];
198 bool GLTestHelper::SaveBackbufferAsBMP(
199 const char* filename
, int width
, int height
) {
200 FILE* fp
= fopen(filename
, "wb");
201 EXPECT_TRUE(fp
!= NULL
);
202 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
203 int num_pixels
= width
* height
;
204 int size
= num_pixels
* 4;
205 scoped_ptr
<uint8
[]> data(new uint8
[size
]);
206 uint8
* pixels
= data
.get();
207 glReadPixels(0, 0, width
, height
, GL_RGBA
, GL_UNSIGNED_BYTE
, pixels
);
210 for (int ii
= 0; ii
< num_pixels
; ++ii
) {
212 uint8 t
= pixels
[offset
+ 0];
213 pixels
[offset
+ 0] = pixels
[offset
+ 2];
214 pixels
[offset
+ 2] = t
;
217 BitmapHeaderFile bhf
;
218 BitmapInfoHeader bih
;
222 Set32BitValue(bhf
.size
, 0);
223 Set32BitValue(bhf
.reserved
, 0);
224 Set32BitValue(bhf
.offset
, sizeof(bhf
) + sizeof(bih
));
226 Set32BitValue(bih
.size
, sizeof(bih
));
227 Set32BitValue(bih
.width
, width
);
228 Set32BitValue(bih
.height
, height
);
229 Set16BitValue(bih
.planes
, 1);
230 Set16BitValue(bih
.bit_count
, 32);
231 Set32BitValue(bih
.compression
, 0);
232 Set32BitValue(bih
.x_pels_per_meter
, 0);
233 Set32BitValue(bih
.y_pels_per_meter
, 0);
234 Set32BitValue(bih
.clr_used
, 0);
235 Set32BitValue(bih
.clr_important
, 0);
237 fwrite(&bhf
, sizeof(bhf
), 1, fp
);
238 fwrite(&bih
, sizeof(bih
), 1, fp
);
239 fwrite(pixels
, size
, 1, fp
);
244 int GLTestHelper::RunTests(int argc
, char** argv
) {
245 testing::InitGoogleMock(&argc
, argv
);
246 return RUN_ALL_TESTS();