Windows should animate when they are about to get docked at screen edges.
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_texture_mailbox_unittests.cc
blobd960efc7151bae9247171d191b114ca817301df3
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 <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);
46 glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
48 glDeleteFramebuffers(1, &fbo);
50 return texel;
54 class GLTextureMailboxTest : public testing::Test {
55 protected:
56 virtual void SetUp() {
57 gl1_.Initialize(GLManager::Options());
58 GLManager::Options options;
59 options.share_mailbox_manager = &gl1_;
60 gl2_.Initialize(options);
63 virtual void TearDown() {
64 gl1_.Destroy();
65 gl2_.Destroy();
68 GLManager gl1_;
69 GLManager gl2_;
72 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTexture) {
73 gl1_.MakeCurrent();
75 GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
76 glGenMailboxCHROMIUM(mailbox1);
78 GLbyte mailbox2[GL_MAILBOX_SIZE_CHROMIUM];
79 glGenMailboxCHROMIUM(mailbox2);
81 GLuint tex1;
82 glGenTextures(1, &tex1);
84 glBindTexture(GL_TEXTURE_2D, tex1);
85 uint32 source_pixel = 0xFF0000FF;
86 glTexImage2D(GL_TEXTURE_2D,
88 GL_RGBA,
89 1, 1,
91 GL_RGBA,
92 GL_UNSIGNED_BYTE,
93 &source_pixel);
95 glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
96 glFlush();
98 gl2_.MakeCurrent();
100 GLuint tex2;
101 glGenTextures(1, &tex2);
103 glBindTexture(GL_TEXTURE_2D, tex2);
104 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
105 EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
106 glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
107 glFlush();
109 gl1_.MakeCurrent();
111 glBindTexture(GL_TEXTURE_2D, tex1);
112 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
113 EXPECT_EQ(source_pixel, ReadTexel(tex1, 0, 0));
116 TEST_F(GLTextureMailboxTest, ProduceTextureValidatesKey) {
117 GLuint tex;
118 glGenTextures(1, &tex);
120 glBindTexture(GL_TEXTURE_2D, tex);
121 uint32 source_pixel = 0xFF0000FF;
122 glTexImage2D(GL_TEXTURE_2D,
124 GL_RGBA,
125 1, 1,
127 GL_RGBA,
128 GL_UNSIGNED_BYTE,
129 &source_pixel);
131 GLbyte invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM];
132 glGenMailboxCHROMIUM(invalid_mailbox);
133 ++invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM - 1];
135 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
136 glProduceTextureCHROMIUM(GL_TEXTURE_2D, invalid_mailbox);
137 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
139 // Ensure level 0 is still intact after glProduceTextureCHROMIUM fails.
140 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
141 EXPECT_EQ(source_pixel, ReadTexel(tex, 0, 0));
142 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
145 TEST_F(GLTextureMailboxTest, ConsumeTextureValidatesKey) {
146 GLuint tex;
147 glGenTextures(1, &tex);
149 glBindTexture(GL_TEXTURE_2D, tex);
150 uint32 source_pixel = 0xFF0000FF;
151 glTexImage2D(GL_TEXTURE_2D,
153 GL_RGBA,
154 1, 1,
156 GL_RGBA,
157 GL_UNSIGNED_BYTE,
158 &source_pixel);
160 GLbyte invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM];
161 glGenMailboxCHROMIUM(invalid_mailbox);
162 ++invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM - 1];
164 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
165 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, invalid_mailbox);
166 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
168 // Ensure level 0 is still intact after glConsumeTextureCHROMIUM fails.
169 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
170 EXPECT_EQ(source_pixel, ReadTexel(tex, 0, 0));
171 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
174 TEST_F(GLTextureMailboxTest, SharedTextures) {
175 gl1_.MakeCurrent();
176 GLuint tex1;
177 glGenTextures(1, &tex1);
179 glBindTexture(GL_TEXTURE_2D, tex1);
180 uint32 source_pixel = 0xFF0000FF;
181 glTexImage2D(GL_TEXTURE_2D,
183 GL_RGBA,
184 1, 1,
186 GL_RGBA,
187 GL_UNSIGNED_BYTE,
188 &source_pixel);
189 GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
190 glGenMailboxCHROMIUM(mailbox);
192 glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
193 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
194 glFlush();
196 gl2_.MakeCurrent();
197 GLuint tex2;
198 glGenTextures(1, &tex2);
200 glBindTexture(GL_TEXTURE_2D, tex2);
201 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
202 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
204 // Change texture in context 2.
205 source_pixel = 0xFF00FF00;
206 glTexSubImage2D(GL_TEXTURE_2D,
208 0, 0,
209 1, 1,
210 GL_RGBA,
211 GL_UNSIGNED_BYTE,
212 &source_pixel);
213 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
214 glFlush();
216 // Check it in context 1.
217 gl1_.MakeCurrent();
218 EXPECT_EQ(source_pixel, ReadTexel(tex1, 0, 0));
219 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
221 // Change parameters (note: ReadTexel will reset those).
222 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
225 GL_LINEAR_MIPMAP_NEAREST);
226 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
227 glFlush();
229 // Check in context 2.
230 gl2_.MakeCurrent();
231 GLint parameter = 0;
232 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &parameter);
233 EXPECT_EQ(GL_REPEAT, parameter);
234 parameter = 0;
235 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &parameter);
236 EXPECT_EQ(GL_LINEAR, parameter);
237 parameter = 0;
238 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &parameter);
239 EXPECT_EQ(GL_LINEAR_MIPMAP_NEAREST, parameter);
241 // Delete texture in context 1.
242 gl1_.MakeCurrent();
243 glDeleteTextures(1, &tex1);
244 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
246 // Check texture still exists in context 2.
247 gl2_.MakeCurrent();
248 EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
249 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
251 // The mailbox should still exist too.
252 GLuint tex3;
253 glGenTextures(1, &tex3);
254 glBindTexture(GL_TEXTURE_2D, tex3);
255 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
256 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
258 // Delete both textures.
259 glDeleteTextures(1, &tex2);
260 glDeleteTextures(1, &tex3);
261 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
263 // Mailbox should be gone now.
264 glGenTextures(1, &tex2);
265 glBindTexture(GL_TEXTURE_2D, tex2);
266 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
267 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
268 glDeleteTextures(1, &tex2);
269 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
272 TEST_F(GLTextureMailboxTest, ProduceFrontBuffer) {
273 gl1_.MakeCurrent();
274 Mailbox mailbox;
275 glGenMailboxCHROMIUM(mailbox.name);
277 gl2_.MakeCurrent();
278 gl2_.decoder()->ProduceFrontBuffer(mailbox);
280 gl1_.MakeCurrent();
281 GLuint tex1;
282 glGenTextures(1, &tex1);
283 glBindTexture(GL_TEXTURE_2D, tex1);
284 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
285 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
287 gl2_.MakeCurrent();
288 glResizeCHROMIUM(10, 10, 1);
289 glClearColor(1, 0, 0, 1);
290 glClear(GL_COLOR_BUFFER_BIT);
291 ::gles2::GetGLContext()->SwapBuffers();
293 gl1_.MakeCurrent();
294 EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 0, 0));
295 EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 9, 9));
296 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
298 gl2_.MakeCurrent();
299 glClearColor(0, 1, 0, 1);
300 glClear(GL_COLOR_BUFFER_BIT);
301 glFlush();
303 gl1_.MakeCurrent();
304 EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 0, 0));
306 gl2_.MakeCurrent();
307 ::gles2::GetGLContext()->SwapBuffers();
309 gl1_.MakeCurrent();
310 EXPECT_EQ(0xFF00FF00u, ReadTexel(tex1, 0, 0));
312 gl2_.MakeCurrent();
313 gl2_.Destroy();
315 gl1_.MakeCurrent();
316 EXPECT_EQ(0xFF00FF00u, ReadTexel(tex1, 0, 0));
317 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
318 glDeleteTextures(1, &tex1);
321 TEST_F(GLTextureMailboxTest, ProduceFrontBufferMultipleContexts) {
322 gl1_.MakeCurrent();
323 Mailbox mailbox[2];
324 glGenMailboxCHROMIUM(mailbox[0].name);
325 glGenMailboxCHROMIUM(mailbox[1].name);
326 GLuint tex[2];
327 glGenTextures(2, tex);
329 GLManager::Options options;
330 options.share_mailbox_manager = &gl1_;
331 GLManager other_gl[2];
332 for (size_t i = 0; i < 2; ++i) {
333 other_gl[i].Initialize(options);
334 other_gl[i].MakeCurrent();
335 other_gl[i].decoder()->ProduceFrontBuffer(mailbox[i]);
336 // Make sure both "other gl" are in the same share group.
337 if (!options.share_group_manager)
338 options.share_group_manager = other_gl+i;
342 gl1_.MakeCurrent();
343 for (size_t i = 0; i < 2; ++i) {
344 glBindTexture(GL_TEXTURE_2D, tex[i]);
345 glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox[i].name);
346 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
349 for (size_t i = 0; i < 2; ++i) {
350 other_gl[i].MakeCurrent();
351 glResizeCHROMIUM(10, 10, 1);
352 glClearColor(1-i%2, i%2, 0, 1);
353 glClear(GL_COLOR_BUFFER_BIT);
354 ::gles2::GetGLContext()->SwapBuffers();
357 gl1_.MakeCurrent();
358 EXPECT_EQ(0xFF0000FFu, ReadTexel(tex[0], 0, 0));
359 EXPECT_EQ(0xFF00FF00u, ReadTexel(tex[1], 9, 9));
361 for (size_t i = 0; i < 2; ++i) {
362 other_gl[i].MakeCurrent();
363 other_gl[i].Destroy();
366 gl1_.MakeCurrent();
367 glDeleteTextures(2, tex);
370 } // namespace gpu