Commit c447acda authored by dmurph@chromium.org's avatar dmurph@chromium.org

Bug fixes for getTranslatedShader

Fixed the following bugs:
 * Getting the length of translated shader source failed on pending compilation
 * Getting the translated shader source failed on pending compilation
 * Getting the translated shader source after a new source is set

Small refactoring:
 * Put an enum in ShaderInfo for storing the compilation state

BUG=137758


Review URL: https://chromiumcodereview.appspot.com/10812002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147997 0039d316-1c4b-4281-b951-d872f2087c98
parent 34850f62
...@@ -1361,6 +1361,8 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, ...@@ -1361,6 +1361,8 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
surface_->DeferDraws(); surface_->DeferDraws();
} }
void ForceCompileShaderIfPending(ShaderManager::ShaderInfo* info);
// Generate a member function prototype for each command in an automated and // Generate a member function prototype for each command in an automated and
// typesafe way. // typesafe way.
#define GLES2_CMD_OP(name) \ #define GLES2_CMD_OP(name) \
...@@ -5125,6 +5127,25 @@ void GLES2DecoderImpl::PerformanceWarning(const std::string& msg) { ...@@ -5125,6 +5127,25 @@ void GLES2DecoderImpl::PerformanceWarning(const std::string& msg) {
LogMessage(std::string("PERFORMANCE WARNING: ") + msg); LogMessage(std::string("PERFORMANCE WARNING: ") + msg);
} }
void GLES2DecoderImpl::ForceCompileShaderIfPending(
ShaderManager::ShaderInfo* info) {
if (info->compilation_status() ==
ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE) {
ShaderTranslator* translator = NULL;
if (use_shader_translator_) {
translator = info->shader_type() == GL_VERTEX_SHADER ?
vertex_translator_.get() : fragment_translator_.get();
}
// We know there will be no errors, because we only defer compilation on
// shaders that were previously compiled successfully.
program_manager()->ForceCompileShader(info->deferred_compilation_source(),
info,
translator,
feature_info_);
}
}
void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() { void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() {
GLenum error; GLenum error;
while ((error = glGetError()) != GL_NO_ERROR) { while ((error = glGetError()) != GL_NO_ERROR) {
...@@ -5848,6 +5869,7 @@ void GLES2DecoderImpl::DoGetShaderiv( ...@@ -5848,6 +5869,7 @@ void GLES2DecoderImpl::DoGetShaderiv(
*params = info->log_info() ? info->log_info()->size() + 1 : 0; *params = info->log_info() ? info->log_info()->size() + 1 : 0;
return; return;
case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
ForceCompileShaderIfPending(info);
*params = info->translated_source() ? *params = info->translated_source() ?
info->translated_source()->size() + 1 : 0; info->translated_source()->size() + 1 : 0;
return; return;
...@@ -5885,6 +5907,7 @@ error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE( ...@@ -5885,6 +5907,7 @@ error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
bucket->SetSize(0); bucket->SetSize(0);
return error::kNoError; return error::kNoError;
} }
ForceCompileShaderIfPending(info);
bucket->SetFromString(info->translated_source() ? bucket->SetFromString(info->translated_source() ?
info->translated_source()->c_str() : NULL); info->translated_source()->c_str() : NULL);
......
...@@ -489,7 +489,8 @@ bool ProgramManager::ProgramInfo::Link(ShaderManager* manager, ...@@ -489,7 +489,8 @@ bool ProgramManager::ProgramInfo::Link(ShaderManager* manager,
const int kShaders = ProgramManager::ProgramInfo::kMaxAttachedShaders; const int kShaders = ProgramManager::ProgramInfo::kMaxAttachedShaders;
for (int i = 0; i < kShaders; ++i) { for (int i = 0; i < kShaders; ++i) {
ShaderManager::ShaderInfo* info = attached_shaders_[i].get(); ShaderManager::ShaderInfo* info = attached_shaders_[i].get();
if (!info->source_compiled()) { if (info->compilation_status() ==
ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE) {
ShaderTranslator* translator = ShaderIndexToTranslator( ShaderTranslator* translator = ShaderIndexToTranslator(
i, i,
vertex_translator, vertex_translator,
......
...@@ -352,13 +352,13 @@ class GPU_EXPORT ProgramManager { ...@@ -352,13 +352,13 @@ class GPU_EXPORT ProgramManager {
ShaderTranslator* translator, ShaderTranslator* translator,
FeatureInfo* feature_info); FeatureInfo* feature_info);
private:
// Actually compiles the shader // Actually compiles the shader
void ForceCompileShader(const std::string* source, void ForceCompileShader(const std::string* source,
ShaderManager::ShaderInfo* info, ShaderManager::ShaderInfo* info,
ShaderTranslator* translator, ShaderTranslator* translator,
FeatureInfo* feature_info); FeatureInfo* feature_info);
private:
void StartTracking(ProgramInfo* info); void StartTracking(ProgramInfo* info);
void StopTracking(ProgramInfo* info); void StopTracking(ProgramInfo* info);
......
...@@ -1383,13 +1383,17 @@ TEST_F(ProgramManagerWithCacheTest, CorrectCompileOnSourceChangeNoCompile) { ...@@ -1383,13 +1383,17 @@ TEST_F(ProgramManagerWithCacheTest, CorrectCompileOnSourceChangeNoCompile) {
SetExpectationsForNoCompile(new_vertex_shader); SetExpectationsForNoCompile(new_vertex_shader);
manager_.DoCompileShader(new_vertex_shader, NULL, NULL); manager_.DoCompileShader(new_vertex_shader, NULL, NULL);
EXPECT_EQ(ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE,
new_vertex_shader->compilation_status());
new_vertex_shader->UpdateSource("different!"); new_vertex_shader->UpdateSource("different!");
EXPECT_EQ(original_source, EXPECT_EQ(original_source,
*new_vertex_shader->deferred_compilation_source()); *new_vertex_shader->deferred_compilation_source());
EXPECT_FALSE(new_vertex_shader->source_compiled()); EXPECT_EQ(ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE,
EXPECT_FALSE(fragment_shader_->source_compiled()); new_vertex_shader->compilation_status());
EXPECT_EQ(ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE,
fragment_shader_->compilation_status());
SetExpectationsForNoCompile(fragment_shader_); SetExpectationsForNoCompile(fragment_shader_);
SetExpectationsForNotCachingProgram(program_info, SetExpectationsForNotCachingProgram(program_info,
...@@ -1441,8 +1445,10 @@ TEST_F(ProgramManagerWithCacheTest, CorrectCompileOnSourceChangeWithCompile) { ...@@ -1441,8 +1445,10 @@ TEST_F(ProgramManagerWithCacheTest, CorrectCompileOnSourceChangeWithCompile) {
EXPECT_EQ(differentSource, EXPECT_EQ(differentSource,
*new_vertex_shader->deferred_compilation_source()); *new_vertex_shader->deferred_compilation_source());
EXPECT_TRUE(new_vertex_shader->source_compiled()); EXPECT_EQ(ShaderManager::ShaderInfo::COMPILED,
EXPECT_FALSE(fragment_shader_->source_compiled()); new_vertex_shader->compilation_status());
EXPECT_EQ(ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE,
fragment_shader_->compilation_status());
// so we don't recompile because we were pending originally // so we don't recompile because we were pending originally
SetExpectationsForNoCompile(new_vertex_shader); SetExpectationsForNoCompile(new_vertex_shader);
......
...@@ -17,7 +17,7 @@ ShaderManager::ShaderInfo::ShaderInfo(GLuint service_id, GLenum shader_type) ...@@ -17,7 +17,7 @@ ShaderManager::ShaderInfo::ShaderInfo(GLuint service_id, GLenum shader_type)
service_id_(service_id), service_id_(service_id),
shader_type_(shader_type), shader_type_(shader_type),
valid_(false), valid_(false),
source_compiled_(false) { compilation_status_(NOT_COMPILED) {
} }
ShaderManager::ShaderInfo::~ShaderInfo() { ShaderManager::ShaderInfo::~ShaderInfo() {
......
...@@ -33,6 +33,13 @@ class GPU_EXPORT ShaderManager { ...@@ -33,6 +33,13 @@ class GPU_EXPORT ShaderManager {
typedef scoped_refptr<ShaderInfo> Ref; typedef scoped_refptr<ShaderInfo> Ref;
typedef ShaderTranslator::VariableInfo VariableInfo; typedef ShaderTranslator::VariableInfo VariableInfo;
enum CompilationStatus {
NOT_COMPILED,
// We're pending compilation for a cache hit with the program cache.
PENDING_DEFERRED_COMPILE,
COMPILED
};
void UpdateSource(const char* source) { void UpdateSource(const char* source) {
// If the source is flagged as compiled, then store our previous source // If the source is flagged as compiled, then store our previous source
// for deferred compile and caching. // for deferred compile and caching.
...@@ -40,7 +47,6 @@ class GPU_EXPORT ShaderManager { ...@@ -40,7 +47,6 @@ class GPU_EXPORT ShaderManager {
deferred_compilation_source_.reset(source_.release()); deferred_compilation_source_.reset(source_.release());
} }
source_.reset(source ? new std::string(source) : NULL); source_.reset(source ? new std::string(source) : NULL);
translated_source_.reset(NULL);
} }
void UpdateTranslatedSource(const char* translated_source) { void UpdateTranslatedSource(const char* translated_source) {
...@@ -68,9 +74,8 @@ class GPU_EXPORT ShaderManager { ...@@ -68,9 +74,8 @@ class GPU_EXPORT ShaderManager {
bool valid, const char* log, bool valid, const char* log,
ShaderTranslatorInterface* translator); ShaderTranslatorInterface* translator);
// If the source was actually compiled (compilation wasn't deferred) CompilationStatus compilation_status() const {
bool source_compiled() const { return compilation_status_;
return source_compiled_;
} }
// The source that was used when the user called CompileShader. // The source that was used when the user called CompileShader.
...@@ -84,7 +89,9 @@ class GPU_EXPORT ShaderManager { ...@@ -84,7 +89,9 @@ class GPU_EXPORT ShaderManager {
// Resets our deferred compilation source and stores if the source was // Resets our deferred compilation source and stores if the source was
// actually compiled, or if we're expecting a cache hit // actually compiled, or if we're expecting a cache hit
void FlagSourceAsCompiled(bool actually_compiled) { void FlagSourceAsCompiled(bool actually_compiled) {
source_compiled_ = actually_compiled; compilation_status_ = actually_compiled ?
COMPILED :
PENDING_DEFERRED_COMPILE;
deferred_compilation_source_.reset(); deferred_compilation_source_.reset();
} }
...@@ -170,9 +177,8 @@ class GPU_EXPORT ShaderManager { ...@@ -170,9 +177,8 @@ class GPU_EXPORT ShaderManager {
VariableMap attrib_map_; VariableMap attrib_map_;
VariableMap uniform_map_; VariableMap uniform_map_;
// If the source was actually compiled (otherwise we're deferring // The current compilation status of the shader
// compilation because of a possible cache hit) CompilationStatus compilation_status_;
bool source_compiled_;
// Holds on to the source for a deferred compile. // Holds on to the source for a deferred compile.
scoped_ptr<std::string> deferred_compilation_source_; scoped_ptr<std::string> deferred_compilation_source_;
......
...@@ -253,11 +253,17 @@ TEST_F(ShaderManagerTest, ShaderInfoStoreCompilationStatus) { ...@@ -253,11 +253,17 @@ TEST_F(ShaderManagerTest, ShaderInfoStoreCompilationStatus) {
kClientId, kServiceId, kShaderType); kClientId, kServiceId, kShaderType);
ASSERT_TRUE(info != NULL); ASSERT_TRUE(info != NULL);
EXPECT_EQ(ShaderManager::ShaderInfo::NOT_COMPILED,
info->compilation_status());
info->UpdateSource("original source"); info->UpdateSource("original source");
EXPECT_EQ(ShaderManager::ShaderInfo::NOT_COMPILED,
info->compilation_status());
info->FlagSourceAsCompiled(false); info->FlagSourceAsCompiled(false);
EXPECT_FALSE(info->source_compiled()); EXPECT_EQ(ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE,
info->compilation_status());
info->FlagSourceAsCompiled(true); info->FlagSourceAsCompiled(true);
EXPECT_TRUE(info->source_compiled()); EXPECT_EQ(ShaderManager::ShaderInfo::COMPILED,
info->compilation_status());
} }
TEST_F(ShaderManagerTest, ShaderInfoStoreDeferredSource) { TEST_F(ShaderManagerTest, ShaderInfoStoreDeferredSource) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment