We started redesigning GpuMemoryBuffer interface to handle multiple buffers [0].
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_texture_mailbox_unittest.cc
blob3ceb5ff65f34b3280963e30bf260f56d46c8bec7
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.
5 #include <GLES2/gl2.h>
6 #include <GLES2/gl2ext.h>
7 #include <GLES2/gl2extchromium.h>
9 #include "gpu/command_buffer/client/gles2_lib.h"
10 #include "gpu/command_buffer/common/mailbox.h"
11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
12 #include "gpu/command_buffer/service/mailbox_manager.h"
13 #include "gpu/command_buffer/tests/gl_manager.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/gl/gl_share_group.h"
18 namespace gpu {
20 namespace {
21 uint32 ReadTexel(GLuint id, GLint x, GLint y) {
22 GLint old_fbo = 0;
23 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo);
25 GLuint fbo;
26 glGenFramebuffers(1, &fbo);
27 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
28 glFramebufferTexture2D(GL_FRAMEBUFFER,
29 GL_COLOR_ATTACHMENT0,
30 GL_TEXTURE_2D,
31 id,
32 0);
33 // Some drivers (NVidia/SGX) require texture settings to be a certain way or
34 // they won't report FRAMEBUFFER_COMPLETE.
35 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
36 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
37 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
38 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
40 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
41 glCheckFramebufferStatus(GL_FRAMEBUFFER));
43 uint32 texel = 0;
44 glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &texel);
45 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
47 glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
49 glDeleteFramebuffers(1, &fbo);
51 return texel;
55 class GLTextureMailboxTest : public testing::Test {
56 protected:
57 void SetUp() override {
58 gl1_.Initialize(GLManager::Options());
59 GLManager::Options options;
60 options.share_mailbox_manager = &gl1_;
61 gl2_.Initialize(options);
64 void TearDown() override {
65 gl1_.Destroy();
66 gl2_.Destroy();
69 GLManager gl1_;
70 GLManager gl2_;
73 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTexture) {
74 gl1_.MakeCurrent();
76 GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
77 glGenMailboxCHROMIUM(mailbox1);
79 GLbyte mailbox2[GL_MAILBOX_SIZE_CHROMIUM];
80 glGenMailboxCHROMIUM(mailbox2);
82 GLuint tex1;
83 glGenTextures(1, &tex1);
85 glBindTexture(GL_TEXTURE_2D, tex1);
86 uint32 source_pixel = 0xFF0000FF;
87 glTexImage2D(GL_TEXTURE_2D,
89 GL_RGBA,
90 1, 1,
92 GL_RGBA,
93 GL_UNSIGNED_BYTE,
94 &source_pixel);
96 glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
97 glFlush();
99 gl2_.MakeCurrent();
101 GLuint tex2;
102 glGenTextures(1, &tex2);
104 glBindTexture(GL_TEXTURE_2D, tex2);
105 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
106 EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
107 glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
108 glFlush();
110 gl1_.MakeCurrent();
112 glBindTexture(GL_TEXTURE_2D, tex1);
113 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
114 EXPECT_EQ(source_pixel, ReadTexel(tex1, 0, 0));
117 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTextureRGB) {
118 gl1_.MakeCurrent();
120 GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
121 glGenMailboxCHROMIUM(mailbox1);
123 GLbyte mailbox2[GL_MAILBOX_SIZE_CHROMIUM];
124 glGenMailboxCHROMIUM(mailbox2);
126 GLuint tex1;
127 glGenTextures(1, &tex1);
129 glBindTexture(GL_TEXTURE_2D, tex1);
130 uint32 source_pixel = 0xFF000000;
131 glTexImage2D(GL_TEXTURE_2D,
133 GL_RGB,
134 1, 1,
136 GL_RGB,
137 GL_UNSIGNED_BYTE,
138 &source_pixel);
140 glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
141 glFlush();
143 gl2_.MakeCurrent();
145 GLuint tex2;
146 glGenTextures(1, &tex2);
148 glBindTexture(GL_TEXTURE_2D, tex2);
149 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
150 EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
151 glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
152 glFlush();
154 gl1_.MakeCurrent();
156 glBindTexture(GL_TEXTURE_2D, tex1);
157 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
158 EXPECT_EQ(source_pixel, ReadTexel(tex1, 0, 0));
161 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTextureDirect) {
162 gl1_.MakeCurrent();
164 GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
165 glGenMailboxCHROMIUM(mailbox1);
167 GLbyte mailbox2[GL_MAILBOX_SIZE_CHROMIUM];
168 glGenMailboxCHROMIUM(mailbox2);
170 GLuint tex1;
171 glGenTextures(1, &tex1);
173 glBindTexture(GL_TEXTURE_2D, tex1);
174 uint32 source_pixel = 0xFF0000FF;
175 glTexImage2D(GL_TEXTURE_2D,
177 GL_RGBA,
178 1, 1,
180 GL_RGBA,
181 GL_UNSIGNED_BYTE,
182 &source_pixel);
184 glProduceTextureDirectCHROMIUM(tex1, GL_TEXTURE_2D, mailbox1);
185 glFlush();
187 gl2_.MakeCurrent();
189 GLuint tex2 = glCreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
190 glBindTexture(GL_TEXTURE_2D, tex2);
191 EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
192 glProduceTextureDirectCHROMIUM(tex2, GL_TEXTURE_2D, mailbox2);
193 glFlush();
195 gl1_.MakeCurrent();
197 GLuint tex3 = glCreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
198 glBindTexture(GL_TEXTURE_2D, tex3);
199 EXPECT_EQ(source_pixel, ReadTexel(tex3, 0, 0));
202 TEST_F(GLTextureMailboxTest, ConsumeTextureValidatesKey) {
203 GLuint tex;
204 glGenTextures(1, &tex);
206 glBindTexture(GL_TEXTURE_2D, tex);
207 uint32 source_pixel = 0xFF0000FF;
208 glTexImage2D(GL_TEXTURE_2D,
210 GL_RGBA,
211 1, 1,
213 GL_RGBA,
214 GL_UNSIGNED_BYTE,
215 &source_pixel);
217 GLbyte invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM];
218 glGenMailboxCHROMIUM(invalid_mailbox);
220 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
221 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, invalid_mailbox);
222 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
224 // Ensure level 0 is still intact after glConsumeTextureCHROMIUM fails.
225 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
226 EXPECT_EQ(source_pixel, ReadTexel(tex, 0, 0));
227 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
230 TEST_F(GLTextureMailboxTest, SharedTextures) {
231 gl1_.MakeCurrent();
232 GLuint tex1;
233 glGenTextures(1, &tex1);
235 glBindTexture(GL_TEXTURE_2D, tex1);
236 uint32 source_pixel = 0xFF0000FF;
237 glTexImage2D(GL_TEXTURE_2D,
239 GL_RGBA,
240 1, 1,
242 GL_RGBA,
243 GL_UNSIGNED_BYTE,
244 &source_pixel);
245 GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
246 glGenMailboxCHROMIUM(mailbox);
248 glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
249 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
250 glFlush();
252 gl2_.MakeCurrent();
253 GLuint tex2;
254 glGenTextures(1, &tex2);
256 glBindTexture(GL_TEXTURE_2D, tex2);
257 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
258 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
260 // Change texture in context 2.
261 source_pixel = 0xFF00FF00;
262 glTexSubImage2D(GL_TEXTURE_2D,
264 0, 0,
265 1, 1,
266 GL_RGBA,
267 GL_UNSIGNED_BYTE,
268 &source_pixel);
269 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
270 glFlush();
272 // Check it in context 1.
273 gl1_.MakeCurrent();
274 EXPECT_EQ(source_pixel, ReadTexel(tex1, 0, 0));
275 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
277 // Change parameters (note: ReadTexel will reset those).
278 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
279 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
280 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
281 GL_LINEAR_MIPMAP_NEAREST);
282 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
283 glFlush();
285 // Check in context 2.
286 gl2_.MakeCurrent();
287 GLint parameter = 0;
288 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &parameter);
289 EXPECT_EQ(GL_REPEAT, parameter);
290 parameter = 0;
291 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &parameter);
292 EXPECT_EQ(GL_LINEAR, parameter);
293 parameter = 0;
294 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &parameter);
295 EXPECT_EQ(GL_LINEAR_MIPMAP_NEAREST, parameter);
297 // Delete texture in context 1.
298 gl1_.MakeCurrent();
299 glDeleteTextures(1, &tex1);
300 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
302 // Check texture still exists in context 2.
303 gl2_.MakeCurrent();
304 EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
305 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
307 // The mailbox should still exist too.
308 GLuint tex3;
309 glGenTextures(1, &tex3);
310 glBindTexture(GL_TEXTURE_2D, tex3);
311 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
312 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
314 // Delete both textures.
315 glDeleteTextures(1, &tex2);
316 glDeleteTextures(1, &tex3);
317 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
319 // Mailbox should be gone now.
320 glGenTextures(1, &tex2);
321 glBindTexture(GL_TEXTURE_2D, tex2);
322 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
323 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
324 glDeleteTextures(1, &tex2);
325 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
328 TEST_F(GLTextureMailboxTest, ProduceFrontBuffer) {
329 gl1_.MakeCurrent();
330 Mailbox mailbox;
331 glGenMailboxCHROMIUM(mailbox.name);
333 gl2_.MakeCurrent();
334 gl2_.decoder()->ProduceFrontBuffer(mailbox);
336 gl1_.MakeCurrent();
337 GLuint tex1;
338 glGenTextures(1, &tex1);
339 glBindTexture(GL_TEXTURE_2D, tex1);
340 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
341 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
343 gl2_.MakeCurrent();
344 glResizeCHROMIUM(10, 10, 1);
345 glClearColor(1, 0, 0, 1);
346 glClear(GL_COLOR_BUFFER_BIT);
347 ::gles2::GetGLContext()->SwapBuffers();
349 gl1_.MakeCurrent();
350 EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 0, 0));
351 EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 9, 9));
352 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
354 gl2_.MakeCurrent();
355 glClearColor(0, 1, 0, 1);
356 glClear(GL_COLOR_BUFFER_BIT);
357 glFlush();
359 gl1_.MakeCurrent();
360 EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 0, 0));
362 gl2_.MakeCurrent();
363 ::gles2::GetGLContext()->SwapBuffers();
365 gl1_.MakeCurrent();
366 EXPECT_EQ(0xFF00FF00u, ReadTexel(tex1, 0, 0));
368 gl2_.MakeCurrent();
369 gl2_.Destroy();
371 gl1_.MakeCurrent();
372 EXPECT_EQ(0xFF00FF00u, ReadTexel(tex1, 0, 0));
373 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
374 glDeleteTextures(1, &tex1);
377 TEST_F(GLTextureMailboxTest, ProduceTextureDirectInvalidTarget) {
378 gl1_.MakeCurrent();
380 GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
381 glGenMailboxCHROMIUM(mailbox1);
383 GLuint tex1;
384 glGenTextures(1, &tex1);
386 glBindTexture(GL_TEXTURE_CUBE_MAP, tex1);
387 uint32 source_pixel = 0xFF0000FF;
388 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X,
390 GL_RGBA,
391 1, 1,
393 GL_RGBA,
394 GL_UNSIGNED_BYTE,
395 &source_pixel);
397 glProduceTextureDirectCHROMIUM(tex1, GL_TEXTURE_2D, mailbox1);
398 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
401 // http://crbug.com/281565
402 #if !defined(OS_ANDROID)
403 TEST_F(GLTextureMailboxTest, ProduceFrontBufferMultipleContexts) {
404 gl1_.MakeCurrent();
405 Mailbox mailbox[2];
406 glGenMailboxCHROMIUM(mailbox[0].name);
407 glGenMailboxCHROMIUM(mailbox[1].name);
408 GLuint tex[2];
409 glGenTextures(2, tex);
411 GLManager::Options options;
412 options.share_mailbox_manager = &gl1_;
413 GLManager other_gl[2];
414 for (size_t i = 0; i < 2; ++i) {
415 other_gl[i].Initialize(options);
416 other_gl[i].MakeCurrent();
417 other_gl[i].decoder()->ProduceFrontBuffer(mailbox[i]);
418 // Make sure both "other gl" are in the same share group.
419 if (!options.share_group_manager)
420 options.share_group_manager = other_gl+i;
424 gl1_.MakeCurrent();
425 for (size_t i = 0; i < 2; ++i) {
426 glBindTexture(GL_TEXTURE_2D, tex[i]);
427 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox[i].name);
428 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
431 for (size_t i = 0; i < 2; ++i) {
432 other_gl[i].MakeCurrent();
433 glResizeCHROMIUM(10, 10, 1);
434 glClearColor(1-i%2, i%2, 0, 1);
435 glClear(GL_COLOR_BUFFER_BIT);
436 ::gles2::GetGLContext()->SwapBuffers();
439 gl1_.MakeCurrent();
440 EXPECT_EQ(0xFF0000FFu, ReadTexel(tex[0], 0, 0));
441 EXPECT_EQ(0xFF00FF00u, ReadTexel(tex[1], 9, 9));
443 for (size_t i = 0; i < 2; ++i) {
444 other_gl[i].MakeCurrent();
445 other_gl[i].Destroy();
448 gl1_.MakeCurrent();
449 glDeleteTextures(2, tex);
451 #endif
453 } // namespace gpu