diff options
author | boliu <boliu@chromium.org> | 2015-01-29 15:00:37 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-29 23:01:33 +0000 |
commit | 2f4ff4807f5d7805a5658ceb7ba71072152ea6c9 (patch) | |
tree | ddfd1b1858152265e8c771ddf9f6c73e26fd8452 /gpu | |
parent | 044dfb80b1f612f3c84b35182db0f9b4d93e086c (diff) | |
download | chromium_src-2f4ff4807f5d7805a5658ceb7ba71072152ea6c9.zip chromium_src-2f4ff4807f5d7805a5658ceb7ba71072152ea6c9.tar.gz chromium_src-2f4ff4807f5d7805a5658ceb7ba71072152ea6c9.tar.bz2 |
Correctly track texture cleared state for sharing
When sharing textures in mailboxes using MailboxManagerSync
there's an optimization that if textures are not updated then
there is no need to share it again. However the code that
checks whether textures are updated ignores the cleared
state, causing shared texture to remain uncleared
indefinitely.
Fix by check the cleared state. And add a unit test.
BUG=453199
Review URL: https://codereview.chromium.org/890453002
Cr-Commit-Position: refs/heads/master@{#313814}
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/mailbox_manager_unittest.cc | 52 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_definition.cc | 14 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_definition.h | 2 |
3 files changed, 67 insertions, 1 deletions
diff --git a/gpu/command_buffer/service/mailbox_manager_unittest.cc b/gpu/command_buffer/service/mailbox_manager_unittest.cc index 231193f..388e1da 100644 --- a/gpu/command_buffer/service/mailbox_manager_unittest.cc +++ b/gpu/command_buffer/service/mailbox_manager_unittest.cc @@ -72,6 +72,13 @@ class MailboxManagerTest : public GpuServiceTest { cleared); } + void SetLevelCleared(Texture* texture, + GLenum target, + GLint level, + bool cleared) { + texture->SetLevelCleared(target, level, cleared); + } + GLenum SetParameter(Texture* texture, GLenum pname, GLint param) { return texture->SetParameteri(feature_info_.get(), pname, param); } @@ -543,6 +550,51 @@ TEST_F(MailboxManagerSyncTest, ProduceAndClobber) { EXPECT_EQ(NULL, manager2_->ConsumeTexture(name)); } +TEST_F(MailboxManagerSyncTest, ClearedStateSynced) { + const GLuint kNewTextureId = 1234; + + Texture* texture = DefineTexture(); + EXPECT_TRUE(texture->SafeToRenderFrom()); + + 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()); + EXPECT_TRUE(texture->SafeToRenderFrom()); + + // Change cleared to false. + SetLevelCleared(texture, texture->target(), 0, false); + EXPECT_FALSE(texture->SafeToRenderFrom()); + + // Synchronize + manager_->PushTextureUpdates(0); + SetupUpdateTexParamExpectations( + kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); + manager2_->PullTextureUpdates(0); + + // Cleared state should be synced. + EXPECT_FALSE(new_texture->SafeToRenderFrom()); + + 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) { diff --git a/gpu/command_buffer/service/texture_definition.cc b/gpu/command_buffer/service/texture_definition.cc index edd4271..7af662c 100644 --- a/gpu/command_buffer/service/texture_definition.cc +++ b/gpu/command_buffer/service/texture_definition.cc @@ -413,7 +413,8 @@ bool TextureDefinition::Matches(const Texture* texture) const { if (texture->min_filter_ != min_filter_ || texture->mag_filter_ != mag_filter_ || texture->wrap_s_ != wrap_s_ || - texture->wrap_t_ != wrap_t_) { + texture->wrap_t_ != wrap_t_ || + texture->SafeToRenderFrom() != SafeToRenderFrom()) { return false; } @@ -424,5 +425,16 @@ bool TextureDefinition::Matches(const Texture* texture) const { return true; } +bool TextureDefinition::SafeToRenderFrom() const { + for (const std::vector<LevelInfo>& face_info : level_infos_) { + for (const LevelInfo& level_info : face_info) { + if (!level_info.cleared) { + return false; + } + } + } + return true; +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/texture_definition.h b/gpu/command_buffer/service/texture_definition.h index ff891fc..95f0fa2 100644 --- a/gpu/command_buffer/service/texture_definition.h +++ b/gpu/command_buffer/service/texture_definition.h @@ -58,6 +58,8 @@ class TextureDefinition { scoped_refptr<NativeImageBuffer> image() const { return image_buffer_; } private: + bool SafeToRenderFrom() const; + struct LevelInfo { LevelInfo(GLenum target, GLenum internal_format, |