1 // Copyright 2014 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.
6 #include <GLES2/gl2chromium.h>
7 #include <GLES2/gl2ext.h>
8 #include <GLES2/gl2extchromium.h>
10 #include "base/bind.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/process/process_handle.h"
13 #include "gpu/command_buffer/client/gles2_implementation.h"
14 #include "gpu/command_buffer/service/command_buffer_service.h"
15 #include "gpu/command_buffer/service/image_manager.h"
16 #include "gpu/command_buffer/tests/gl_manager.h"
17 #include "gpu/command_buffer/tests/gl_test_utils.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "ui/gfx/gpu_memory_buffer.h"
21 #include "ui/gl/gl_image.h"
24 using testing::IgnoreResult
;
25 using testing::InvokeWithoutArgs
;
26 using testing::Invoke
;
27 using testing::Return
;
28 using testing::SetArgPointee
;
29 using testing::StrictMock
;
34 static const int kImageWidth
= 32;
35 static const int kImageHeight
= 32;
37 class GpuMemoryBufferTest
38 : public testing::TestWithParam
<gfx::GpuMemoryBuffer::Format
> {
40 void SetUp() override
{
41 GLManager::Options options
;
42 options
.size
= gfx::Size(kImageWidth
, kImageHeight
);
43 gl_
.Initialize(options
);
47 void TearDown() override
{
56 #define SHADER(Src) #Src
59 const char kVertexShader
[] =
61 attribute vec4 a_position
;
62 varying vec2 v_texCoord
;
64 gl_Position
= a_position
;
65 v_texCoord
= vec2((a_position
.x
+ 1.0) * 0.5, (a_position
.y
+ 1.0) * 0.5);
69 const char* kFragmentShader
=
71 precision mediump
float;
72 uniform sampler2D a_texture
;
73 varying vec2 v_texCoord
;
75 gl_FragColor
= texture2D(a_texture
, v_texCoord
);
80 std::vector
<uint8
> GetTexturePixel(gfx::GpuMemoryBuffer::Format format
) {
81 std::vector
<uint8
> pixel
;
83 case gfx::GpuMemoryBuffer::R_8
:
84 pixel
.push_back(255u);
86 case gfx::GpuMemoryBuffer::RGBA_8888
:
87 pixel
.push_back(255u);
90 pixel
.push_back(255u);
92 case gfx::GpuMemoryBuffer::BGRA_8888
:
95 pixel
.push_back(255u);
96 pixel
.push_back(255u);
98 case gfx::GpuMemoryBuffer::ATC
:
99 case gfx::GpuMemoryBuffer::ATCIA
:
100 case gfx::GpuMemoryBuffer::DXT1
:
101 case gfx::GpuMemoryBuffer::DXT5
:
102 case gfx::GpuMemoryBuffer::ETC1
:
103 case gfx::GpuMemoryBuffer::RGBX_8888
:
104 case gfx::GpuMemoryBuffer::YUV_420
:
106 return std::vector
<uint8
>();
110 return std::vector
<uint8
>();
113 std::vector
<uint8
> GetFramebufferPixel(
114 gfx::GpuMemoryBuffer::Format format
) {
115 std::vector
<uint8
> pixel
;
117 case gfx::GpuMemoryBuffer::R_8
:
118 case gfx::GpuMemoryBuffer::RGBA_8888
:
119 case gfx::GpuMemoryBuffer::BGRA_8888
:
120 pixel
.push_back(255u);
123 pixel
.push_back(255u);
125 case gfx::GpuMemoryBuffer::ATC
:
126 case gfx::GpuMemoryBuffer::ATCIA
:
127 case gfx::GpuMemoryBuffer::DXT1
:
128 case gfx::GpuMemoryBuffer::DXT5
:
129 case gfx::GpuMemoryBuffer::ETC1
:
130 case gfx::GpuMemoryBuffer::RGBX_8888
:
131 case gfx::GpuMemoryBuffer::YUV_420
:
133 return std::vector
<uint8
>();
137 return std::vector
<uint8
>();
140 GLenum
InternalFormat(gfx::GpuMemoryBuffer::Format format
) {
142 case gfx::GpuMemoryBuffer::R_8
:
144 case gfx::GpuMemoryBuffer::RGBA_8888
:
146 case gfx::GpuMemoryBuffer::BGRA_8888
:
148 case gfx::GpuMemoryBuffer::ATC
:
149 case gfx::GpuMemoryBuffer::ATCIA
:
150 case gfx::GpuMemoryBuffer::DXT1
:
151 case gfx::GpuMemoryBuffer::DXT5
:
152 case gfx::GpuMemoryBuffer::ETC1
:
153 case gfx::GpuMemoryBuffer::RGBX_8888
:
154 case gfx::GpuMemoryBuffer::YUV_420
:
165 // An end to end test that tests the whole GpuMemoryBuffer lifecycle.
166 TEST_P(GpuMemoryBufferTest
, Lifecycle
) {
167 ASSERT_TRUE((GetParam() != gfx::GpuMemoryBuffer::R_8
) ||
168 gl_
.GetCapabilities().texture_rg
);
170 GLuint texture_id
= 0;
171 glGenTextures(1, &texture_id
);
172 ASSERT_NE(0u, texture_id
);
173 glBindTexture(GL_TEXTURE_2D
, texture_id
);
174 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
175 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
176 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
177 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
179 // Create the gpu memory buffer.
180 scoped_ptr
<gfx::GpuMemoryBuffer
> buffer(gl_
.CreateGpuMemoryBuffer(
181 gfx::Size(kImageWidth
, kImageHeight
), GetParam()));
183 // Map buffer for writing.
185 bool rv
= buffer
->Map(&data
);
188 uint8
* mapped_buffer
= static_cast<uint8
*>(data
);
189 ASSERT_TRUE(mapped_buffer
!= NULL
);
191 // Assign a value to each pixel.
193 buffer
->GetStride(&stride
);
194 ASSERT_NE(stride
, 0);
195 std::vector
<uint8
> pixel
= GetTexturePixel(GetParam());
196 for (int y
= 0; y
< kImageHeight
; ++y
) {
197 for (int x
= 0; x
< kImageWidth
; ++x
) {
198 std::copy(pixel
.begin(), pixel
.end(),
199 mapped_buffer
+ y
* stride
+ x
* pixel
.size());
206 // Create the image. This should add the image ID to the ImageManager.
208 glCreateImageCHROMIUM(buffer
->AsClientBuffer(), kImageWidth
, kImageHeight
,
209 InternalFormat(GetParam()));
210 ASSERT_NE(0u, image_id
);
211 ASSERT_TRUE(gl_
.decoder()->GetImageManager()->LookupImage(image_id
) != NULL
);
214 glBindTexImage2DCHROMIUM(GL_TEXTURE_2D
, image_id
);
216 // Build program, buffers and draw the texture.
217 GLuint vertex_shader
=
218 GLTestHelper::LoadShader(GL_VERTEX_SHADER
, kVertexShader
);
219 GLuint fragment_shader
=
220 GLTestHelper::LoadShader(GL_FRAGMENT_SHADER
, kFragmentShader
);
221 GLuint program
= GLTestHelper::SetupProgram(vertex_shader
, fragment_shader
);
222 ASSERT_NE(0u, program
);
223 glUseProgram(program
);
225 GLint sampler_location
= glGetUniformLocation(program
, "a_texture");
226 ASSERT_NE(-1, sampler_location
);
227 glUniform1i(sampler_location
, 0);
230 GLTestHelper::SetupUnitQuad(glGetAttribLocation(program
, "a_position"));
232 glViewport(0, 0, kImageWidth
, kImageHeight
);
233 glDrawArrays(GL_TRIANGLES
, 0, 6);
234 ASSERT_TRUE(glGetError() == GL_NO_ERROR
);
236 // Check if pixels match the values that were assigned to the mapped buffer.
237 GLTestHelper::CheckPixels(0, 0, kImageWidth
, kImageHeight
, 0,
238 &GetFramebufferPixel(GetParam()).front());
239 EXPECT_TRUE(GL_NO_ERROR
== glGetError());
241 // Release the image.
242 glReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D
, image_id
);
245 glDeleteProgram(program
);
246 glDeleteShader(vertex_shader
);
247 glDeleteShader(fragment_shader
);
248 glDeleteBuffers(1, &vbo
);
249 glDestroyImageCHROMIUM(image_id
);
250 glDeleteTextures(1, &texture_id
);
253 INSTANTIATE_TEST_CASE_P(GpuMemoryBufferTests
,
255 ::testing::Values(gfx::GpuMemoryBuffer::R_8
,
256 gfx::GpuMemoryBuffer::RGBA_8888
,
257 gfx::GpuMemoryBuffer::BGRA_8888
));