summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordyen <dyen@chromium.org>2015-02-24 21:24:31 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-25 05:25:25 +0000
commitc6a36cdd86305aa691641fcfd6ded5a571510834 (patch)
treeb833fa48f13f0649b88eeede0daab620689842ec
parent586e3dbe02974966b7a3adaf0aebfbcc4d6983ba (diff)
downloadchromium_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}
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc3
-rw-r--r--gpu/command_buffer/service/shader_manager.cc16
-rw-r--r--gpu/command_buffer/service/shader_manager.h4
-rw-r--r--gpu/command_buffer/service/shader_manager_unittest.cc25
-rw-r--r--gpu/command_buffer/tests/gl_program_unittest.cc33
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