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) { |