OLD | NEW |
| (Empty) |
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, ¶meter); | |
233 EXPECT_EQ(GL_REPEAT, parameter); | |
234 parameter = 0; | |
235 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ¶meter); | |
236 EXPECT_EQ(GL_LINEAR, parameter); | |
237 parameter = 0; | |
238 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ¶meter); | |
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 | |
OLD | NEW |