- add sources.
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / tests / gl_texture_mailbox_unittests.cc
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 #include <GLES2/gl2extchromium.h>
8
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"
17
18 namespace gpu {
19
20 namespace {
21 uint32 ReadTexel(GLuint id, GLint x, GLint y) {
22   GLint old_fbo = 0;
23   glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo);
24
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);
39
40   EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
41             glCheckFramebufferStatus(GL_FRAMEBUFFER));
42
43   uint32 texel = 0;
44   glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &texel);
45
46   glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
47
48   glDeleteFramebuffers(1, &fbo);
49
50   return texel;
51 }
52 }
53
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);
61   }
62
63   virtual void TearDown() {
64     gl1_.Destroy();
65     gl2_.Destroy();
66   }
67
68   GLManager gl1_;
69   GLManager gl2_;
70 };
71
72 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTexture) {
73   gl1_.MakeCurrent();
74
75   GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
76   glGenMailboxCHROMIUM(mailbox1);
77
78   GLbyte mailbox2[GL_MAILBOX_SIZE_CHROMIUM];
79   glGenMailboxCHROMIUM(mailbox2);
80
81   GLuint tex1;
82   glGenTextures(1, &tex1);
83
84   glBindTexture(GL_TEXTURE_2D, tex1);
85   uint32 source_pixel = 0xFF0000FF;
86   glTexImage2D(GL_TEXTURE_2D,
87                0,
88                GL_RGBA,
89                1, 1,
90                0,
91                GL_RGBA,
92                GL_UNSIGNED_BYTE,
93                &source_pixel);
94
95   glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
96   glFlush();
97
98   gl2_.MakeCurrent();
99
100   GLuint tex2;
101   glGenTextures(1, &tex2);
102
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();
108
109   gl1_.MakeCurrent();
110
111   glBindTexture(GL_TEXTURE_2D, tex1);
112   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
113   EXPECT_EQ(source_pixel, ReadTexel(tex1, 0, 0));
114 }
115
116 TEST_F(GLTextureMailboxTest, ProduceTextureValidatesKey) {
117   GLuint tex;
118   glGenTextures(1, &tex);
119
120   glBindTexture(GL_TEXTURE_2D, tex);
121   uint32 source_pixel = 0xFF0000FF;
122   glTexImage2D(GL_TEXTURE_2D,
123                0,
124                GL_RGBA,
125                1, 1,
126                0,
127                GL_RGBA,
128                GL_UNSIGNED_BYTE,
129                &source_pixel);
130
131   GLbyte invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM];
132   glGenMailboxCHROMIUM(invalid_mailbox);
133   ++invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM - 1];
134
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());
138
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());
143 }
144
145 TEST_F(GLTextureMailboxTest, ConsumeTextureValidatesKey) {
146   GLuint tex;
147   glGenTextures(1, &tex);
148
149   glBindTexture(GL_TEXTURE_2D, tex);
150   uint32 source_pixel = 0xFF0000FF;
151   glTexImage2D(GL_TEXTURE_2D,
152                0,
153                GL_RGBA,
154                1, 1,
155                0,
156                GL_RGBA,
157                GL_UNSIGNED_BYTE,
158                &source_pixel);
159
160   GLbyte invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM];
161   glGenMailboxCHROMIUM(invalid_mailbox);
162   ++invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM - 1];
163
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());
167
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());
172 }
173
174 TEST_F(GLTextureMailboxTest, SharedTextures) {
175   gl1_.MakeCurrent();
176   GLuint tex1;
177   glGenTextures(1, &tex1);
178
179   glBindTexture(GL_TEXTURE_2D, tex1);
180   uint32 source_pixel = 0xFF0000FF;
181   glTexImage2D(GL_TEXTURE_2D,
182                0,
183                GL_RGBA,
184                1, 1,
185                0,
186                GL_RGBA,
187                GL_UNSIGNED_BYTE,
188                &source_pixel);
189   GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
190   glGenMailboxCHROMIUM(mailbox);
191
192   glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
193   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
194   glFlush();
195
196   gl2_.MakeCurrent();
197   GLuint tex2;
198   glGenTextures(1, &tex2);
199
200   glBindTexture(GL_TEXTURE_2D, tex2);
201   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
202   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
203
204   // Change texture in context 2.
205   source_pixel = 0xFF00FF00;
206   glTexSubImage2D(GL_TEXTURE_2D,
207                   0,
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();
215
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());
220
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();
228
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);
240
241   // Delete texture in context 1.
242   gl1_.MakeCurrent();
243   glDeleteTextures(1, &tex1);
244   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
245
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());
250
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());
257
258   // Delete both textures.
259   glDeleteTextures(1, &tex2);
260   glDeleteTextures(1, &tex3);
261   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
262
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());
270 }
271
272 TEST_F(GLTextureMailboxTest, ProduceFrontBuffer) {
273   gl1_.MakeCurrent();
274   Mailbox mailbox;
275   glGenMailboxCHROMIUM(mailbox.name);
276
277   gl2_.MakeCurrent();
278   gl2_.decoder()->ProduceFrontBuffer(mailbox);
279
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());
286
287   gl2_.MakeCurrent();
288   glResizeCHROMIUM(10, 10, 1);
289   glClearColor(1, 0, 0, 1);
290   glClear(GL_COLOR_BUFFER_BIT);
291   ::gles2::GetGLContext()->SwapBuffers();
292
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());
297
298   gl2_.MakeCurrent();
299   glClearColor(0, 1, 0, 1);
300   glClear(GL_COLOR_BUFFER_BIT);
301   glFlush();
302
303   gl1_.MakeCurrent();
304   EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 0, 0));
305
306   gl2_.MakeCurrent();
307   ::gles2::GetGLContext()->SwapBuffers();
308
309   gl1_.MakeCurrent();
310   EXPECT_EQ(0xFF00FF00u, ReadTexel(tex1, 0, 0));
311
312   gl2_.MakeCurrent();
313   gl2_.Destroy();
314
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);
319 }
320
321 // http://crbug.com/281565
322 #if !defined(OS_ANDROID)
323 TEST_F(GLTextureMailboxTest, ProduceFrontBufferMultipleContexts) {
324   gl1_.MakeCurrent();
325   Mailbox mailbox[2];
326   glGenMailboxCHROMIUM(mailbox[0].name);
327   glGenMailboxCHROMIUM(mailbox[1].name);
328   GLuint tex[2];
329   glGenTextures(2, tex);
330
331   GLManager::Options options;
332   options.share_mailbox_manager = &gl1_;
333   GLManager other_gl[2];
334   for (size_t i = 0; i < 2; ++i) {
335     other_gl[i].Initialize(options);
336     other_gl[i].MakeCurrent();
337     other_gl[i].decoder()->ProduceFrontBuffer(mailbox[i]);
338     // Make sure both "other gl" are in the same share group.
339     if (!options.share_group_manager)
340       options.share_group_manager = other_gl+i;
341   }
342
343
344   gl1_.MakeCurrent();
345   for (size_t i = 0; i < 2; ++i) {
346     glBindTexture(GL_TEXTURE_2D, tex[i]);
347     glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox[i].name);
348     EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
349   }
350
351   for (size_t i = 0; i < 2; ++i) {
352     other_gl[i].MakeCurrent();
353     glResizeCHROMIUM(10, 10, 1);
354     glClearColor(1-i%2, i%2, 0, 1);
355     glClear(GL_COLOR_BUFFER_BIT);
356     ::gles2::GetGLContext()->SwapBuffers();
357   }
358
359   gl1_.MakeCurrent();
360   EXPECT_EQ(0xFF0000FFu, ReadTexel(tex[0], 0, 0));
361   EXPECT_EQ(0xFF00FF00u, ReadTexel(tex[1], 9, 9));
362
363   for (size_t i = 0; i < 2; ++i) {
364     other_gl[i].MakeCurrent();
365     other_gl[i].Destroy();
366   }
367
368   gl1_.MakeCurrent();
369   glDeleteTextures(2, tex);
370 }
371 #endif
372
373 }  // namespace gpu
374