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
);
54 GLenum internal_format
,
62 texture
->SetLevelInfo(NULL
,
75 void SetLevelCleared(Texture
* texture
,
79 texture
->SetLevelCleared(target
, level
, cleared
);
82 GLenum
SetParameter(Texture
* texture
, GLenum pname
, GLint param
) {
83 return texture
->SetParameteri(feature_info_
.get(), pname
, param
);
86 void DestroyTexture(Texture
* texture
) {
90 scoped_refptr
<MailboxManager
> manager_
;
93 scoped_refptr
<FeatureInfo
> feature_info_
;
95 DISALLOW_COPY_AND_ASSIGN(MailboxManagerTest
);
98 // Tests basic produce/consume behavior.
99 TEST_F(MailboxManagerTest
, Basic
) {
100 Texture
* texture
= CreateTexture();
102 Mailbox name
= Mailbox::Generate();
103 manager_
->ProduceTexture(name
, texture
);
104 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
106 // We can consume multiple times.
107 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
109 // Destroy should cleanup the mailbox.
110 DestroyTexture(texture
);
111 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
114 // Tests behavior with multiple produce on the same texture.
115 TEST_F(MailboxManagerTest
, ProduceMultipleMailbox
) {
116 Texture
* texture
= CreateTexture();
118 Mailbox name1
= Mailbox::Generate();
120 manager_
->ProduceTexture(name1
, texture
);
121 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name1
));
123 // Can produce a second time with the same mailbox.
124 manager_
->ProduceTexture(name1
, texture
);
125 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name1
));
127 // Can produce again, with a different mailbox.
128 Mailbox name2
= Mailbox::Generate();
129 manager_
->ProduceTexture(name2
, texture
);
131 // Still available under all mailboxes.
132 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name1
));
133 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name2
));
135 // Destroy should cleanup all mailboxes.
136 DestroyTexture(texture
);
137 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name1
));
138 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name2
));
141 // Tests behavior with multiple produce on the same mailbox with different
143 TEST_F(MailboxManagerTest
, ProduceMultipleTexture
) {
144 Texture
* texture1
= CreateTexture();
145 Texture
* texture2
= CreateTexture();
147 Mailbox name
= Mailbox::Generate();
149 manager_
->ProduceTexture(name
, texture1
);
150 EXPECT_EQ(texture1
, manager_
->ConsumeTexture(name
));
152 // Can produce a second time with the same mailbox, but different texture.
153 manager_
->ProduceTexture(name
, texture2
);
154 EXPECT_EQ(texture2
, manager_
->ConsumeTexture(name
));
156 // Destroying the texture that's under no mailbox shouldn't have an effect.
157 DestroyTexture(texture1
);
158 EXPECT_EQ(texture2
, manager_
->ConsumeTexture(name
));
160 // Destroying the texture that's bound should clean up.
161 DestroyTexture(texture2
);
162 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
165 TEST_F(MailboxManagerTest
, ProduceMultipleTextureMailbox
) {
166 Texture
* texture1
= CreateTexture();
167 Texture
* texture2
= CreateTexture();
168 Mailbox name1
= Mailbox::Generate();
169 Mailbox name2
= Mailbox::Generate();
171 // Put texture1 on name1 and name2.
172 manager_
->ProduceTexture(name1
, texture1
);
173 manager_
->ProduceTexture(name2
, texture1
);
174 EXPECT_EQ(texture1
, manager_
->ConsumeTexture(name1
));
175 EXPECT_EQ(texture1
, manager_
->ConsumeTexture(name2
));
177 // Put texture2 on name2.
178 manager_
->ProduceTexture(name2
, texture2
);
179 EXPECT_EQ(texture1
, manager_
->ConsumeTexture(name1
));
180 EXPECT_EQ(texture2
, manager_
->ConsumeTexture(name2
));
182 // Destroy texture1, shouldn't affect name2.
183 DestroyTexture(texture1
);
184 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name1
));
185 EXPECT_EQ(texture2
, manager_
->ConsumeTexture(name2
));
187 DestroyTexture(texture2
);
188 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name2
));
191 const GLsizei kMaxTextureWidth
= 64;
192 const GLsizei kMaxTextureHeight
= 64;
193 const GLsizei kMaxTextureDepth
= 1;
195 class MailboxManagerSyncTest
: public MailboxManagerTest
{
197 MailboxManagerSyncTest() {}
198 ~MailboxManagerSyncTest() override
{}
201 void SetUp() override
{
202 MailboxManagerTest::SetUpWithSynchronizer();
203 manager2_
= new MailboxManagerSync();
204 context_
= new gfx::GLContextStub();
205 surface_
= new gfx::GLSurfaceStub();
206 context_
->MakeCurrent(surface_
.get());
209 Texture
* DefineTexture() {
210 Texture
* texture
= CreateTexture();
211 const GLsizei levels_needed
= TextureManager::ComputeMipMapCount(
212 GL_TEXTURE_2D
, kMaxTextureWidth
, kMaxTextureHeight
, kMaxTextureDepth
);
213 SetTarget(texture
, GL_TEXTURE_2D
, levels_needed
);
214 SetLevelInfo(texture
,
225 SetParameter(texture
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
226 SetParameter(texture
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
230 void SetupUpdateTexParamExpectations(GLuint texture_id
,
236 const GLuint kCurrentTexture
= 0;
237 EXPECT_CALL(*gl_
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
238 .WillOnce(SetArgPointee
<1>(kCurrentTexture
))
239 .RetiresOnSaturation();
240 EXPECT_CALL(*gl_
, BindTexture(GL_TEXTURE_2D
, texture_id
))
242 .RetiresOnSaturation();
244 TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, min
))
246 .RetiresOnSaturation();
248 TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, mag
))
250 .RetiresOnSaturation();
251 EXPECT_CALL(*gl_
, TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, wrap_s
))
253 .RetiresOnSaturation();
254 EXPECT_CALL(*gl_
, TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, wrap_t
))
256 .RetiresOnSaturation();
257 EXPECT_CALL(*gl_
, Flush())
259 .RetiresOnSaturation();
260 EXPECT_CALL(*gl_
, BindTexture(GL_TEXTURE_2D
, kCurrentTexture
))
262 .RetiresOnSaturation();
265 void TearDown() override
{
266 context_
->ReleaseCurrent(NULL
);
267 MailboxManagerTest::TearDown();
270 scoped_refptr
<MailboxManager
> manager2_
;
271 scoped_refptr
<gfx::GLContext
> context_
;
272 scoped_refptr
<gfx::GLSurface
> surface_
;
275 DISALLOW_COPY_AND_ASSIGN(MailboxManagerSyncTest
);
278 TEST_F(MailboxManagerSyncTest
, ProduceDestroy
) {
279 Texture
* texture
= DefineTexture();
280 Mailbox name
= Mailbox::Generate();
283 manager_
->ProduceTexture(name
, texture
);
284 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
286 DestroyTexture(texture
);
287 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
288 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
291 TEST_F(MailboxManagerSyncTest
, ProduceSyncDestroy
) {
294 Texture
* texture
= DefineTexture();
295 Mailbox name
= Mailbox::Generate();
297 manager_
->ProduceTexture(name
, texture
);
298 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
301 manager_
->PushTextureUpdates(0);
302 manager2_
->PullTextureUpdates(0);
304 DestroyTexture(texture
);
305 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
306 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
309 TEST_F(MailboxManagerSyncTest
, ProduceSyncClobberDestroy
) {
312 Texture
* texture
= DefineTexture();
313 Mailbox name
= Mailbox::Generate();
315 manager_
->ProduceTexture(name
, texture
);
316 manager_
->PushTextureUpdates(0);
319 Texture
* old_texture
= texture
;
320 texture
= DefineTexture();
321 manager_
->ProduceTexture(name
, texture
);
323 DestroyTexture(old_texture
);
324 DestroyTexture(texture
);
325 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
326 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
329 // Duplicates a texture into a second manager instance, and then
330 // makes sure a redefinition becomes visible there too.
331 TEST_F(MailboxManagerSyncTest
, ProduceConsumeResize
) {
332 const GLuint kNewTextureId
= 1234;
335 Texture
* texture
= DefineTexture();
336 Mailbox name
= Mailbox::Generate();
338 manager_
->ProduceTexture(name
, texture
);
339 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
342 manager_
->PushTextureUpdates(0);
343 manager2_
->PullTextureUpdates(0);
345 EXPECT_CALL(*gl_
, GenTextures(1, _
))
346 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
347 SetupUpdateTexParamExpectations(
348 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
349 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
350 EXPECT_FALSE(new_texture
== NULL
);
351 EXPECT_NE(texture
, new_texture
);
352 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
354 // Resize original texture
355 SetLevelInfo(texture
,
366 // Should have been orphaned
367 EXPECT_TRUE(texture
->GetLevelImage(GL_TEXTURE_2D
, 0) == NULL
);
370 manager_
->PushTextureUpdates(0);
371 SetupUpdateTexParamExpectations(
372 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
373 manager2_
->PullTextureUpdates(0);
374 GLsizei width
, height
;
375 new_texture
->GetLevelSize(GL_TEXTURE_2D
, 0, &width
, &height
);
376 EXPECT_EQ(16, width
);
377 EXPECT_EQ(32, height
);
379 // Should have gotten a new attachment
380 EXPECT_TRUE(texture
->GetLevelImage(GL_TEXTURE_2D
, 0) != NULL
);
381 // Resize original texture again....
382 SetLevelInfo(texture
,
393 // ...and immediately delete the texture which should save the changes.
394 SetupUpdateTexParamExpectations(
395 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
396 DestroyTexture(texture
);
398 // Should be still around since there is a ref from manager2
399 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name
));
401 // The last change to the texture should be visible without a sync point (i.e.
403 manager2_
->PullTextureUpdates(0);
404 new_texture
->GetLevelSize(GL_TEXTURE_2D
, 0, &width
, &height
);
405 EXPECT_EQ(64, width
);
406 EXPECT_EQ(64, height
);
408 DestroyTexture(new_texture
);
409 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
410 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
413 // Makes sure changes are correctly published even when updates are
414 // pushed in both directions, i.e. makes sure we don't clobber a shared
415 // texture definition with an older version.
416 TEST_F(MailboxManagerSyncTest
, ProduceConsumeBidirectional
) {
417 const GLuint kNewTextureId1
= 1234;
418 const GLuint kNewTextureId2
= 4321;
420 Texture
* texture1
= DefineTexture();
421 Mailbox name1
= Mailbox::Generate();
422 Texture
* texture2
= DefineTexture();
423 Mailbox name2
= Mailbox::Generate();
424 Texture
* new_texture1
= NULL
;
425 Texture
* new_texture2
= NULL
;
427 manager_
->ProduceTexture(name1
, texture1
);
428 manager2_
->ProduceTexture(name2
, texture2
);
431 manager_
->PushTextureUpdates(0);
432 manager2_
->PushTextureUpdates(0);
434 // Create textures in the other manager instances for texture1 and texture2,
435 // respectively to create a real sharing scenario. Otherwise, there would
436 // never be conflicting updates/pushes.
439 EXPECT_CALL(*gl_
, GenTextures(1, _
))
440 .WillOnce(SetArgPointee
<1>(kNewTextureId1
));
441 SetupUpdateTexParamExpectations(
442 kNewTextureId1
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
443 new_texture1
= manager2_
->ConsumeTexture(name1
);
444 EXPECT_CALL(*gl_
, GenTextures(1, _
))
445 .WillOnce(SetArgPointee
<1>(kNewTextureId2
));
446 SetupUpdateTexParamExpectations(
447 kNewTextureId2
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
448 new_texture2
= manager_
->ConsumeTexture(name2
);
450 EXPECT_EQ(kNewTextureId1
, new_texture1
->service_id());
451 EXPECT_EQ(kNewTextureId2
, new_texture2
->service_id());
453 // Make a change to texture1
454 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), texture1
->min_filter());
455 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
456 SetParameter(texture1
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
458 // Make sure this does not clobber it with the previous version we pushed.
459 manager_
->PullTextureUpdates(0);
461 // Make a change to texture2
462 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), texture2
->mag_filter());
463 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
464 SetParameter(texture2
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
466 Mock::VerifyAndClearExpectations(gl_
.get());
468 // Synchronize in both directions
469 manager_
->PushTextureUpdates(0);
470 manager2_
->PushTextureUpdates(0);
471 // manager1 should see the change to texture2 mag_filter being applied.
472 SetupUpdateTexParamExpectations(
473 new_texture2
->service_id(), GL_LINEAR
, GL_NEAREST
, GL_REPEAT
, GL_REPEAT
);
474 manager_
->PullTextureUpdates(0);
475 // manager2 should see the change to texture1 min_filter being applied.
476 SetupUpdateTexParamExpectations(
477 new_texture1
->service_id(), GL_NEAREST
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
478 manager2_
->PullTextureUpdates(0);
480 DestroyTexture(texture1
);
481 DestroyTexture(texture2
);
482 DestroyTexture(new_texture1
);
483 DestroyTexture(new_texture2
);
486 // If a texture is shared with another manager instance, but the mailbox
487 // is then clobbered with a different texture in the source context, this should
488 // disconnect the earlier texture from updates.
489 TEST_F(MailboxManagerSyncTest
, ProduceAndClobber
) {
490 const GLuint kNewTextureId
= 1234;
493 Texture
* texture
= DefineTexture();
494 Mailbox name
= Mailbox::Generate();
496 manager_
->ProduceTexture(name
, texture
);
497 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
500 manager_
->PushTextureUpdates(0);
501 manager2_
->PullTextureUpdates(0);
503 EXPECT_CALL(*gl_
, GenTextures(1, _
))
504 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
505 SetupUpdateTexParamExpectations(
506 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
507 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
508 EXPECT_FALSE(new_texture
== NULL
);
509 EXPECT_NE(texture
, new_texture
);
510 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
512 Texture
* old_texture
= texture
;
513 texture
= DefineTexture();
514 manager_
->ProduceTexture(name
, texture
);
516 // Make a change to the new texture
517 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), texture
->min_filter());
518 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
519 SetParameter(texture
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
521 // Synchronize in both directions - no changes, since it's not shared
522 manager_
->PushTextureUpdates(0);
523 manager2_
->PullTextureUpdates(0);
524 EXPECT_EQ(static_cast<GLuint
>(GL_LINEAR
), new_texture
->min_filter());
526 // Make a change to the previously shared texture
527 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), old_texture
->mag_filter());
528 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
529 SetParameter(old_texture
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
531 // Synchronize and expect update
532 manager_
->PushTextureUpdates(0);
533 SetupUpdateTexParamExpectations(
534 new_texture
->service_id(), GL_LINEAR
, GL_NEAREST
, GL_REPEAT
, GL_REPEAT
);
535 manager2_
->PullTextureUpdates(0);
537 EXPECT_CALL(*gl_
, GenTextures(1, _
))
538 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
539 SetupUpdateTexParamExpectations(
540 kNewTextureId
, GL_NEAREST
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
541 Texture
* tmp_texture
= manager2_
->ConsumeTexture(name
);
542 EXPECT_NE(new_texture
, tmp_texture
);
543 DestroyTexture(tmp_texture
);
545 DestroyTexture(old_texture
);
546 DestroyTexture(texture
);
547 DestroyTexture(new_texture
);
549 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
550 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
553 TEST_F(MailboxManagerSyncTest
, ClearedStateSynced
) {
554 const GLuint kNewTextureId
= 1234;
556 Texture
* texture
= DefineTexture();
557 EXPECT_TRUE(texture
->SafeToRenderFrom());
559 Mailbox name
= Mailbox::Generate();
561 manager_
->ProduceTexture(name
, texture
);
562 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
565 manager_
->PushTextureUpdates(0);
566 manager2_
->PullTextureUpdates(0);
568 EXPECT_CALL(*gl_
, GenTextures(1, _
))
569 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
570 SetupUpdateTexParamExpectations(
571 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
572 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
573 EXPECT_FALSE(new_texture
== NULL
);
574 EXPECT_NE(texture
, new_texture
);
575 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
576 EXPECT_TRUE(texture
->SafeToRenderFrom());
578 // Change cleared to false.
579 SetLevelCleared(texture
, texture
->target(), 0, false);
580 EXPECT_FALSE(texture
->SafeToRenderFrom());
583 manager_
->PushTextureUpdates(0);
584 SetupUpdateTexParamExpectations(
585 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
586 manager2_
->PullTextureUpdates(0);
588 // Cleared state should be synced.
589 EXPECT_FALSE(new_texture
->SafeToRenderFrom());
591 DestroyTexture(texture
);
592 DestroyTexture(new_texture
);
594 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
595 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
598 TEST_F(MailboxManagerSyncTest
, SyncIncompleteTexture
) {
599 const GLuint kNewTextureId
= 1234;
601 // Create but not define texture.
602 Texture
* texture
= CreateTexture();
603 SetTarget(texture
, GL_TEXTURE_2D
, 1);
604 EXPECT_FALSE(texture
->IsDefined());
606 Mailbox name
= Mailbox::Generate();
607 manager_
->ProduceTexture(name
, texture
);
608 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
611 manager_
->PushTextureUpdates(0);
612 manager2_
->PullTextureUpdates(0);
614 // Should sync to new texture which is not defined.
615 EXPECT_CALL(*gl_
, GenTextures(1, _
))
616 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
617 SetupUpdateTexParamExpectations(kNewTextureId
, texture
->min_filter(),
618 texture
->mag_filter(), texture
->wrap_s(),
620 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
621 ASSERT_TRUE(new_texture
);
622 EXPECT_NE(texture
, new_texture
);
623 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
624 EXPECT_FALSE(new_texture
->IsDefined());
626 // Change cleared to false.
627 SetLevelInfo(texture
,
638 SetParameter(texture
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
639 SetParameter(texture
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
640 EXPECT_TRUE(texture
->IsDefined());
643 manager_
->PushTextureUpdates(0);
644 SetupUpdateTexParamExpectations(
645 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
646 manager2_
->PullTextureUpdates(0);
648 // Cleared state should be synced.
649 EXPECT_TRUE(new_texture
->IsDefined());
651 DestroyTexture(texture
);
652 DestroyTexture(new_texture
);
654 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
655 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
658 // Putting the same texture into multiple mailboxes should result in sharing
659 // only a single texture also within a synchronized manager instance.
660 TEST_F(MailboxManagerSyncTest
, SharedThroughMultipleMailboxes
) {
661 const GLuint kNewTextureId
= 1234;
664 Texture
* texture
= DefineTexture();
665 Mailbox name1
= Mailbox::Generate();
666 Mailbox name2
= Mailbox::Generate();
668 manager_
->ProduceTexture(name1
, texture
);
671 manager_
->PushTextureUpdates(0);
672 EXPECT_CALL(*gl_
, GenTextures(1, _
))
673 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
674 manager2_
->PullTextureUpdates(0);
675 SetupUpdateTexParamExpectations(
676 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
677 Texture
* new_texture
= manager2_
->ConsumeTexture(name1
);
678 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
680 manager_
->ProduceTexture(name2
, texture
);
683 manager_
->PushTextureUpdates(0);
684 manager2_
->PullTextureUpdates(0);
686 // name2 should return the same texture
687 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name2
));
689 // Even after destroying the source texture, the original mailbox should
691 DestroyTexture(texture
);
692 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name1
));
693 DestroyTexture(new_texture
);
696 // A: produce texture1 into M, B: consume into new_texture
697 // B: produce texture2 into M, A: produce texture1 into M
698 // B: consume M should return new_texture
699 TEST_F(MailboxManagerSyncTest
, ProduceBothWays
) {
700 const GLuint kNewTextureId
= 1234;
703 Texture
* texture1
= DefineTexture();
704 Texture
* texture2
= DefineTexture();
705 Mailbox name
= Mailbox::Generate();
707 manager_
->ProduceTexture(name
, texture1
);
710 manager_
->PushTextureUpdates(0);
711 EXPECT_CALL(*gl_
, GenTextures(1, _
))
712 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
713 SetupUpdateTexParamExpectations(
714 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
715 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
716 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
719 manager2_
->ProduceTexture(name
, texture2
);
720 manager_
->ProduceTexture(name
, texture1
);
722 // Synchronize manager -> manager2
723 manager_
->PushTextureUpdates(0);
724 manager2_
->PullTextureUpdates(0);
726 // name should return the original texture, and not texture2 or a new one.
727 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name
));
729 DestroyTexture(texture1
);
730 DestroyTexture(texture2
);
731 DestroyTexture(new_texture
);
734 // TODO: Texture::level_infos_[][].size()
736 // TODO: unsupported targets and formats