diff options
author | dyen <dyen@chromium.org> | 2015-02-24 21:24:31 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-25 05:25:25 +0000 |
commit | c6a36cdd86305aa691641fcfd6ded5a571510834 (patch) | |
tree | b833fa48f13f0649b88eeede0daab620689842ec /gpu | |
parent | 586e3dbe02974966b7a3adaf0aebfbcc4d6983ba (diff) | |
download | chromium_src-c6a36cdd86305aa691641fcfd6ded5a571510834.zip chromium_src-c6a36cdd86305aa691641fcfd6ded5a571510834.tar.gz chromium_src-c6a36cdd86305aa691641fcfd6ded5a571510834.tar.bz2 |
Compile shader upon deletion if attached.
R=kbr@chromium.org, vmiura@chromium.org
BUG=459778
TEST=chromote locally with enableVideoDecodeRenderer
Review URL: https://codereview.chromium.org/954073002
Cr-Commit-Position: refs/heads/master@{#317985}
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 3 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_manager.cc | 16 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_manager.h | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_manager_unittest.cc | 25 | ||||
-rw-r--r-- | gpu/command_buffer/tests/gl_program_unittest.cc | 33 |
5 files changed, 65 insertions, 16 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 6b254e0..e61dc22 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -5133,8 +5133,7 @@ error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size, Shader* shader = GetShader(client_id); if (shader) { if (!shader->IsDeleted()) { - glDeleteShader(shader->service_id()); - shader_manager()->MarkAsDeleted(shader); + shader_manager()->Delete(shader); } } else { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader"); diff --git a/gpu/command_buffer/service/shader_manager.cc b/gpu/command_buffer/service/shader_manager.cc index d88a628..fa07180 100644 --- a/gpu/command_buffer/service/shader_manager.cc +++ b/gpu/command_buffer/service/shader_manager.cc @@ -133,8 +133,13 @@ void Shader::DecUseCount() { DCHECK_GE(use_count_, 0); } -void Shader::MarkAsDeleted() { +void Shader::Delete() { + if (use_count_ > 0) { + // If attached, compile the shader before we delete it. + DoCompile(); + } DCHECK_NE(service_id_, 0u); + glDeleteShader(service_id_); service_id_ = 0; } @@ -185,8 +190,7 @@ void ShaderManager::Destroy(bool have_context) { if (have_context) { Shader* shader = shaders_.begin()->second.get(); if (!shader->IsDeleted()) { - glDeleteShader(shader->service_id()); - shader->MarkAsDeleted(); + shader->Delete(); } } shaders_.erase(shaders_.begin()); @@ -247,10 +251,10 @@ void ShaderManager::RemoveShader(Shader* shader) { } } -void ShaderManager::MarkAsDeleted(Shader* shader) { +void ShaderManager::Delete(Shader* shader) { DCHECK(shader); DCHECK(IsOwned(shader)); - shader->MarkAsDeleted(); + shader->Delete(); RemoveShader(shader); } @@ -269,5 +273,3 @@ void ShaderManager::UnuseShader(Shader* shader) { } // namespace gles2 } // namespace gpu - - diff --git a/gpu/command_buffer/service/shader_manager.h b/gpu/command_buffer/service/shader_manager.h index 82fd288..2fbe0dc 100644 --- a/gpu/command_buffer/service/shader_manager.h +++ b/gpu/command_buffer/service/shader_manager.h @@ -147,7 +147,7 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { void IncUseCount(); void DecUseCount(); - void MarkAsDeleted(); + void Delete(); int use_count_; @@ -215,7 +215,7 @@ class GPU_EXPORT ShaderManager { // Gets a client id for a given service id. bool GetClientId(GLuint service_id, GLuint* client_id) const; - void MarkAsDeleted(Shader* shader); + void Delete(Shader* shader); // Mark a shader as used void UseShader(Shader* shader); diff --git a/gpu/command_buffer/service/shader_manager_unittest.cc b/gpu/command_buffer/service/shader_manager_unittest.cc index c46b734..88f4715 100644 --- a/gpu/command_buffer/service/shader_manager_unittest.cc +++ b/gpu/command_buffer/service/shader_manager_unittest.cc @@ -43,7 +43,10 @@ TEST_F(ShaderManagerTest, Basic) { // Check we get nothing for a non-existent shader. EXPECT_TRUE(manager_.GetShader(kClient2Id) == NULL); // Check we can't get the shader after we remove it. - manager_.MarkAsDeleted(shader1); + EXPECT_CALL(*gl_, DeleteShader(kService1Id)) + .Times(1) + .RetiresOnSaturation(); + manager_.Delete(shader1); EXPECT_TRUE(manager_.GetShader(kClient1Id) == NULL); } @@ -79,8 +82,14 @@ TEST_F(ShaderManagerTest, DeleteBug) { ASSERT_TRUE(shader1.get()); ASSERT_TRUE(shader2.get()); manager_.UseShader(shader1.get()); - manager_.MarkAsDeleted(shader1.get()); - manager_.MarkAsDeleted(shader2.get()); + EXPECT_CALL(*gl_, DeleteShader(kService1Id)) + .Times(1) + .RetiresOnSaturation(); + manager_.Delete(shader1.get()); + EXPECT_CALL(*gl_, DeleteShader(kService2Id)) + .Times(1) + .RetiresOnSaturation(); + manager_.Delete(shader2.get()); EXPECT_TRUE(manager_.IsOwned(shader1.get())); EXPECT_FALSE(manager_.IsOwned(shader2.get())); } @@ -249,7 +258,10 @@ TEST_F(ShaderManagerTest, ShaderInfoUseCount) { EXPECT_TRUE(shader1->InUse()); manager_.UseShader(shader1); EXPECT_TRUE(shader1->InUse()); - manager_.MarkAsDeleted(shader1); + EXPECT_CALL(*gl_, DeleteShader(kService1Id)) + .Times(1) + .RetiresOnSaturation(); + manager_.Delete(shader1); EXPECT_TRUE(shader1->IsDeleted()); Shader* shader2 = manager_.GetShader(kClient1Id); EXPECT_EQ(shader1, shader2); @@ -272,7 +284,10 @@ TEST_F(ShaderManagerTest, ShaderInfoUseCount) { EXPECT_FALSE(shader1->InUse()); shader2 = manager_.GetShader(kClient1Id); EXPECT_EQ(shader1, shader2); - manager_.MarkAsDeleted(shader1); // this should delete the shader. + EXPECT_CALL(*gl_, DeleteShader(kService1Id)) + .Times(1) + .RetiresOnSaturation(); + manager_.Delete(shader1); // this should delete the shader. shader2 = manager_.GetShader(kClient1Id); EXPECT_TRUE(shader2 == NULL); } diff --git a/gpu/command_buffer/tests/gl_program_unittest.cc b/gpu/command_buffer/tests/gl_program_unittest.cc index d243994..c0abb12 100644 --- a/gpu/command_buffer/tests/gl_program_unittest.cc +++ b/gpu/command_buffer/tests/gl_program_unittest.cc @@ -251,5 +251,38 @@ TEST_F(GLProgramTest, DeferCompileWithExt) { EXPECT_NE(0u, program_good2); } +TEST_F(GLProgramTest, DeleteAttachedShaderLinks) { + static const char* v_shdr_str = R"( + attribute vec4 vPosition; + void main() + { + gl_Position = vPosition; + } + )"; + static const char* f_shdr_str = R"( + void main() + { + gl_FragColor = vec4(1, 1, 1, 1); + } + )"; + + // Compiling the shaders, attaching, then deleting before linking should work. + GLuint vs = GLTestHelper::CompileShader(GL_VERTEX_SHADER, v_shdr_str); + GLuint fs = GLTestHelper::CompileShader(GL_FRAGMENT_SHADER, f_shdr_str); + + GLuint program = glCreateProgram(); + glAttachShader(program, vs); + glAttachShader(program, fs); + + glDeleteShader(vs); + glDeleteShader(fs); + + glLinkProgram(program); + + GLint linked = 0; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + EXPECT_NE(0, linked); +} + } // namespace gpu |