1 // Copyright 2013 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 "gpu/command_buffer/service/feature_info.h"
6 #include "gpu/command_buffer/service/gpu_service_test.h"
7 #include "gpu/command_buffer/service/mailbox_manager_impl.h"
8 #include "gpu/command_buffer/service/mailbox_manager_sync.h"
9 #include "gpu/command_buffer/service/texture_manager.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/gl/gl_context_stub.h"
12 #include "ui/gl/gl_mock.h"
13 #include "ui/gl/gl_surface_stub.h"
18 using namespace ::testing
;
20 class MailboxManagerTest
: public GpuServiceTest
{
22 MailboxManagerTest() {}
23 ~MailboxManagerTest() override
{}
26 void SetUp() override
{
27 GpuServiceTest::SetUp();
28 feature_info_
= new FeatureInfo
;
29 manager_
= new MailboxManagerImpl
;
30 DCHECK(!manager_
->UsesSync());
33 virtual void SetUpWithSynchronizer() {
34 GpuServiceTest::SetUp();
35 feature_info_
= new FeatureInfo
;
36 manager_
= new MailboxManagerSync();
37 DCHECK(manager_
->UsesSync());
40 void TearDown() override
{ GpuServiceTest::TearDown(); }
42 Texture
* CreateTexture() {
43 return new Texture(1);
46 void SetTarget(Texture
* texture
, GLenum target
, GLuint max_level
) {
47 texture
->SetTarget(NULL
, target
, max_level
);
50 void SetLevelInfo(Texture
* texture
,
53 GLenum internal_format
,
60 const gfx::Rect
& cleared_rect
) {
61 texture
->SetLevelInfo(NULL
, target
, level
, internal_format
, width
, height
,
62 depth
, border
, format
, type
, cleared_rect
);
65 void SetLevelCleared(Texture
* texture
,
69 texture
->SetLevelCleared(target
, level
, cleared
);
72 GLenum
SetParameter(Texture
* texture
, GLenum pname
, GLint param
) {
73 return texture
->SetParameteri(feature_info_
.get(), pname
, param
);
76 void DestroyTexture(Texture
* texture
) {
80 scoped_refptr
<MailboxManager
> manager_
;
83 scoped_refptr
<FeatureInfo
> feature_info_
;
85 DISALLOW_COPY_AND_ASSIGN(MailboxManagerTest
);
88 // Tests basic produce/consume behavior.
89 TEST_F(MailboxManagerTest
, Basic
) {
90 Texture
* texture
= CreateTexture();
92 Mailbox name
= Mailbox::Generate();
93 manager_
->ProduceTexture(name
, texture
);
94 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
96 // We can consume multiple times.
97 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
99 // Destroy should cleanup the mailbox.
100 DestroyTexture(texture
);
101 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
104 // Tests behavior with multiple produce on the same texture.
105 TEST_F(MailboxManagerTest
, ProduceMultipleMailbox
) {
106 Texture
* texture
= CreateTexture();
108 Mailbox name1
= Mailbox::Generate();
110 manager_
->ProduceTexture(name1
, texture
);
111 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name1
));
113 // Can produce a second time with the same mailbox.
114 manager_
->ProduceTexture(name1
, texture
);
115 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name1
));
117 // Can produce again, with a different mailbox.
118 Mailbox name2
= Mailbox::Generate();
119 manager_
->ProduceTexture(name2
, texture
);
121 // Still available under all mailboxes.
122 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name1
));
123 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name2
));
125 // Destroy should cleanup all mailboxes.
126 DestroyTexture(texture
);
127 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name1
));
128 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name2
));
131 // Tests behavior with multiple produce on the same mailbox with different
133 TEST_F(MailboxManagerTest
, ProduceMultipleTexture
) {
134 Texture
* texture1
= CreateTexture();
135 Texture
* texture2
= CreateTexture();
137 Mailbox name
= Mailbox::Generate();
139 manager_
->ProduceTexture(name
, texture1
);
140 EXPECT_EQ(texture1
, manager_
->ConsumeTexture(name
));
142 // Can produce a second time with the same mailbox, but different texture.
143 manager_
->ProduceTexture(name
, texture2
);
144 EXPECT_EQ(texture2
, manager_
->ConsumeTexture(name
));
146 // Destroying the texture that's under no mailbox shouldn't have an effect.
147 DestroyTexture(texture1
);
148 EXPECT_EQ(texture2
, manager_
->ConsumeTexture(name
));
150 // Destroying the texture that's bound should clean up.
151 DestroyTexture(texture2
);
152 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
155 TEST_F(MailboxManagerTest
, ProduceMultipleTextureMailbox
) {
156 Texture
* texture1
= CreateTexture();
157 Texture
* texture2
= CreateTexture();
158 Mailbox name1
= Mailbox::Generate();
159 Mailbox name2
= Mailbox::Generate();
161 // Put texture1 on name1 and name2.
162 manager_
->ProduceTexture(name1
, texture1
);
163 manager_
->ProduceTexture(name2
, texture1
);
164 EXPECT_EQ(texture1
, manager_
->ConsumeTexture(name1
));
165 EXPECT_EQ(texture1
, manager_
->ConsumeTexture(name2
));
167 // Put texture2 on name2.
168 manager_
->ProduceTexture(name2
, texture2
);
169 EXPECT_EQ(texture1
, manager_
->ConsumeTexture(name1
));
170 EXPECT_EQ(texture2
, manager_
->ConsumeTexture(name2
));
172 // Destroy texture1, shouldn't affect name2.
173 DestroyTexture(texture1
);
174 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name1
));
175 EXPECT_EQ(texture2
, manager_
->ConsumeTexture(name2
));
177 DestroyTexture(texture2
);
178 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name2
));
181 const GLsizei kMaxTextureWidth
= 64;
182 const GLsizei kMaxTextureHeight
= 64;
183 const GLsizei kMaxTextureDepth
= 1;
185 class MailboxManagerSyncTest
: public MailboxManagerTest
{
187 MailboxManagerSyncTest() {}
188 ~MailboxManagerSyncTest() override
{}
191 void SetUp() override
{
192 MailboxManagerTest::SetUpWithSynchronizer();
193 manager2_
= new MailboxManagerSync();
194 context_
= new gfx::GLContextStub();
195 surface_
= new gfx::GLSurfaceStub();
196 context_
->MakeCurrent(surface_
.get());
199 Texture
* DefineTexture() {
200 Texture
* texture
= CreateTexture();
201 const GLsizei levels_needed
= TextureManager::ComputeMipMapCount(
202 GL_TEXTURE_2D
, kMaxTextureWidth
, kMaxTextureHeight
, kMaxTextureDepth
);
203 SetTarget(texture
, GL_TEXTURE_2D
, levels_needed
);
204 SetLevelInfo(texture
, GL_TEXTURE_2D
, 0, GL_RGBA
, 1, 1, 1, 0, GL_RGBA
,
205 GL_UNSIGNED_BYTE
, gfx::Rect(1, 1));
206 SetParameter(texture
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
207 SetParameter(texture
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
211 void SetupUpdateTexParamExpectations(GLuint texture_id
,
217 const GLuint kCurrentTexture
= 0;
218 EXPECT_CALL(*gl_
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
219 .WillOnce(SetArgPointee
<1>(kCurrentTexture
))
220 .RetiresOnSaturation();
221 EXPECT_CALL(*gl_
, BindTexture(GL_TEXTURE_2D
, texture_id
))
223 .RetiresOnSaturation();
225 TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, min
))
227 .RetiresOnSaturation();
229 TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, mag
))
231 .RetiresOnSaturation();
232 EXPECT_CALL(*gl_
, TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, wrap_s
))
234 .RetiresOnSaturation();
235 EXPECT_CALL(*gl_
, TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, wrap_t
))
237 .RetiresOnSaturation();
238 EXPECT_CALL(*gl_
, BindTexture(GL_TEXTURE_2D
, kCurrentTexture
))
240 .RetiresOnSaturation();
243 void TearDown() override
{
244 context_
->ReleaseCurrent(NULL
);
245 MailboxManagerTest::TearDown();
248 scoped_refptr
<MailboxManager
> manager2_
;
249 scoped_refptr
<gfx::GLContext
> context_
;
250 scoped_refptr
<gfx::GLSurface
> surface_
;
253 DISALLOW_COPY_AND_ASSIGN(MailboxManagerSyncTest
);
256 TEST_F(MailboxManagerSyncTest
, ProduceDestroy
) {
257 Texture
* texture
= DefineTexture();
258 Mailbox name
= Mailbox::Generate();
261 manager_
->ProduceTexture(name
, texture
);
262 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
264 DestroyTexture(texture
);
265 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
266 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
269 TEST_F(MailboxManagerSyncTest
, ProduceSyncDestroy
) {
272 Texture
* texture
= DefineTexture();
273 Mailbox name
= Mailbox::Generate();
275 manager_
->ProduceTexture(name
, texture
);
276 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
279 manager_
->PushTextureUpdates(0);
280 manager2_
->PullTextureUpdates(0);
282 DestroyTexture(texture
);
283 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
284 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
287 TEST_F(MailboxManagerSyncTest
, ProduceSyncClobberDestroy
) {
290 Texture
* texture
= DefineTexture();
291 Mailbox name
= Mailbox::Generate();
293 manager_
->ProduceTexture(name
, texture
);
294 manager_
->PushTextureUpdates(0);
297 Texture
* old_texture
= texture
;
298 texture
= DefineTexture();
299 manager_
->ProduceTexture(name
, texture
);
301 DestroyTexture(old_texture
);
302 DestroyTexture(texture
);
303 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
304 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
307 // Duplicates a texture into a second manager instance, and then
308 // makes sure a redefinition becomes visible there too.
309 TEST_F(MailboxManagerSyncTest
, ProduceConsumeResize
) {
310 const GLuint kNewTextureId
= 1234;
313 Texture
* texture
= DefineTexture();
314 Mailbox name
= Mailbox::Generate();
316 manager_
->ProduceTexture(name
, texture
);
317 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
320 manager_
->PushTextureUpdates(0);
321 manager2_
->PullTextureUpdates(0);
323 EXPECT_CALL(*gl_
, GenTextures(1, _
))
324 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
325 SetupUpdateTexParamExpectations(
326 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
327 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
328 EXPECT_FALSE(new_texture
== NULL
);
329 EXPECT_NE(texture
, new_texture
);
330 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
332 // Resize original texture
333 SetLevelInfo(texture
, GL_TEXTURE_2D
, 0, GL_RGBA
, 16, 32, 1, 0, GL_RGBA
,
334 GL_UNSIGNED_BYTE
, gfx::Rect(16, 32));
335 // Should have been orphaned
336 EXPECT_TRUE(texture
->GetLevelImage(GL_TEXTURE_2D
, 0) == NULL
);
339 manager_
->PushTextureUpdates(0);
340 SetupUpdateTexParamExpectations(
341 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
342 manager2_
->PullTextureUpdates(0);
343 GLsizei width
, height
;
344 new_texture
->GetLevelSize(GL_TEXTURE_2D
, 0, &width
, &height
, nullptr);
345 EXPECT_EQ(16, width
);
346 EXPECT_EQ(32, height
);
348 // Should have gotten a new attachment
349 EXPECT_TRUE(texture
->GetLevelImage(GL_TEXTURE_2D
, 0) != NULL
);
350 // Resize original texture again....
351 SetLevelInfo(texture
, GL_TEXTURE_2D
, 0, GL_RGBA
, 64, 64, 1, 0, GL_RGBA
,
352 GL_UNSIGNED_BYTE
, gfx::Rect(64, 64));
353 // ...and immediately delete the texture which should save the changes.
354 SetupUpdateTexParamExpectations(
355 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
356 DestroyTexture(texture
);
358 // Should be still around since there is a ref from manager2
359 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name
));
361 // The last change to the texture should be visible without a sync point (i.e.
363 manager2_
->PullTextureUpdates(0);
364 new_texture
->GetLevelSize(GL_TEXTURE_2D
, 0, &width
, &height
, nullptr);
365 EXPECT_EQ(64, width
);
366 EXPECT_EQ(64, height
);
368 DestroyTexture(new_texture
);
369 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
370 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
373 // Makes sure changes are correctly published even when updates are
374 // pushed in both directions, i.e. makes sure we don't clobber a shared
375 // texture definition with an older version.
376 TEST_F(MailboxManagerSyncTest
, ProduceConsumeBidirectional
) {
377 const GLuint kNewTextureId1
= 1234;
378 const GLuint kNewTextureId2
= 4321;
380 Texture
* texture1
= DefineTexture();
381 Mailbox name1
= Mailbox::Generate();
382 Texture
* texture2
= DefineTexture();
383 Mailbox name2
= Mailbox::Generate();
384 Texture
* new_texture1
= NULL
;
385 Texture
* new_texture2
= NULL
;
387 manager_
->ProduceTexture(name1
, texture1
);
388 manager2_
->ProduceTexture(name2
, texture2
);
391 manager_
->PushTextureUpdates(0);
392 manager2_
->PushTextureUpdates(0);
394 // Create textures in the other manager instances for texture1 and texture2,
395 // respectively to create a real sharing scenario. Otherwise, there would
396 // never be conflicting updates/pushes.
399 EXPECT_CALL(*gl_
, GenTextures(1, _
))
400 .WillOnce(SetArgPointee
<1>(kNewTextureId1
));
401 SetupUpdateTexParamExpectations(
402 kNewTextureId1
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
403 new_texture1
= manager2_
->ConsumeTexture(name1
);
404 EXPECT_CALL(*gl_
, GenTextures(1, _
))
405 .WillOnce(SetArgPointee
<1>(kNewTextureId2
));
406 SetupUpdateTexParamExpectations(
407 kNewTextureId2
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
408 new_texture2
= manager_
->ConsumeTexture(name2
);
410 EXPECT_EQ(kNewTextureId1
, new_texture1
->service_id());
411 EXPECT_EQ(kNewTextureId2
, new_texture2
->service_id());
413 // Make a change to texture1
414 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), texture1
->min_filter());
415 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
416 SetParameter(texture1
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
418 // Make sure this does not clobber it with the previous version we pushed.
419 manager_
->PullTextureUpdates(0);
421 // Make a change to texture2
422 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), texture2
->mag_filter());
423 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
424 SetParameter(texture2
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
426 Mock::VerifyAndClearExpectations(gl_
.get());
428 // Synchronize in both directions
429 manager_
->PushTextureUpdates(0);
430 manager2_
->PushTextureUpdates(0);
431 // manager1 should see the change to texture2 mag_filter being applied.
432 SetupUpdateTexParamExpectations(
433 new_texture2
->service_id(), GL_LINEAR
, GL_NEAREST
, GL_REPEAT
, GL_REPEAT
);
434 manager_
->PullTextureUpdates(0);
435 // manager2 should see the change to texture1 min_filter being applied.
436 SetupUpdateTexParamExpectations(
437 new_texture1
->service_id(), GL_NEAREST
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
438 manager2_
->PullTextureUpdates(0);
440 DestroyTexture(texture1
);
441 DestroyTexture(texture2
);
442 DestroyTexture(new_texture1
);
443 DestroyTexture(new_texture2
);
446 // If a texture is shared with another manager instance, but the mailbox
447 // is then clobbered with a different texture in the source context, this should
448 // disconnect the earlier texture from updates.
449 TEST_F(MailboxManagerSyncTest
, ProduceAndClobber
) {
450 const GLuint kNewTextureId
= 1234;
453 Texture
* texture
= DefineTexture();
454 Mailbox name
= Mailbox::Generate();
456 manager_
->ProduceTexture(name
, texture
);
457 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
460 manager_
->PushTextureUpdates(0);
461 manager2_
->PullTextureUpdates(0);
463 EXPECT_CALL(*gl_
, GenTextures(1, _
))
464 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
465 SetupUpdateTexParamExpectations(
466 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
467 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
468 EXPECT_FALSE(new_texture
== NULL
);
469 EXPECT_NE(texture
, new_texture
);
470 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
472 Texture
* old_texture
= texture
;
473 texture
= DefineTexture();
474 manager_
->ProduceTexture(name
, texture
);
476 // Make a change to the new texture
477 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), texture
->min_filter());
478 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
479 SetParameter(texture
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
481 // Synchronize in both directions - no changes, since it's not shared
482 manager_
->PushTextureUpdates(0);
483 manager2_
->PullTextureUpdates(0);
484 EXPECT_EQ(static_cast<GLuint
>(GL_LINEAR
), new_texture
->min_filter());
486 // Make a change to the previously shared texture
487 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), old_texture
->mag_filter());
488 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
489 SetParameter(old_texture
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
491 // Synchronize and expect update
492 manager_
->PushTextureUpdates(0);
493 SetupUpdateTexParamExpectations(
494 new_texture
->service_id(), GL_LINEAR
, GL_NEAREST
, GL_REPEAT
, GL_REPEAT
);
495 manager2_
->PullTextureUpdates(0);
497 EXPECT_CALL(*gl_
, GenTextures(1, _
))
498 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
499 SetupUpdateTexParamExpectations(
500 kNewTextureId
, GL_NEAREST
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
501 Texture
* tmp_texture
= manager2_
->ConsumeTexture(name
);
502 EXPECT_NE(new_texture
, tmp_texture
);
503 DestroyTexture(tmp_texture
);
505 DestroyTexture(old_texture
);
506 DestroyTexture(texture
);
507 DestroyTexture(new_texture
);
509 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
510 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
513 TEST_F(MailboxManagerSyncTest
, ClearedStateSynced
) {
514 const GLuint kNewTextureId
= 1234;
516 Texture
* texture
= DefineTexture();
517 EXPECT_TRUE(texture
->SafeToRenderFrom());
519 Mailbox name
= Mailbox::Generate();
521 manager_
->ProduceTexture(name
, texture
);
522 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
525 manager_
->PushTextureUpdates(0);
526 manager2_
->PullTextureUpdates(0);
528 EXPECT_CALL(*gl_
, GenTextures(1, _
))
529 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
530 SetupUpdateTexParamExpectations(
531 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
532 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
533 EXPECT_FALSE(new_texture
== NULL
);
534 EXPECT_NE(texture
, new_texture
);
535 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
536 EXPECT_TRUE(texture
->SafeToRenderFrom());
538 // Change cleared to false.
539 SetLevelCleared(texture
, texture
->target(), 0, false);
540 EXPECT_FALSE(texture
->SafeToRenderFrom());
543 manager_
->PushTextureUpdates(0);
544 SetupUpdateTexParamExpectations(
545 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
546 manager2_
->PullTextureUpdates(0);
548 // Cleared state should be synced.
549 EXPECT_FALSE(new_texture
->SafeToRenderFrom());
551 DestroyTexture(texture
);
552 DestroyTexture(new_texture
);
554 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
555 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
558 TEST_F(MailboxManagerSyncTest
, SyncIncompleteTexture
) {
559 const GLuint kNewTextureId
= 1234;
561 // Create but not define texture.
562 Texture
* texture
= CreateTexture();
563 SetTarget(texture
, GL_TEXTURE_2D
, 1);
564 EXPECT_FALSE(texture
->IsDefined());
566 Mailbox name
= Mailbox::Generate();
567 manager_
->ProduceTexture(name
, texture
);
568 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
571 manager_
->PushTextureUpdates(0);
572 manager2_
->PullTextureUpdates(0);
574 // Should sync to new texture which is not defined.
575 EXPECT_CALL(*gl_
, GenTextures(1, _
))
576 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
577 SetupUpdateTexParamExpectations(kNewTextureId
, texture
->min_filter(),
578 texture
->mag_filter(), texture
->wrap_s(),
580 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
581 ASSERT_TRUE(new_texture
);
582 EXPECT_NE(texture
, new_texture
);
583 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
584 EXPECT_FALSE(new_texture
->IsDefined());
586 // Change cleared to false.
587 SetLevelInfo(texture
, GL_TEXTURE_2D
, 0, GL_RGBA
, 1, 1, 1, 0, GL_RGBA
,
588 GL_UNSIGNED_BYTE
, gfx::Rect(1, 1));
589 SetParameter(texture
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
590 SetParameter(texture
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
591 EXPECT_TRUE(texture
->IsDefined());
594 manager_
->PushTextureUpdates(0);
595 SetupUpdateTexParamExpectations(
596 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
597 manager2_
->PullTextureUpdates(0);
599 // Cleared state should be synced.
600 EXPECT_TRUE(new_texture
->IsDefined());
602 DestroyTexture(texture
);
603 DestroyTexture(new_texture
);
605 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
606 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
609 // Putting the same texture into multiple mailboxes should result in sharing
610 // only a single texture also within a synchronized manager instance.
611 TEST_F(MailboxManagerSyncTest
, SharedThroughMultipleMailboxes
) {
612 const GLuint kNewTextureId
= 1234;
615 Texture
* texture
= DefineTexture();
616 Mailbox name1
= Mailbox::Generate();
617 Mailbox name2
= Mailbox::Generate();
619 manager_
->ProduceTexture(name1
, texture
);
622 manager_
->PushTextureUpdates(0);
623 EXPECT_CALL(*gl_
, GenTextures(1, _
))
624 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
625 manager2_
->PullTextureUpdates(0);
626 SetupUpdateTexParamExpectations(
627 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
628 Texture
* new_texture
= manager2_
->ConsumeTexture(name1
);
629 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
631 manager_
->ProduceTexture(name2
, texture
);
634 manager_
->PushTextureUpdates(0);
635 manager2_
->PullTextureUpdates(0);
637 // name2 should return the same texture
638 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name2
));
640 // Even after destroying the source texture, the original mailbox should
642 DestroyTexture(texture
);
643 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name1
));
644 DestroyTexture(new_texture
);
647 // A: produce texture1 into M, B: consume into new_texture
648 // B: produce texture2 into M, A: produce texture1 into M
649 // B: consume M should return new_texture
650 TEST_F(MailboxManagerSyncTest
, ProduceBothWays
) {
651 const GLuint kNewTextureId
= 1234;
654 Texture
* texture1
= DefineTexture();
655 Texture
* texture2
= DefineTexture();
656 Mailbox name
= Mailbox::Generate();
658 manager_
->ProduceTexture(name
, texture1
);
661 manager_
->PushTextureUpdates(0);
662 EXPECT_CALL(*gl_
, GenTextures(1, _
))
663 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
664 SetupUpdateTexParamExpectations(
665 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
666 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
667 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
670 manager2_
->ProduceTexture(name
, texture2
);
671 manager_
->ProduceTexture(name
, texture1
);
673 // Synchronize manager -> manager2
674 manager_
->PushTextureUpdates(0);
675 manager2_
->PullTextureUpdates(0);
677 // name should return the original texture, and not texture2 or a new one.
678 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name
));
680 DestroyTexture(texture1
);
681 DestroyTexture(texture2
);
682 DestroyTexture(new_texture
);
685 // TODO: Texture::level_infos_[][].size()
687 // TODO: unsupported targets and formats