| 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 0b8d68d80f362255cdd347cf5335a116dd0ed0b9..67cdf0aa7bb7438dccbc66154e4d209fda3fff8e 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -943,6 +943,10 @@ class GLES2DecoderImpl : public GLES2Decoder,
|
| void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
|
| GLuint client_id);
|
|
|
| + void DoSubscribeUniformCHROMIUM(GLint locaton, GLenum target);
|
| + void DoUnsubscribeUniformCHROMIUM(GLint location);
|
| + void DoPopulateSubscribedUniformsCHROMIUM();
|
| +
|
| void DoBindTexImage2DCHROMIUM(
|
| GLenum target,
|
| GLint image_id);
|
| @@ -1192,6 +1196,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
|
| @@ -1203,6 +1214,8 @@ class GLES2DecoderImpl : public GLES2Decoder,
|
| GLenum* type,
|
| GLsizei* count);
|
|
|
| + void PopulateSubscribedUniforms(Program* program);
|
| +
|
| // Gets the service id for any simulated backbuffer fbo.
|
| GLuint GetBackbufferServiceId() const;
|
|
|
| @@ -1582,6 +1595,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);
|
| @@ -5772,6 +5787,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,
|
| @@ -5795,11 +5823,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) {
|
| @@ -5815,6 +5839,16 @@ bool GLES2DecoderImpl::PrepForSetUniformByLocation(
|
| return true;
|
| }
|
|
|
| +void GLES2DecoderImpl::PopulateSubscribedUniforms(Program* program) {
|
| + const Program::SubscriptionMap& subscription_map =
|
| + program->subscription_map();
|
| + for (Program::SubscriptionMap::const_iterator it = subscription_map.begin();
|
| + it != subscription_map.end();
|
| + ++it) {
|
| + // TODO(orglofch):
|
| + }
|
| +}
|
| +
|
| void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
|
| GLenum type = 0;
|
| GLsizei count = 1;
|
| @@ -6075,6 +6109,9 @@ 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);
|
| + if (program->needs_update_subscriptions()) {
|
| + PopulateSubscribedUniforms(program);
|
| + }
|
| }
|
| }
|
|
|
| @@ -10673,6 +10710,63 @@ 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",
|
| + program_manager()->ApiTypeForSubscriptionTarget(target))) {
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +void GLES2DecoderImpl::DoSubscribeUniformCHROMIUM(GLint location,
|
| + GLenum target) {
|
| + TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoSubscribeUniformCHROMIUM");
|
| + if (!ValidateSubscribeUniform(location, target)) {
|
| + return;
|
| + }
|
| + if (state_.current_program.get()) {
|
| + state_.current_program.get()->AddSubscription(location, target);
|
| + }
|
| +}
|
| +
|
| +void GLES2DecoderImpl::DoUnsubscribeUniformCHROMIUM(GLint location) {
|
| + TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoUnsubscribeUniformCHROMIUM");
|
| + if (!CheckCurrentProgramForUniform(location,
|
| + "glUnsubscribeUniformCHROMIUM")) {
|
| + return;
|
| + }
|
| + if (state_.current_program.get()) {
|
| + state_.current_program.get()->RemoveSubscription(location);
|
| + }
|
| +}
|
| +
|
| +void GLES2DecoderImpl::DoPopulateSubscribedUniformsCHROMIUM() {
|
| + TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoPopulateSubscribedUniformsCHROMIUM");
|
| + program_manager()->ActivateUniformSubscriptionState();
|
| + // Defer population of other programs until calls to DoUseProgram
|
| + if (state_.current_program.get() &&
|
| + state_.current_program.get()->needs_update_subscriptions()) {
|
| + PopulateSubscribedUniforms(state_.current_program.get());
|
| + }
|
| +}
|
| +
|
| void GLES2DecoderImpl::DoInsertEventMarkerEXT(
|
| GLsizei length, const GLchar* marker) {
|
| if (!marker) {
|
|
|