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();
241 EXPECT_CALL(*gl_
, Flush())
243 .RetiresOnSaturation();
246 void TearDown() override
{
247 context_
->ReleaseCurrent(NULL
);
248 MailboxManagerTest::TearDown();
251 scoped_refptr
<MailboxManager
> manager2_
;
252 scoped_refptr
<gfx::GLContext
> context_
;
253 scoped_refptr
<gfx::GLSurface
> surface_
;
256 DISALLOW_COPY_AND_ASSIGN(MailboxManagerSyncTest
);
259 TEST_F(MailboxManagerSyncTest
, ProduceDestroy
) {
260 Texture
* texture
= DefineTexture();
261 Mailbox name
= Mailbox::Generate();
264 manager_
->ProduceTexture(name
, texture
);
265 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
267 DestroyTexture(texture
);
268 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
269 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
272 TEST_F(MailboxManagerSyncTest
, ProduceSyncDestroy
) {
275 Texture
* texture
= DefineTexture();
276 Mailbox name
= Mailbox::Generate();
278 manager_
->ProduceTexture(name
, texture
);
279 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
282 manager_
->PushTextureUpdates(0);
283 manager2_
->PullTextureUpdates(0);
285 DestroyTexture(texture
);
286 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
287 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
290 TEST_F(MailboxManagerSyncTest
, ProduceSyncClobberDestroy
) {
293 Texture
* texture
= DefineTexture();
294 Mailbox name
= Mailbox::Generate();
296 manager_
->ProduceTexture(name
, texture
);
297 manager_
->PushTextureUpdates(0);
300 Texture
* old_texture
= texture
;
301 texture
= DefineTexture();
302 manager_
->ProduceTexture(name
, texture
);
304 DestroyTexture(old_texture
);
305 DestroyTexture(texture
);
306 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
307 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
310 // Duplicates a texture into a second manager instance, and then
311 // makes sure a redefinition becomes visible there too.
312 TEST_F(MailboxManagerSyncTest
, ProduceConsumeResize
) {
313 const GLuint kNewTextureId
= 1234;
316 Texture
* texture
= DefineTexture();
317 Mailbox name
= Mailbox::Generate();
319 manager_
->ProduceTexture(name
, texture
);
320 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
323 manager_
->PushTextureUpdates(0);
324 manager2_
->PullTextureUpdates(0);
326 EXPECT_CALL(*gl_
, GenTextures(1, _
))
327 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
328 SetupUpdateTexParamExpectations(
329 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
330 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
331 EXPECT_FALSE(new_texture
== NULL
);
332 EXPECT_NE(texture
, new_texture
);
333 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
335 // Resize original texture
336 SetLevelInfo(texture
, GL_TEXTURE_2D
, 0, GL_RGBA
, 16, 32, 1, 0, GL_RGBA
,
337 GL_UNSIGNED_BYTE
, gfx::Rect(16, 32));
338 // Should have been orphaned
339 EXPECT_TRUE(texture
->GetLevelImage(GL_TEXTURE_2D
, 0) == NULL
);
342 manager_
->PushTextureUpdates(0);
343 SetupUpdateTexParamExpectations(
344 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
345 manager2_
->PullTextureUpdates(0);
346 GLsizei width
, height
;
347 new_texture
->GetLevelSize(GL_TEXTURE_2D
, 0, &width
, &height
, nullptr);
348 EXPECT_EQ(16, width
);
349 EXPECT_EQ(32, height
);
351 // Should have gotten a new attachment
352 EXPECT_TRUE(texture
->GetLevelImage(GL_TEXTURE_2D
, 0) != NULL
);
353 // Resize original texture again....
354 SetLevelInfo(texture
, GL_TEXTURE_2D
, 0, GL_RGBA
, 64, 64, 1, 0, GL_RGBA
,
355 GL_UNSIGNED_BYTE
, gfx::Rect(64, 64));
356 // ...and immediately delete the texture which should save the changes.
357 SetupUpdateTexParamExpectations(
358 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
359 DestroyTexture(texture
);
361 // Should be still around since there is a ref from manager2
362 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name
));
364 // The last change to the texture should be visible without a sync point (i.e.
366 manager2_
->PullTextureUpdates(0);
367 new_texture
->GetLevelSize(GL_TEXTURE_2D
, 0, &width
, &height
, nullptr);
368 EXPECT_EQ(64, width
);
369 EXPECT_EQ(64, height
);
371 DestroyTexture(new_texture
);
372 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
373 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
376 // Makes sure changes are correctly published even when updates are
377 // pushed in both directions, i.e. makes sure we don't clobber a shared
378 // texture definition with an older version.
379 TEST_F(MailboxManagerSyncTest
, ProduceConsumeBidirectional
) {
380 const GLuint kNewTextureId1
= 1234;
381 const GLuint kNewTextureId2
= 4321;
383 Texture
* texture1
= DefineTexture();
384 Mailbox name1
= Mailbox::Generate();
385 Texture
* texture2
= DefineTexture();
386 Mailbox name2
= Mailbox::Generate();
387 Texture
* new_texture1
= NULL
;
388 Texture
* new_texture2
= NULL
;
390 manager_
->ProduceTexture(name1
, texture1
);
391 manager2_
->ProduceTexture(name2
, texture2
);
394 manager_
->PushTextureUpdates(0);
395 manager2_
->PushTextureUpdates(0);
397 // Create textures in the other manager instances for texture1 and texture2,
398 // respectively to create a real sharing scenario. Otherwise, there would
399 // never be conflicting updates/pushes.
402 EXPECT_CALL(*gl_
, GenTextures(1, _
))
403 .WillOnce(SetArgPointee
<1>(kNewTextureId1
));
404 SetupUpdateTexParamExpectations(
405 kNewTextureId1
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
406 new_texture1
= manager2_
->ConsumeTexture(name1
);
407 EXPECT_CALL(*gl_
, GenTextures(1, _
))
408 .WillOnce(SetArgPointee
<1>(kNewTextureId2
));
409 SetupUpdateTexParamExpectations(
410 kNewTextureId2
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
411 new_texture2
= manager_
->ConsumeTexture(name2
);
413 EXPECT_EQ(kNewTextureId1
, new_texture1
->service_id());
414 EXPECT_EQ(kNewTextureId2
, new_texture2
->service_id());
416 // Make a change to texture1
417 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), texture1
->min_filter());
418 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
419 SetParameter(texture1
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
421 // Make sure this does not clobber it with the previous version we pushed.
422 manager_
->PullTextureUpdates(0);
424 // Make a change to texture2
425 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), texture2
->mag_filter());
426 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
427 SetParameter(texture2
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
429 Mock::VerifyAndClearExpectations(gl_
.get());
431 // Synchronize in both directions
432 manager_
->PushTextureUpdates(0);
433 manager2_
->PushTextureUpdates(0);
434 // manager1 should see the change to texture2 mag_filter being applied.
435 SetupUpdateTexParamExpectations(
436 new_texture2
->service_id(), GL_LINEAR
, GL_NEAREST
, GL_REPEAT
, GL_REPEAT
);
437 manager_
->PullTextureUpdates(0);
438 // manager2 should see the change to texture1 min_filter being applied.
439 SetupUpdateTexParamExpectations(
440 new_texture1
->service_id(), GL_NEAREST
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
441 manager2_
->PullTextureUpdates(0);
443 DestroyTexture(texture1
);
444 DestroyTexture(texture2
);
445 DestroyTexture(new_texture1
);
446 DestroyTexture(new_texture2
);
449 // If a texture is shared with another manager instance, but the mailbox
450 // is then clobbered with a different texture in the source context, this should
451 // disconnect the earlier texture from updates.
452 TEST_F(MailboxManagerSyncTest
, ProduceAndClobber
) {
453 const GLuint kNewTextureId
= 1234;
456 Texture
* texture
= DefineTexture();
457 Mailbox name
= Mailbox::Generate();
459 manager_
->ProduceTexture(name
, texture
);
460 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
463 manager_
->PushTextureUpdates(0);
464 manager2_
->PullTextureUpdates(0);
466 EXPECT_CALL(*gl_
, GenTextures(1, _
))
467 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
468 SetupUpdateTexParamExpectations(
469 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
470 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
471 EXPECT_FALSE(new_texture
== NULL
);
472 EXPECT_NE(texture
, new_texture
);
473 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
475 Texture
* old_texture
= texture
;
476 texture
= DefineTexture();
477 manager_
->ProduceTexture(name
, texture
);
479 // Make a change to the new texture
480 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), texture
->min_filter());
481 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
482 SetParameter(texture
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
484 // Synchronize in both directions - no changes, since it's not shared
485 manager_
->PushTextureUpdates(0);
486 manager2_
->PullTextureUpdates(0);
487 EXPECT_EQ(static_cast<GLuint
>(GL_LINEAR
), new_texture
->min_filter());
489 // Make a change to the previously shared texture
490 DCHECK_EQ(static_cast<GLuint
>(GL_LINEAR
), old_texture
->mag_filter());
491 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
),
492 SetParameter(old_texture
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
494 // Synchronize and expect update
495 manager_
->PushTextureUpdates(0);
496 SetupUpdateTexParamExpectations(
497 new_texture
->service_id(), GL_LINEAR
, GL_NEAREST
, GL_REPEAT
, GL_REPEAT
);
498 manager2_
->PullTextureUpdates(0);
500 EXPECT_CALL(*gl_
, GenTextures(1, _
))
501 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
502 SetupUpdateTexParamExpectations(
503 kNewTextureId
, GL_NEAREST
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
504 Texture
* tmp_texture
= manager2_
->ConsumeTexture(name
);
505 EXPECT_NE(new_texture
, tmp_texture
);
506 DestroyTexture(tmp_texture
);
508 DestroyTexture(old_texture
);
509 DestroyTexture(texture
);
510 DestroyTexture(new_texture
);
512 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
513 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
516 TEST_F(MailboxManagerSyncTest
, ClearedStateSynced
) {
517 const GLuint kNewTextureId
= 1234;
519 Texture
* texture
= DefineTexture();
520 EXPECT_TRUE(texture
->SafeToRenderFrom());
522 Mailbox name
= Mailbox::Generate();
524 manager_
->ProduceTexture(name
, texture
);
525 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
528 manager_
->PushTextureUpdates(0);
529 manager2_
->PullTextureUpdates(0);
531 EXPECT_CALL(*gl_
, GenTextures(1, _
))
532 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
533 SetupUpdateTexParamExpectations(
534 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
535 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
536 EXPECT_FALSE(new_texture
== NULL
);
537 EXPECT_NE(texture
, new_texture
);
538 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
539 EXPECT_TRUE(texture
->SafeToRenderFrom());
541 // Change cleared to false.
542 SetLevelCleared(texture
, texture
->target(), 0, false);
543 EXPECT_FALSE(texture
->SafeToRenderFrom());
546 manager_
->PushTextureUpdates(0);
547 SetupUpdateTexParamExpectations(
548 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
549 manager2_
->PullTextureUpdates(0);
551 // Cleared state should be synced.
552 EXPECT_FALSE(new_texture
->SafeToRenderFrom());
554 DestroyTexture(texture
);
555 DestroyTexture(new_texture
);
557 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
558 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
561 TEST_F(MailboxManagerSyncTest
, SyncIncompleteTexture
) {
562 const GLuint kNewTextureId
= 1234;
564 // Create but not define texture.
565 Texture
* texture
= CreateTexture();
566 SetTarget(texture
, GL_TEXTURE_2D
, 1);
567 EXPECT_FALSE(texture
->IsDefined());
569 Mailbox name
= Mailbox::Generate();
570 manager_
->ProduceTexture(name
, texture
);
571 EXPECT_EQ(texture
, manager_
->ConsumeTexture(name
));
574 manager_
->PushTextureUpdates(0);
575 manager2_
->PullTextureUpdates(0);
577 // Should sync to new texture which is not defined.
578 EXPECT_CALL(*gl_
, GenTextures(1, _
))
579 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
580 SetupUpdateTexParamExpectations(kNewTextureId
, texture
->min_filter(),
581 texture
->mag_filter(), texture
->wrap_s(),
583 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
584 ASSERT_TRUE(new_texture
);
585 EXPECT_NE(texture
, new_texture
);
586 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
587 EXPECT_FALSE(new_texture
->IsDefined());
589 // Change cleared to false.
590 SetLevelInfo(texture
, GL_TEXTURE_2D
, 0, GL_RGBA
, 1, 1, 1, 0, GL_RGBA
,
591 GL_UNSIGNED_BYTE
, gfx::Rect(1, 1));
592 SetParameter(texture
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
593 SetParameter(texture
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
594 EXPECT_TRUE(texture
->IsDefined());
597 manager_
->PushTextureUpdates(0);
598 SetupUpdateTexParamExpectations(
599 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
600 manager2_
->PullTextureUpdates(0);
602 // Cleared state should be synced.
603 EXPECT_TRUE(new_texture
->IsDefined());
605 DestroyTexture(texture
);
606 DestroyTexture(new_texture
);
608 EXPECT_EQ(NULL
, manager_
->ConsumeTexture(name
));
609 EXPECT_EQ(NULL
, manager2_
->ConsumeTexture(name
));
612 // Putting the same texture into multiple mailboxes should result in sharing
613 // only a single texture also within a synchronized manager instance.
614 TEST_F(MailboxManagerSyncTest
, SharedThroughMultipleMailboxes
) {
615 const GLuint kNewTextureId
= 1234;
618 Texture
* texture
= DefineTexture();
619 Mailbox name1
= Mailbox::Generate();
620 Mailbox name2
= Mailbox::Generate();
622 manager_
->ProduceTexture(name1
, texture
);
625 manager_
->PushTextureUpdates(0);
626 EXPECT_CALL(*gl_
, GenTextures(1, _
))
627 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
628 manager2_
->PullTextureUpdates(0);
629 SetupUpdateTexParamExpectations(
630 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
631 Texture
* new_texture
= manager2_
->ConsumeTexture(name1
);
632 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
634 manager_
->ProduceTexture(name2
, texture
);
637 manager_
->PushTextureUpdates(0);
638 manager2_
->PullTextureUpdates(0);
640 // name2 should return the same texture
641 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name2
));
643 // Even after destroying the source texture, the original mailbox should
645 DestroyTexture(texture
);
646 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name1
));
647 DestroyTexture(new_texture
);
650 // A: produce texture1 into M, B: consume into new_texture
651 // B: produce texture2 into M, A: produce texture1 into M
652 // B: consume M should return new_texture
653 TEST_F(MailboxManagerSyncTest
, ProduceBothWays
) {
654 const GLuint kNewTextureId
= 1234;
657 Texture
* texture1
= DefineTexture();
658 Texture
* texture2
= DefineTexture();
659 Mailbox name
= Mailbox::Generate();
661 manager_
->ProduceTexture(name
, texture1
);
664 manager_
->PushTextureUpdates(0);
665 EXPECT_CALL(*gl_
, GenTextures(1, _
))
666 .WillOnce(SetArgPointee
<1>(kNewTextureId
));
667 SetupUpdateTexParamExpectations(
668 kNewTextureId
, GL_LINEAR
, GL_LINEAR
, GL_REPEAT
, GL_REPEAT
);
669 Texture
* new_texture
= manager2_
->ConsumeTexture(name
);
670 EXPECT_EQ(kNewTextureId
, new_texture
->service_id());
673 manager2_
->ProduceTexture(name
, texture2
);
674 manager_
->ProduceTexture(name
, texture1
);
676 // Synchronize manager -> manager2
677 manager_
->PushTextureUpdates(0);
678 manager2_
->PullTextureUpdates(0);
680 // name should return the original texture, and not texture2 or a new one.
681 EXPECT_EQ(new_texture
, manager2_
->ConsumeTexture(name
));
683 DestroyTexture(texture1
);
684 DestroyTexture(texture2
);
685 DestroyTexture(new_texture
);
688 // TODO: Texture::level_infos_[][].size()
690 // TODO: unsupported targets and formats