Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(925)

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc

Issue 12717013: Add reference-counting for mailbox textures. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 8d86800e65b17bc50043f6482774a43f8184f76a..47dac0ca60bbee2548ba5966bfd56dc8d4066148 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -7244,111 +7244,283 @@ TEST_F(GLES2DecoderTest, GenMailboxCHROMIUM) {
sizeof(zero)));
}
-TEST_F(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) {
- GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
- group().mailbox_manager()->GenerateMailboxName(
- reinterpret_cast<MailboxName*>(mailbox));
+class TextureMailboxTest : public GLES2DecoderTestBase {
+ public:
+ TextureMailboxTest()
+ : GLES2DecoderTestBase() {
+ }
- memcpy(shared_memory_address_, mailbox, sizeof(mailbox));
+ virtual void SetUp() {
+ GLES2DecoderTestBase::SetUp();
- DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
- DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
- 0, 0);
- DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
- 0, 0);
- Texture* texture = group().texture_manager()->GetTexture(client_texture_id_);
- EXPECT_EQ(kServiceTextureId, texture->service_id());
+ // Register some extra texture ids.
+ RegisterTexture(kClientId1, kServiceId1);
+ RegisterTexture(kClientId2, kServiceId2);
+ RegisterTexture(kClientId3, kServiceId3);
+ }
- // Assigns and binds new service side texture ID.
- EXPECT_CALL(*gl_, GenTextures(1, _))
- .WillOnce(SetArgumentPointee<1>(kNewServiceId))
- .RetiresOnSaturation();
- EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kNewServiceId))
- .Times(1)
- .RetiresOnSaturation();
+ protected:
+ MailboxName ProduceTexture() {
+ MailboxName mailbox;
+ group().mailbox_manager()->GenerateMailboxName(&mailbox);
+ memcpy(shared_memory_address_, &mailbox, sizeof(mailbox));
+ ProduceTextureCHROMIUM produce_cmd;
+ produce_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(produce_cmd));
+ return mailbox;
+ }
- ProduceTextureCHROMIUM produce_cmd;
- produce_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
- EXPECT_EQ(error::kNoError, ExecuteCmd(produce_cmd));
+ void ConsumeTexture(
+ const MailboxName& mailbox, GLuint old_texture, GLuint new_texture) {
+ if (old_texture != new_texture) {
+ // TextureManager::Restore will set TexParameters.
+ EXPECT_CALL(*gl_, TexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, TexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, TexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, TexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT))
+ .Times(1)
+ .RetiresOnSaturation();
+#if 0
+ EXPECT_CALL(*gl_, TexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_NONE))
+ .Times(1)
+ .RetiresOnSaturation();
+#endif
+ // Assigns and binds original service size texture ID.
+ EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(old_texture)))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, new_texture))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
- // Texture is zero-by-zero.
- GLsizei width;
- GLsizei height;
- GLenum type;
- GLenum internal_format;
+ memcpy(shared_memory_address_, &mailbox, sizeof(mailbox));
+ ConsumeTextureCHROMIUM consume_cmd;
+ consume_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(consume_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ ::testing::Mock::VerifyAndClearExpectations(gl_.get());
+ }
- EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
- EXPECT_EQ(0, width);
- EXPECT_EQ(0, height);
- EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
- EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
- EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+ void VerifyLevel(Texture* texture, GLint level, GLint width, GLint height,
+ GLenum type, GLenum format) {
+ GLint w, h;
+ EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, level, &w, &h));
+ EXPECT_EQ(w, width);
+ EXPECT_EQ(h, height);
+ GLenum t, f;
+ EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, level, &t, &f));
+ EXPECT_EQ(static_cast<GLenum>(type), t);
+ EXPECT_EQ(static_cast<GLenum>(format), f);
+ }
- EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
- EXPECT_EQ(0, width);
- EXPECT_EQ(0, height);
- EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
- EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
- EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+ static const GLuint kClientId1;
+ static const GLuint kServiceId1;
+ static const GLuint kClientId2;
+ static const GLuint kServiceId2;
+ static const GLuint kClientId3;
+ static const GLuint kServiceId3;
- // Service ID has changed.
- EXPECT_EQ(kNewServiceId, texture->service_id());
+ private:
+ void RegisterTexture(GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, GenTextures(_, _))
+ .WillOnce(SetArgumentPointee<1>(service_id))
+ .RetiresOnSaturation();
+ GenHelper<GenTexturesImmediate>(client_id);
+ Texture* texture = group().texture_manager()->GetTexture(client_id);
+ EXPECT_EQ(service_id, texture->service_id());
+ }
+};
- // Assigns and binds original service size texture ID.
- EXPECT_CALL(*gl_, DeleteTextures(1, _))
- .Times(1)
- .RetiresOnSaturation();
- EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
- .Times(1)
- .RetiresOnSaturation();
+const GLuint TextureMailboxTest::kClientId1 = 4100;
+const GLuint TextureMailboxTest::kServiceId1 = 4101;
+const GLuint TextureMailboxTest::kClientId2 = 4102;
+const GLuint TextureMailboxTest::kServiceId2 = 4103;
+const GLuint TextureMailboxTest::kClientId3 = 4104;
+const GLuint TextureMailboxTest::kServiceId3 = 4105;
+
+// Produces and consumes a texture back into the same client texture.
+TEST_F(TextureMailboxTest, ProduceAndConsumeToSameTexture) {
+ GLsizei level0_width = 3;
+ GLsizei level0_height = 1;
+ GLenum type = GL_UNSIGNED_BYTE;
+ GLenum format = GL_RGBA;
- // TextureManager::Restore will set TexParameters.
- EXPECT_CALL(*gl_, TexParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR))
- .Times(1)
- .RetiresOnSaturation();
- EXPECT_CALL(*gl_, TexParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
- .Times(1)
- .RetiresOnSaturation();
- EXPECT_CALL(*gl_, TexParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT))
- .Times(1)
- .RetiresOnSaturation();
- EXPECT_CALL(*gl_, TexParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT))
- .Times(1)
- .RetiresOnSaturation();
- #if 0
- EXPECT_CALL(*gl_, TexParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_NONE))
- .Times(1)
- .RetiresOnSaturation();
- #endif
+ DoBindTexture(GL_TEXTURE_2D, kClientId1, kServiceId1);
+ DoTexImage2D(GL_TEXTURE_2D, 0, format, level0_width, level0_height,
+ 0, format, type, 0, 0);
+ Texture* texture = group().texture_manager()->GetTexture(kClientId1);
+ EXPECT_FALSE(texture->IsImmutable());
+
+ MailboxName mailbox = ProduceTexture();
+
+ VerifyLevel(texture, 0, level0_width, level0_height, type, format);
+
+ // The texture is the same but has become immutable.
+ EXPECT_EQ(kServiceId1, texture->service_id());
+ EXPECT_TRUE(texture->IsImmutable());
- ConsumeTextureCHROMIUM consume_cmd;
- consume_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
- EXPECT_EQ(error::kNoError, ExecuteCmd(consume_cmd));
+ ConsumeTexture(mailbox, kServiceId1, kServiceId1);
+
+ // Texture is unchanged but mutable.
+ VerifyLevel(texture, 0, level0_width, level0_height, type, format);
+ EXPECT_EQ(kServiceId1, texture->service_id());
+ EXPECT_FALSE(texture->IsImmutable());
+
+ DoDeleteTexture(kClientId1, kServiceId1);
+
+ // The texture should have been removed from the mailbox.
+ EXPECT_TRUE(group().mailbox_manager()->
+ ConsumeTexture(GL_TEXTURE_2D, mailbox) == NULL);
+}
+
+// Produces and consumes two textures between two clients.
+TEST_F(TextureMailboxTest, ProduceAndConsumeTextures) {
+ const GLsizei level0_width = 3;
+ const GLsizei level0_height = 1;
+ const GLsizei level1_width = 2;
+ const GLsizei level1_height = 4;
+ const GLenum type = GL_UNSIGNED_BYTE;
+ const GLenum format = GL_RGBA;
+
+ // Produce a texture with two levels.
+ DoBindTexture(GL_TEXTURE_2D, kClientId1, kServiceId1);
+ DoTexImage2D(GL_TEXTURE_2D, 0, format, level0_width, level0_height,
+ 0, format, type, 0, 0);
+ DoTexImage2D(GL_TEXTURE_2D, 1, format, level1_width, level1_height,
+ 0, format, type, 0, 0);
+ MailboxName mailbox1 = ProduceTexture();
+
+ // Produce a second 16x16 texture.
+ DoBindTexture(GL_TEXTURE_2D, kClientId2, kServiceId2);
+ DoTexImage2D(GL_TEXTURE_2D, 0, format, 16, 16,
+ 0, format, type, 0, 0);
+ MailboxName mailbox2 = ProduceTexture();
+
+ // Consume the first texture.
+ DoBindTexture(GL_TEXTURE_2D, kClientId3, kServiceId3);
+ ConsumeTexture(mailbox1, kServiceId3, kServiceId1);
+ Texture* texture = group().texture_manager()->GetTexture(kClientId3);
+ EXPECT_FALSE(texture->IsImmutable());
+
+ // The textures should have been removed from the mailbox.
+ EXPECT_TRUE(group().mailbox_manager()->
+ ConsumeTexture(GL_TEXTURE_2D, mailbox1) == NULL);
+
+ // Delete the producer texture now and make sure it still gets cleaned up
+ // correctly from the consumer.
+ cmds::DeleteTextures cmd;
+ cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+ memcpy(shared_memory_address_, &kClientId1, sizeof(kClientId1));
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
// Texture is redefined.
- EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
- EXPECT_EQ(3, width);
- EXPECT_EQ(1, height);
- EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
- EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
- EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+ VerifyLevel(texture, 0, level0_width, level0_height, type, format);
+ VerifyLevel(texture, 1, level1_width, level1_height, type, format);
- EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
- EXPECT_EQ(2, width);
- EXPECT_EQ(4, height);
- EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
- EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
- EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+ // Service ID is unchanged.
+ EXPECT_EQ(kServiceId1, texture->service_id());
- // Service ID is restored.
- EXPECT_EQ(kServiceTextureId, texture->service_id());
+ // Consume the second texture.
+ ConsumeTexture(mailbox2, kServiceId1, kServiceId2);
+ VerifyLevel(texture, 0, 16, 16, type, format);
+ VerifyLevel(texture, 1, 0, 0, 0, 0);
+
+ // The textures should have been removed from the mailbox.
+ EXPECT_TRUE(group().mailbox_manager()->
+ ConsumeTexture(GL_TEXTURE_2D, mailbox2) == NULL);
+
+ // Delete the producer client texture. The actual texture will not be
+ // deleted yet.
+ cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+ memcpy(shared_memory_address_, &kClientId2, sizeof(kClientId2));
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+ // Deleting the consumer-side client texure causes the actual texture to be
+ // deleted.
+ DoDeleteTexture(kClientId3, kServiceId2);
}
+// Produces and consumes a texture back and forth between two clients.
+TEST_F(TextureMailboxTest, PingPongTexture) {
+ const GLsizei width = 2;
+ const GLsizei height = 4;
+ const GLenum type = GL_UNSIGNED_BYTE;
+ const GLenum format = GL_RGBA;
+
+ // Produce a texture from client1.
+ DoBindTexture(GL_TEXTURE_2D, kClientId1, kServiceId1);
+ DoTexImage2D(GL_TEXTURE_2D, 0, format, width, height,
+ 0, format, type, 0, 0);
+ MailboxName mailbox1 = ProduceTexture();
+
+ // Consume the texture from client2.
+ DoBindTexture(GL_TEXTURE_2D, kClientId2, kServiceId2);
+ ConsumeTexture(mailbox1, kServiceId2, kServiceId1);
+
+ // The textures should have been removed from the mailbox.
+ EXPECT_TRUE(group().mailbox_manager()->
+ ConsumeTexture(GL_TEXTURE_2D, mailbox1) == NULL);
+
+ // Produce it into a new mailbox.
+ MailboxName mailbox2 = ProduceTexture();
+ Texture* texture = group().texture_manager()->GetTexture(kClientId2);
+ EXPECT_EQ(kServiceId1, texture->service_id());
+ EXPECT_TRUE(texture->IsImmutable());
+
+ // Consume the texture back from client1.
+ DoBindTexture(GL_TEXTURE_2D, kClientId1, kServiceId1);
+ ConsumeTexture(mailbox2, kServiceId1, kServiceId1);
+ texture = group().texture_manager()->GetTexture(kClientId1);
+ EXPECT_FALSE(texture->IsImmutable());
+ VerifyLevel(texture, 0, width, height, type, format);
+
+ // The textures should have been removed from the mailbox.
+ EXPECT_TRUE(group().mailbox_manager()->
+ ConsumeTexture(GL_TEXTURE_2D, mailbox2) == NULL);
+
+ // Delete the read-only side client texture.
+ cmds::DeleteTextures cmd;
+ cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+ memcpy(shared_memory_address_, &kClientId2, sizeof(kClientId2));
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+ // Delete the other texture, which causes it to be deleted.
+ DoDeleteTexture(kClientId1, kServiceId1);
+}
+
+// Produces a texture but deletes it before it gets consumed from the mailbox.
+TEST_F(TextureMailboxTest, ProduceAndDeleteTexture) {
+ GLsizei width = 3;
+ GLsizei height = 1;
+ GLenum type = GL_UNSIGNED_BYTE;
+ GLenum format = GL_RGBA;
+
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, format, width, height,
+ 0, format, type, 0, 0);
+
+ MailboxName mailbox = ProduceTexture();
+
+ // Deleting the consumer-side client texure causes the actual texture to be
+ // deleted.
+ DoDeleteTexture(client_texture_id_, kServiceTextureId);
+
+ // The texture should have been removed from the mailbox.
+ EXPECT_TRUE(group().mailbox_manager()->
+ ConsumeTexture(GL_TEXTURE_2D, mailbox) == NULL);
+}
TEST_F(GLES2DecoderTest, CanChangeSurface) {
scoped_refptr<GLSurfaceMock> other_surface(new GLSurfaceMock);

Powered by Google App Engine
This is Rietveld 408576698