Index: gpu/command_buffer/service/mailbox_manager_unittest.cc |
diff --git a/gpu/command_buffer/service/mailbox_manager_unittest.cc b/gpu/command_buffer/service/mailbox_manager_unittest.cc |
index 63ffc6d6e4af0b9043c2fcbaef37b5f002f6cb2b..1aea4c587ccc82353f4b8f075a4f493d58d4df1d 100644 |
--- a/gpu/command_buffer/service/mailbox_manager_unittest.cc |
+++ b/gpu/command_buffer/service/mailbox_manager_unittest.cc |
@@ -2,11 +2,10 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "gpu/command_buffer/service/mailbox_manager.h" |
- |
#include "gpu/command_buffer/service/feature_info.h" |
#include "gpu/command_buffer/service/gpu_service_test.h" |
-#include "gpu/command_buffer/service/mailbox_synchronizer.h" |
+#include "gpu/command_buffer/service/mailbox_manager_impl.h" |
+#include "gpu/command_buffer/service/mailbox_manager_sync.h" |
#include "gpu/command_buffer/service/texture_manager.h" |
#include "testing/gtest/include/gtest/gtest.h" |
#include "ui/gl/gl_context_stub.h" |
@@ -20,27 +19,25 @@ using namespace ::testing; |
class MailboxManagerTest : public GpuServiceTest { |
public: |
- MailboxManagerTest() : initialized_synchronizer_(false) {} |
+ MailboxManagerTest() {} |
virtual ~MailboxManagerTest() {} |
protected: |
virtual void SetUp() { |
GpuServiceTest::SetUp(); |
feature_info_ = new FeatureInfo; |
- manager_ = new MailboxManager; |
+ manager_ = new MailboxManagerImpl; |
+ DCHECK(!manager_->UsesSync()); |
} |
virtual void SetUpWithSynchronizer() { |
GpuServiceTest::SetUp(); |
- MailboxSynchronizer::Initialize(); |
- initialized_synchronizer_ = true; |
feature_info_ = new FeatureInfo; |
- manager_ = new MailboxManager; |
+ manager_ = new MailboxManagerSync(); |
+ DCHECK(manager_->UsesSync()); |
} |
virtual void TearDown() { |
- if (initialized_synchronizer_) |
- MailboxSynchronizer::Terminate(); |
GpuServiceTest::TearDown(); |
} |
@@ -88,7 +85,6 @@ class MailboxManagerTest : public GpuServiceTest { |
scoped_refptr<MailboxManager> manager_; |
private: |
- bool initialized_synchronizer_; |
scoped_refptr<FeatureInfo> feature_info_; |
DISALLOW_COPY_AND_ASSIGN(MailboxManagerTest); |
@@ -99,18 +95,15 @@ TEST_F(MailboxManagerTest, Basic) { |
Texture* texture = CreateTexture(); |
Mailbox name = Mailbox::Generate(); |
- manager_->ProduceTexture(0, name, texture); |
- EXPECT_EQ(texture, manager_->ConsumeTexture(0, name)); |
+ manager_->ProduceTexture(name, texture); |
+ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); |
// We can consume multiple times. |
- EXPECT_EQ(texture, manager_->ConsumeTexture(0, name)); |
- |
- // Wrong target should fail the consume. |
- EXPECT_EQ(NULL, manager_->ConsumeTexture(1, name)); |
+ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); |
// Destroy should cleanup the mailbox. |
DestroyTexture(texture); |
- EXPECT_EQ(NULL, manager_->ConsumeTexture(0, name)); |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name)); |
} |
// Tests behavior with multiple produce on the same texture. |
@@ -119,25 +112,25 @@ TEST_F(MailboxManagerTest, ProduceMultipleMailbox) { |
Mailbox name1 = Mailbox::Generate(); |
- manager_->ProduceTexture(0, name1, texture); |
- EXPECT_EQ(texture, manager_->ConsumeTexture(0, name1)); |
+ manager_->ProduceTexture(name1, texture); |
+ EXPECT_EQ(texture, manager_->ConsumeTexture(name1)); |
// Can produce a second time with the same mailbox. |
- manager_->ProduceTexture(0, name1, texture); |
- EXPECT_EQ(texture, manager_->ConsumeTexture(0, name1)); |
+ manager_->ProduceTexture(name1, texture); |
+ EXPECT_EQ(texture, manager_->ConsumeTexture(name1)); |
// Can produce again, with a different mailbox. |
Mailbox name2 = Mailbox::Generate(); |
- manager_->ProduceTexture(0, name2, texture); |
+ manager_->ProduceTexture(name2, texture); |
// Still available under all mailboxes. |
- EXPECT_EQ(texture, manager_->ConsumeTexture(0, name1)); |
- EXPECT_EQ(texture, manager_->ConsumeTexture(0, name2)); |
+ EXPECT_EQ(texture, manager_->ConsumeTexture(name1)); |
+ EXPECT_EQ(texture, manager_->ConsumeTexture(name2)); |
// Destroy should cleanup all mailboxes. |
DestroyTexture(texture); |
- EXPECT_EQ(NULL, manager_->ConsumeTexture(0, name1)); |
- EXPECT_EQ(NULL, manager_->ConsumeTexture(0, name2)); |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name1)); |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name2)); |
} |
// Tests behavior with multiple produce on the same mailbox with different |
@@ -148,20 +141,20 @@ TEST_F(MailboxManagerTest, ProduceMultipleTexture) { |
Mailbox name = Mailbox::Generate(); |
- manager_->ProduceTexture(0, name, texture1); |
- EXPECT_EQ(texture1, manager_->ConsumeTexture(0, name)); |
+ manager_->ProduceTexture(name, texture1); |
+ EXPECT_EQ(texture1, manager_->ConsumeTexture(name)); |
// Can produce a second time with the same mailbox, but different texture. |
- manager_->ProduceTexture(0, name, texture2); |
- EXPECT_EQ(texture2, manager_->ConsumeTexture(0, name)); |
+ manager_->ProduceTexture(name, texture2); |
+ EXPECT_EQ(texture2, manager_->ConsumeTexture(name)); |
// Destroying the texture that's under no mailbox shouldn't have an effect. |
DestroyTexture(texture1); |
- EXPECT_EQ(texture2, manager_->ConsumeTexture(0, name)); |
+ EXPECT_EQ(texture2, manager_->ConsumeTexture(name)); |
// Destroying the texture that's bound should clean up. |
DestroyTexture(texture2); |
- EXPECT_EQ(NULL, manager_->ConsumeTexture(0, name)); |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name)); |
} |
TEST_F(MailboxManagerTest, ProduceMultipleTextureMailbox) { |
@@ -171,23 +164,23 @@ TEST_F(MailboxManagerTest, ProduceMultipleTextureMailbox) { |
Mailbox name2 = Mailbox::Generate(); |
// Put texture1 on name1 and name2. |
- manager_->ProduceTexture(0, name1, texture1); |
- manager_->ProduceTexture(0, name2, texture1); |
- EXPECT_EQ(texture1, manager_->ConsumeTexture(0, name1)); |
- EXPECT_EQ(texture1, manager_->ConsumeTexture(0, name2)); |
+ manager_->ProduceTexture(name1, texture1); |
+ manager_->ProduceTexture(name2, texture1); |
+ EXPECT_EQ(texture1, manager_->ConsumeTexture(name1)); |
+ EXPECT_EQ(texture1, manager_->ConsumeTexture(name2)); |
// Put texture2 on name2. |
- manager_->ProduceTexture(0, name2, texture2); |
- EXPECT_EQ(texture1, manager_->ConsumeTexture(0, name1)); |
- EXPECT_EQ(texture2, manager_->ConsumeTexture(0, name2)); |
+ manager_->ProduceTexture(name2, texture2); |
+ EXPECT_EQ(texture1, manager_->ConsumeTexture(name1)); |
+ EXPECT_EQ(texture2, manager_->ConsumeTexture(name2)); |
// Destroy texture1, shouldn't affect name2. |
DestroyTexture(texture1); |
- EXPECT_EQ(NULL, manager_->ConsumeTexture(0, name1)); |
- EXPECT_EQ(texture2, manager_->ConsumeTexture(0, name2)); |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name1)); |
+ EXPECT_EQ(texture2, manager_->ConsumeTexture(name2)); |
DestroyTexture(texture2); |
- EXPECT_EQ(NULL, manager_->ConsumeTexture(0, name2)); |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name2)); |
} |
const GLsizei kMaxTextureWidth = 64; |
@@ -202,7 +195,7 @@ class MailboxManagerSyncTest : public MailboxManagerTest { |
protected: |
virtual void SetUp() { |
MailboxManagerTest::SetUpWithSynchronizer(); |
- manager2_ = new MailboxManager; |
+ manager2_ = new MailboxManagerSync(); |
context_ = new gfx::GLContextStub(); |
surface_ = new gfx::GLSurfaceStub(); |
context_->MakeCurrent(surface_.get()); |
@@ -282,12 +275,12 @@ TEST_F(MailboxManagerSyncTest, ProduceDestroy) { |
Mailbox name = Mailbox::Generate(); |
InSequence sequence; |
- manager_->ProduceTexture(GL_TEXTURE_2D, name, texture); |
- EXPECT_EQ(texture, manager_->ConsumeTexture(GL_TEXTURE_2D, name)); |
+ manager_->ProduceTexture(name, texture); |
+ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); |
DestroyTexture(texture); |
- EXPECT_EQ(NULL, manager_->ConsumeTexture(GL_TEXTURE_2D, name)); |
- EXPECT_EQ(NULL, manager2_->ConsumeTexture(GL_TEXTURE_2D, name)); |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name)); |
+ EXPECT_EQ(NULL, manager2_->ConsumeTexture(name)); |
} |
TEST_F(MailboxManagerSyncTest, ProduceSyncDestroy) { |
@@ -296,16 +289,36 @@ TEST_F(MailboxManagerSyncTest, ProduceSyncDestroy) { |
Texture* texture = DefineTexture(); |
Mailbox name = Mailbox::Generate(); |
- manager_->ProduceTexture(GL_TEXTURE_2D, name, texture); |
- EXPECT_EQ(texture, manager_->ConsumeTexture(GL_TEXTURE_2D, name)); |
+ manager_->ProduceTexture(name, texture); |
+ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); |
// Synchronize |
manager_->PushTextureUpdates(0); |
manager2_->PullTextureUpdates(0); |
DestroyTexture(texture); |
- EXPECT_EQ(NULL, manager_->ConsumeTexture(GL_TEXTURE_2D, name)); |
- EXPECT_EQ(NULL, manager2_->ConsumeTexture(GL_TEXTURE_2D, name)); |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name)); |
+ EXPECT_EQ(NULL, manager2_->ConsumeTexture(name)); |
+} |
+ |
+TEST_F(MailboxManagerSyncTest, ProduceSyncClobberDestroy) { |
+ InSequence sequence; |
+ |
+ Texture* texture = DefineTexture(); |
+ Mailbox name = Mailbox::Generate(); |
+ |
+ manager_->ProduceTexture(name, texture); |
+ manager_->PushTextureUpdates(0); |
+ |
+ // Clobber |
+ Texture* old_texture = texture; |
+ texture = DefineTexture(); |
+ manager_->ProduceTexture(name, texture); |
+ |
+ DestroyTexture(old_texture); |
+ DestroyTexture(texture); |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name)); |
+ EXPECT_EQ(NULL, manager2_->ConsumeTexture(name)); |
} |
// Duplicates a texture into a second manager instance, and then |
@@ -317,8 +330,8 @@ TEST_F(MailboxManagerSyncTest, ProduceConsumeResize) { |
Texture* texture = DefineTexture(); |
Mailbox name = Mailbox::Generate(); |
- manager_->ProduceTexture(GL_TEXTURE_2D, name, texture); |
- EXPECT_EQ(texture, manager_->ConsumeTexture(GL_TEXTURE_2D, name)); |
+ manager_->ProduceTexture(name, texture); |
+ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); |
// Synchronize |
manager_->PushTextureUpdates(0); |
@@ -328,7 +341,7 @@ TEST_F(MailboxManagerSyncTest, ProduceConsumeResize) { |
.WillOnce(SetArgPointee<1>(kNewTextureId)); |
SetupUpdateTexParamExpectations( |
kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); |
- Texture* new_texture = manager2_->ConsumeTexture(GL_TEXTURE_2D, name); |
+ Texture* new_texture = manager2_->ConsumeTexture(name); |
EXPECT_FALSE(new_texture == NULL); |
EXPECT_NE(texture, new_texture); |
EXPECT_EQ(kNewTextureId, new_texture->service_id()); |
@@ -378,7 +391,7 @@ TEST_F(MailboxManagerSyncTest, ProduceConsumeResize) { |
DestroyTexture(texture); |
// Should be still around since there is a ref from manager2 |
- EXPECT_EQ(new_texture, manager2_->ConsumeTexture(GL_TEXTURE_2D, name)); |
+ EXPECT_EQ(new_texture, manager2_->ConsumeTexture(name)); |
// The last change to the texture should be visible without a sync point (i.e. |
// push). |
@@ -388,8 +401,8 @@ TEST_F(MailboxManagerSyncTest, ProduceConsumeResize) { |
EXPECT_EQ(64, height); |
DestroyTexture(new_texture); |
- EXPECT_EQ(NULL, manager_->ConsumeTexture(GL_TEXTURE_2D, name)); |
- EXPECT_EQ(NULL, manager2_->ConsumeTexture(GL_TEXTURE_2D, name)); |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name)); |
+ EXPECT_EQ(NULL, manager2_->ConsumeTexture(name)); |
} |
// Makes sure changes are correctly published even when updates are |
@@ -406,8 +419,8 @@ TEST_F(MailboxManagerSyncTest, ProduceConsumeBidirectional) { |
Texture* new_texture1 = NULL; |
Texture* new_texture2 = NULL; |
- manager_->ProduceTexture(GL_TEXTURE_2D, name1, texture1); |
- manager2_->ProduceTexture(GL_TEXTURE_2D, name2, texture2); |
+ manager_->ProduceTexture(name1, texture1); |
+ manager2_->ProduceTexture(name2, texture2); |
// Make visible. |
manager_->PushTextureUpdates(0); |
@@ -422,12 +435,12 @@ TEST_F(MailboxManagerSyncTest, ProduceConsumeBidirectional) { |
.WillOnce(SetArgPointee<1>(kNewTextureId1)); |
SetupUpdateTexParamExpectations( |
kNewTextureId1, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); |
- new_texture1 = manager2_->ConsumeTexture(GL_TEXTURE_2D, name1); |
+ new_texture1 = manager2_->ConsumeTexture(name1); |
EXPECT_CALL(*gl_, GenTextures(1, _)) |
.WillOnce(SetArgPointee<1>(kNewTextureId2)); |
SetupUpdateTexParamExpectations( |
kNewTextureId2, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); |
- new_texture2 = manager_->ConsumeTexture(GL_TEXTURE_2D, name2); |
+ new_texture2 = manager_->ConsumeTexture(name2); |
} |
EXPECT_EQ(kNewTextureId1, new_texture1->service_id()); |
EXPECT_EQ(kNewTextureId2, new_texture2->service_id()); |
@@ -465,9 +478,148 @@ TEST_F(MailboxManagerSyncTest, ProduceConsumeBidirectional) { |
DestroyTexture(new_texture2); |
} |
-// TODO: different texture into same mailbox |
+// If a texture is shared with another manager instance, but the mailbox |
+// is then clobbered with a different texture in the source context, this should |
+// disconnect the earlier texture from updates. |
+TEST_F(MailboxManagerSyncTest, ProduceAndClobber) { |
+ const GLuint kNewTextureId = 1234; |
+ InSequence sequence; |
+ |
+ Texture* texture = DefineTexture(); |
+ Mailbox name = Mailbox::Generate(); |
+ |
+ manager_->ProduceTexture(name, texture); |
+ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); |
+ |
+ // Synchronize |
+ manager_->PushTextureUpdates(0); |
+ manager2_->PullTextureUpdates(0); |
+ |
+ EXPECT_CALL(*gl_, GenTextures(1, _)) |
+ .WillOnce(SetArgPointee<1>(kNewTextureId)); |
+ SetupUpdateTexParamExpectations( |
+ kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); |
+ Texture* new_texture = manager2_->ConsumeTexture(name); |
+ EXPECT_FALSE(new_texture == NULL); |
+ EXPECT_NE(texture, new_texture); |
+ EXPECT_EQ(kNewTextureId, new_texture->service_id()); |
+ |
+ Texture* old_texture = texture; |
+ texture = DefineTexture(); |
+ manager_->ProduceTexture(name, texture); |
+ |
+ // Make a change to the new texture |
+ DCHECK_EQ(static_cast<GLuint>(GL_LINEAR), texture->min_filter()); |
+ EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), |
+ SetParameter(texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
+ |
+ // Synchronize in both directions - no changes, since it's not shared |
+ manager_->PushTextureUpdates(0); |
+ manager2_->PullTextureUpdates(0); |
+ EXPECT_EQ(static_cast<GLuint>(GL_LINEAR), new_texture->min_filter()); |
+ |
+ // Make a change to the previously shared texture |
+ DCHECK_EQ(static_cast<GLuint>(GL_LINEAR), old_texture->mag_filter()); |
+ EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), |
+ SetParameter(old_texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); |
+ |
+ // Synchronize and expect update |
+ manager_->PushTextureUpdates(0); |
+ SetupUpdateTexParamExpectations( |
+ new_texture->service_id(), GL_LINEAR, GL_NEAREST, GL_REPEAT, GL_REPEAT); |
+ manager2_->PullTextureUpdates(0); |
+ |
+ EXPECT_CALL(*gl_, GenTextures(1, _)) |
+ .WillOnce(SetArgPointee<1>(kNewTextureId)); |
+ SetupUpdateTexParamExpectations( |
+ kNewTextureId, GL_NEAREST, GL_LINEAR, GL_REPEAT, GL_REPEAT); |
+ Texture* tmp_texture = manager2_->ConsumeTexture(name); |
+ EXPECT_NE(new_texture, tmp_texture); |
+ DestroyTexture(tmp_texture); |
+ |
+ DestroyTexture(old_texture); |
+ DestroyTexture(texture); |
+ DestroyTexture(new_texture); |
+ |
+ EXPECT_EQ(NULL, manager_->ConsumeTexture(name)); |
+ EXPECT_EQ(NULL, manager2_->ConsumeTexture(name)); |
+} |
+ |
+// Putting the same texture into multiple mailboxes should result in sharing |
+// only a single texture also within a synchronized manager instance. |
+TEST_F(MailboxManagerSyncTest, SharedThroughMultipleMailboxes) { |
+ const GLuint kNewTextureId = 1234; |
+ InSequence sequence; |
+ |
+ Texture* texture = DefineTexture(); |
+ Mailbox name1 = Mailbox::Generate(); |
+ Mailbox name2 = Mailbox::Generate(); |
+ |
+ manager_->ProduceTexture(name1, texture); |
+ |
+ // Share |
+ manager_->PushTextureUpdates(0); |
+ EXPECT_CALL(*gl_, GenTextures(1, _)) |
+ .WillOnce(SetArgPointee<1>(kNewTextureId)); |
+ manager2_->PullTextureUpdates(0); |
+ SetupUpdateTexParamExpectations( |
+ kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); |
+ Texture* new_texture = manager2_->ConsumeTexture(name1); |
+ EXPECT_EQ(kNewTextureId, new_texture->service_id()); |
+ |
+ manager_->ProduceTexture(name2, texture); |
-// TODO: same texture, multiple mailboxes |
+ // Synchronize |
+ manager_->PushTextureUpdates(0); |
+ manager2_->PullTextureUpdates(0); |
+ |
+ // name2 should return the same texture |
+ EXPECT_EQ(new_texture, manager2_->ConsumeTexture(name2)); |
+ |
+ // Even after destroying the source texture, the original mailbox should |
+ // still exist. |
+ DestroyTexture(texture); |
+ EXPECT_EQ(new_texture, manager2_->ConsumeTexture(name1)); |
+ DestroyTexture(new_texture); |
+} |
+ |
+// A: produce texture1 into M, B: consume into new_texture |
+// B: produce texture2 into M, A: produce texture1 into M |
+// B: consume M should return new_texture |
+TEST_F(MailboxManagerSyncTest, ProduceBothWays) { |
+ const GLuint kNewTextureId = 1234; |
+ InSequence sequence; |
+ |
+ Texture* texture1 = DefineTexture(); |
+ Texture* texture2 = DefineTexture(); |
+ Mailbox name = Mailbox::Generate(); |
+ |
+ manager_->ProduceTexture(name, texture1); |
+ |
+ // Share |
+ manager_->PushTextureUpdates(0); |
+ EXPECT_CALL(*gl_, GenTextures(1, _)) |
+ .WillOnce(SetArgPointee<1>(kNewTextureId)); |
+ SetupUpdateTexParamExpectations( |
+ kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); |
+ Texture* new_texture = manager2_->ConsumeTexture(name); |
+ EXPECT_EQ(kNewTextureId, new_texture->service_id()); |
+ |
+ // Clobber |
+ manager2_->ProduceTexture(name, texture2); |
+ manager_->ProduceTexture(name, texture1); |
+ |
+ // Synchronize manager -> manager2 |
+ manager_->PushTextureUpdates(0); |
+ manager2_->PullTextureUpdates(0); |
+ |
+ // name should return the original texture, and not texture2 or a new one. |
+ EXPECT_EQ(new_texture, manager2_->ConsumeTexture(name)); |
+ |
+ DestroyTexture(texture1); |
+ DestroyTexture(texture2); |
+ DestroyTexture(new_texture); |
+} |
// TODO: Produce incomplete texture |