Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| index 6253cc8926112765af5d5e6094e9ae71d628564a..b9f8d613613fe1aa3cffb7a251850cbb7ccd486b 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -56,6 +56,7 @@ |
| #include "gpu/command_buffer/service/shader_translator.h" |
| #include "gpu/command_buffer/service/shader_translator_cache.h" |
| #include "gpu/command_buffer/service/texture_manager.h" |
| +#include "gpu/command_buffer/service/uniform_subscription_manager.h" |
| #include "gpu/command_buffer/service/vertex_array_manager.h" |
| #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
| #include "third_party/smhasher/src/City.h" |
| @@ -796,6 +797,10 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| ImageManager* image_manager() { return image_manager_.get(); } |
| + UniformSubscriptionManager* uniform_subscription_manager() { |
| + return uniform_subscription_manager_.get(); |
| + } |
| + |
| VertexArrayManager* vertex_array_manager() { |
| return vertex_array_manager_.get(); |
| } |
| @@ -958,6 +963,9 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key, |
| GLuint client_id); |
| + void DoSubscribeUniformCHROMIUM(GLint locaton, GLenum target); |
| + void DoPopulateSubscribedUniformsCHROMIUM(); |
| + |
| void DoBindTexImage2DCHROMIUM( |
| GLenum target, |
| GLint image_id); |
| @@ -1207,6 +1215,13 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| // of the draw operation are the same. |
| bool CheckDrawingFeedbackLoops(); |
| + // Checks if |api_type| is valid for the given uniform |
| + // If the api type is not valid generates the appropriate GL |
| + // error. Returns true if |api_type| is valid for the uniform |
| + bool CheckUniformForApiType(const Program::UniformInfo* info, |
| + const char* function_name, |
| + Program::UniformApiType api_type); |
| + |
| // Gets the type of a uniform for a location in the current program. Sets GL |
| // errors if the current program is not valid. Returns true if the current |
| // program is valid and the location exists. Adjusts count so it |
| @@ -1218,6 +1233,9 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| GLenum* type, |
| GLsizei* count); |
| + // Populate subscribed uniforms for program specified by |client_id| |
| + void PopulateSubscribedUniforms(GLuint client_id); |
| + |
| // Gets the service id for any simulated backbuffer fbo. |
| GLuint GetBackbufferServiceId() const; |
| @@ -1597,6 +1615,8 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| GLsizei width, GLsizei height, GLenum format, |
| Texture* texture); |
| + bool ValidateSubscribeUniform(GLint fake_location, GLenum target); |
| + |
| void RenderWarning(const char* filename, int line, const std::string& msg); |
| void PerformanceWarning( |
| const char* filename, int line, const std::string& msg); |
| @@ -1733,6 +1753,8 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| scoped_ptr<ImageManager> image_manager_; |
| + scoped_ptr<UniformSubscriptionManager> uniform_subscription_manager_; |
| + |
| base::Callback<void(gfx::Size, float)> resize_callback_; |
| WaitSyncPointCallback wait_sync_point_callback_; |
| @@ -2446,6 +2468,8 @@ bool GLES2DecoderImpl::Initialize( |
| image_manager_.reset(new ImageManager); |
| + uniform_subscription_manager_.reset(new UniformSubscriptionManager); |
| + |
| util_.set_num_compressed_texture_formats( |
| validators_->compressed_texture_format.GetValues().size()); |
| @@ -3530,6 +3554,11 @@ void GLES2DecoderImpl::Destroy(bool have_context) { |
| image_manager_.reset(); |
| } |
| + if (uniform_subscription_manager_.get()) { |
| + uniform_subscription_manager_->Destroy(have_context); |
| + uniform_subscription_manager_.reset(); |
| + } |
| + |
| offscreen_target_frame_buffer_.reset(); |
| offscreen_target_color_texture_.reset(); |
| offscreen_target_color_render_buffer_.reset(); |
| @@ -5755,6 +5784,7 @@ bool GLES2DecoderImpl::CheckCurrentProgramForUniform( |
| return location != -1; |
| } |
| + |
| bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() { |
| Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER); |
| if (!framebuffer) |
| @@ -5787,6 +5817,19 @@ bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() { |
| return false; |
| } |
| +bool GLES2DecoderImpl::CheckUniformForApiType( |
| + const Program::UniformInfo* info, |
| + const char* function_name, |
| + Program::UniformApiType api_type) { |
| + DCHECK(info); |
| + if ((api_type & info->accepts_api_type) == 0) { |
| + LOCAL_SET_GL_ERROR( |
| + GL_INVALID_OPERATION, function_name, "wrong uniform function for type"); |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| bool GLES2DecoderImpl::PrepForSetUniformByLocation( |
| GLint fake_location, |
| const char* function_name, |
| @@ -5810,11 +5853,7 @@ bool GLES2DecoderImpl::PrepForSetUniformByLocation( |
| GL_INVALID_OPERATION, function_name, "unknown location"); |
| return false; |
| } |
| - |
| - if ((api_type & info->accepts_api_type) == 0) { |
| - LOCAL_SET_GL_ERROR( |
| - GL_INVALID_OPERATION, function_name, |
| - "wrong uniform function for type"); |
| + if (!CheckUniformForApiType(info, function_name, api_type)) { |
| return false; |
| } |
| if (*count > 1 && !info->is_array) { |
| @@ -5830,6 +5869,15 @@ bool GLES2DecoderImpl::PrepForSetUniformByLocation( |
| return true; |
| } |
| +void GLES2DecoderImpl::PopulateSubscribedUniforms(GLuint client_id) { |
| + const UniformSubscriptionManager::ProgramSubscriptions* |
| + program_subscriptions = |
| + uniform_subscription_manager()->SubscriptionsForProgram(client_id); |
| + if (program_subscriptions) { |
| + // TODO(orglofch) |
| + } |
| +} |
| + |
| void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) { |
| GLenum type = 0; |
| GLsizei count = 1; |
| @@ -6090,6 +6138,7 @@ void GLES2DecoderImpl::DoUseProgram(GLuint program_id) { |
| program_manager()->UseProgram(state_.current_program.get()); |
| if (workarounds().clear_uniforms_before_first_program_use) |
| program_manager()->ClearUniforms(program); |
| + PopulateSubscribedUniforms(program_id); |
|
piman
2014/10/21 20:00:41
I think we'd want to populate the uniforms only on
orglofch
2014/10/22 23:10:21
Done. I added needs_update_subscriptions_ flag to
|
| } |
| } |
| @@ -10688,6 +10737,55 @@ void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target, |
| texture_ref = texture_manager()->Consume(client_id, texture); |
| } |
| +bool GLES2DecoderImpl::ValidateSubscribeUniform(GLint fake_location, |
| + GLenum target) { |
| + if (!CheckCurrentProgramForUniform(fake_location, |
| + "glSubscribeUniformCHROMIUM")) { |
| + return false; |
| + } |
| + GLint array_index = -1; |
| + GLint real_location = -1; |
| + const Program::UniformInfo* info = |
| + state_.current_program->GetUniformInfoByFakeLocation( |
| + fake_location, &real_location, &array_index); |
| + if (!info) { |
| + LOCAL_SET_GL_ERROR( |
| + GL_INVALID_OPERATION, "glSubscribeUniformCHROMIUM", "unknown location"); |
| + return false; |
| + } |
| + if (!CheckUniformForApiType( |
| + info, |
| + "glSubscribeUniformCHROMIUM", |
| + uniform_subscription_manager()->ApiTypeForTarget(target))) { |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +void GLES2DecoderImpl::DoSubscribeUniformCHROMIUM(GLint location, |
| + GLenum target) { |
| + TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoSubscribeUniformCHROMIUM"); |
| + if (!ValidateSubscribeUniform(location, target)) { |
| + return; |
| + } |
| + GLuint client_id; |
| + program_manager()->GetClientId(state_.current_program.get()->service_id(), |
| + &client_id); |
| + uniform_subscription_manager()->AddSubscription(client_id, location, target); |
| +} |
| + |
| +void GLES2DecoderImpl::DoPopulateSubscribedUniformsCHROMIUM() { |
| + TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoPopulateSubscribedUniformsCHROMIUM"); |
| + uniform_subscription_manager()->ActivateUniformSubscriptionState(); |
| + // Defer population of other programs until calls to DoUseProgram |
| + if (state_.current_program.get()) { |
| + GLuint client_id; |
| + program_manager()->GetClientId(state_.current_program.get()->service_id(), |
| + &client_id); |
| + PopulateSubscribedUniforms(client_id); |
| + } |
| +} |
| + |
| void GLES2DecoderImpl::DoInsertEventMarkerEXT( |
| GLsizei length, const GLchar* marker) { |
| if (!marker) { |