| 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 9b028fd494fd6f946d611875dcd00a10c917bc84..4d54739da5538081fa7d797233eeac0e9431ae54 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/valuebuffer_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"
|
| @@ -627,7 +628,7 @@ class GLES2DecoderImpl : public GLES2Decoder,
|
| return vertex_array_manager_.get();
|
| }
|
| ImageManager* GetImageManager() override { return image_manager_.get(); }
|
| - bool ProcessPendingQueries() override;
|
| + bool ProcessPendingQueries(bool did_finish) override;
|
| bool HasMoreIdleWork() override;
|
| void PerformIdleWork() override;
|
|
|
| @@ -727,6 +728,8 @@ class GLES2DecoderImpl : public GLES2Decoder,
|
| void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
|
| bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
|
| void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
|
| + bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
|
| + void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
|
| bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
|
| void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
|
| bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
|
| @@ -756,6 +759,10 @@ class GLES2DecoderImpl : public GLES2Decoder,
|
| return group_->framebuffer_manager();
|
| }
|
|
|
| + ValuebufferManager* valuebuffer_manager() {
|
| + return group_->valuebuffer_manager();
|
| + }
|
| +
|
| ProgramManager* program_manager() {
|
| return group_->program_manager();
|
| }
|
| @@ -944,6 +951,14 @@ class GLES2DecoderImpl : public GLES2Decoder,
|
| void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
|
| GLuint client_id);
|
|
|
| + bool DoIsValuebufferCHROMIUM(GLuint client_id);
|
| + void DoBindValueBufferCHROMIUM(GLenum target, GLuint valuebuffer);
|
| + void DoSubscribeValueCHROMIUM(GLenum target, GLenum subscription);
|
| + void DoPopulateSubscribedValuesCHROMIUM(GLenum target);
|
| + void DoUniformValueBufferCHROMIUM(GLint location,
|
| + GLenum target,
|
| + GLenum subscription);
|
| +
|
| void DoBindTexImage2DCHROMIUM(
|
| GLenum target,
|
| GLint image_id);
|
| @@ -1096,6 +1111,21 @@ class GLES2DecoderImpl : public GLES2Decoder,
|
| renderbuffer_manager()->RemoveRenderbuffer(client_id);
|
| }
|
|
|
| + // Creates a valuebuffer info for the given valuebuffer.
|
| + void CreateValuebuffer(GLuint client_id) {
|
| + return valuebuffer_manager()->CreateValuebuffer(client_id);
|
| + }
|
| +
|
| + // Gets the valuebuffer info for a given valuebuffer.
|
| + Valuebuffer* GetValuebuffer(GLuint client_id) {
|
| + return valuebuffer_manager()->GetValuebuffer(client_id);
|
| + }
|
| +
|
| + // Removes the valuebuffer info for the given valuebuffer.
|
| + void RemoveValuebuffer(GLuint client_id) {
|
| + valuebuffer_manager()->RemoveValuebuffer(client_id);
|
| + }
|
| +
|
| // Gets the vertex attrib manager for the given vertex array.
|
| VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
|
| VertexAttribManager* info =
|
| @@ -1177,6 +1207,22 @@ class GLES2DecoderImpl : public GLES2Decoder,
|
| GLenum target,
|
| const char* func_name);
|
|
|
| + // Check if the current valuebuffer exists and is valid. If not generates
|
| + // the appropriate GL error. Returns true if the current valuebuffer is in
|
| + // a usable state.
|
| + bool CheckCurrentValuebuffer(const char* function_name);
|
| +
|
| + // Check if the current valuebuffer exists and is valiud and that the
|
| + // value buffer is actually subscribed to the given subscription
|
| + bool CheckCurrentValuebufferForSubscription(GLenum subscription,
|
| + const char* function_name);
|
| +
|
| + // Check if the location can be used for the given subscription target. If not
|
| + // generates the appropriate GL error. Returns true if the location is usable
|
| + bool CheckSubscriptionTarget(GLint location,
|
| + GLenum subscription,
|
| + const char* function_name);
|
| +
|
| // Checks if the current program exists and is valid. If not generates the
|
| // appropriate GL error. Returns true if the current program is in a usable
|
| // state.
|
| @@ -1193,6 +1239,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
|
| @@ -2670,6 +2723,7 @@ bool GLES2DecoderImpl::Initialize(
|
| DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
| DoBindFramebuffer(GL_FRAMEBUFFER, 0);
|
| DoBindRenderbuffer(GL_RENDERBUFFER, 0);
|
| + DoBindValueBufferCHROMIUM(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, 0);
|
|
|
| bool call_gl_clear = !surfaceless_;
|
| #if defined(OS_ANDROID)
|
| @@ -2719,6 +2773,34 @@ Capabilities GLES2DecoderImpl::GetCapabilities() {
|
| DCHECK(initialized());
|
|
|
| Capabilities caps;
|
| + caps.VisitPrecisions([](GLenum shader, GLenum type,
|
| + Capabilities::ShaderPrecision* shader_precision) {
|
| + GLint range[2] = {0, 0};
|
| + GLint precision = 0;
|
| + GetShaderPrecisionFormatImpl(shader, type, range, &precision);
|
| + shader_precision->min_range = range[0];
|
| + shader_precision->max_range = range[1];
|
| + shader_precision->precision = precision;
|
| + });
|
| + DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
|
| + &caps.max_combined_texture_image_units);
|
| + DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size);
|
| + DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
|
| + &caps.max_fragment_uniform_vectors);
|
| + DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size);
|
| + DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units);
|
| + DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size);
|
| + DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors);
|
| + DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs);
|
| + DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
|
| + &caps.max_vertex_texture_image_units);
|
| + DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
|
| + &caps.max_vertex_uniform_vectors);
|
| + DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
|
| + &caps.num_compressed_texture_formats);
|
| + DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats);
|
| + DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
|
| + &caps.bind_generates_resource_chromium);
|
|
|
| caps.egl_image_external =
|
| feature_info_->feature_flags().oes_egl_image_external;
|
| @@ -2907,6 +2989,19 @@ bool GLES2DecoderImpl::GenRenderbuffersHelper(
|
| return true;
|
| }
|
|
|
| +bool GLES2DecoderImpl::GenValuebuffersCHROMIUMHelper(GLsizei n,
|
| + const GLuint* client_ids) {
|
| + for (GLsizei ii = 0; ii < n; ++ii) {
|
| + if (GetValuebuffer(client_ids[ii])) {
|
| + return false;
|
| + }
|
| + }
|
| + for (GLsizei ii = 0; ii < n; ++ii) {
|
| + CreateValuebuffer(client_ids[ii]);
|
| + }
|
| + return true;
|
| +}
|
| +
|
| bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
|
| for (GLsizei ii = 0; ii < n; ++ii) {
|
| if (GetTexture(client_ids[ii])) {
|
| @@ -2996,6 +3091,20 @@ void GLES2DecoderImpl::DeleteRenderbuffersHelper(
|
| }
|
| }
|
|
|
| +void GLES2DecoderImpl::DeleteValuebuffersCHROMIUMHelper(
|
| + GLsizei n,
|
| + const GLuint* client_ids) {
|
| + for (GLsizei ii = 0; ii < n; ++ii) {
|
| + Valuebuffer* valuebuffer = GetValuebuffer(client_ids[ii]);
|
| + if (valuebuffer) {
|
| + if (state_.bound_valuebuffer.get() == valuebuffer) {
|
| + state_.bound_valuebuffer = NULL;
|
| + }
|
| + RemoveValuebuffer(client_ids[ii]);
|
| + }
|
| + }
|
| +}
|
| +
|
| void GLES2DecoderImpl::DeleteTexturesHelper(
|
| GLsizei n, const GLuint* client_ids) {
|
| bool supports_separate_framebuffer_binds =
|
| @@ -3425,6 +3534,7 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
|
| framebuffer_state_.bound_read_framebuffer = NULL;
|
| framebuffer_state_.bound_draw_framebuffer = NULL;
|
| state_.bound_renderbuffer = NULL;
|
| + state_.bound_valuebuffer = NULL;
|
|
|
| if (offscreen_saved_color_texture_info_.get()) {
|
| DCHECK(offscreen_target_color_texture_);
|
| @@ -3916,12 +4026,12 @@ bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
|
| void GLES2DecoderImpl::DoFinish() {
|
| glFinish();
|
| ProcessPendingReadPixels();
|
| - ProcessPendingQueries();
|
| + ProcessPendingQueries(true);
|
| }
|
|
|
| void GLES2DecoderImpl::DoFlush() {
|
| glFlush();
|
| - ProcessPendingQueries();
|
| + ProcessPendingQueries(false);
|
| }
|
|
|
| void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
|
| @@ -5722,6 +5832,55 @@ void GLES2DecoderImpl::DoTexParameteriv(
|
| "glTexParameteriv", GetErrorState(), texture, pname, *params);
|
| }
|
|
|
| +bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
|
| + if (!state_.bound_valuebuffer.get()) {
|
| + // There is no valuebuffer bound
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
|
| + "no valuebuffer in use");
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
|
| + GLenum subscription,
|
| + const char* function_name) {
|
| + if (!CheckCurrentValuebuffer(function_name)) {
|
| + return false;
|
| + }
|
| + if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
|
| + // The valuebuffer is not subscribed to the target
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
|
| + "valuebuffer is not subscribed");
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
|
| + GLenum subscription,
|
| + const char* function_name) {
|
| + if (!CheckCurrentProgramForUniform(location, function_name)) {
|
| + return false;
|
| + }
|
| + GLint real_location = -1;
|
| + GLint array_index = -1;
|
| + const Program::UniformInfo* info =
|
| + state_.current_program->GetUniformInfoByFakeLocation(
|
| + location, &real_location, &array_index);
|
| + if (!info) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
|
| + return false;
|
| + }
|
| + if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
|
| + info->accepts_api_type) == 0) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
|
| + "wrong type for subscription");
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
|
| if (!state_.current_program.get()) {
|
| // The program does not exist.
|
| @@ -5777,6 +5936,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,
|
| @@ -5800,11 +5972,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) {
|
| @@ -7608,7 +7776,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
|
| }
|
| } else {
|
| if (async && features().use_async_readpixels) {
|
| - GLuint buffer;
|
| + GLuint buffer = 0;
|
| glGenBuffersARB(1, &buffer);
|
| glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
|
| glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
|
| @@ -7627,6 +7795,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
|
| } else {
|
| // On error, unbind pack buffer and fall through to sync readpixels
|
| glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
|
| + glDeleteBuffersARB(1, &buffer);
|
| }
|
| }
|
| glReadPixels(x, y, width, height, format, type, pixels);
|
| @@ -9572,88 +9741,6 @@ error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
|
| return error::kNoError;
|
| }
|
|
|
| -error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
|
| - uint32 immediate_data_size,
|
| - const void* cmd_data) {
|
| - const gles2::cmds::GetMultipleIntegervCHROMIUM& c =
|
| - *static_cast<const gles2::cmds::GetMultipleIntegervCHROMIUM*>(cmd_data);
|
| - GLuint count = c.count;
|
| - uint32 pnames_size;
|
| - if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
|
| - return error::kOutOfBounds;
|
| - }
|
| - const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
|
| - c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
|
| - if (pnames == NULL) {
|
| - return error::kOutOfBounds;
|
| - }
|
| -
|
| - // We have to copy them since we use them twice so the client
|
| - // can't change them between the time we validate them and the time we use
|
| - // them.
|
| - scoped_ptr<GLenum[]> enums(new GLenum[count]);
|
| - memcpy(enums.get(), pnames, pnames_size);
|
| -
|
| - // Count up the space needed for the result.
|
| - uint32 num_results = 0;
|
| - for (GLuint ii = 0; ii < count; ++ii) {
|
| - uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
|
| - if (num == 0) {
|
| - LOCAL_SET_GL_ERROR_INVALID_ENUM(
|
| - "glGetMultipleCHROMIUM", enums[ii], "pname");
|
| - return error::kNoError;
|
| - }
|
| - // Num will never be more than 4.
|
| - DCHECK_LE(num, 4u);
|
| - if (!SafeAddUint32(num_results, num, &num_results)) {
|
| - return error::kOutOfBounds;
|
| - }
|
| - }
|
| -
|
| - uint32 result_size = 0;
|
| - if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
|
| - return error::kOutOfBounds;
|
| - }
|
| -
|
| - if (result_size != static_cast<uint32>(c.size)) {
|
| - LOCAL_SET_GL_ERROR(
|
| - GL_INVALID_VALUE,
|
| - "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
|
| - return error::kNoError;
|
| - }
|
| -
|
| - GLint* results = GetSharedMemoryAs<GLint*>(
|
| - c.results_shm_id, c.results_shm_offset, result_size);
|
| - if (results == NULL) {
|
| - return error::kOutOfBounds;
|
| - }
|
| -
|
| - // Check the results have been cleared in case the context was lost.
|
| - for (uint32 ii = 0; ii < num_results; ++ii) {
|
| - if (results[ii]) {
|
| - return error::kInvalidArguments;
|
| - }
|
| - }
|
| -
|
| - // Get each result.
|
| - GLint* start = results;
|
| - for (GLuint ii = 0; ii < count; ++ii) {
|
| - GLsizei num_written = 0;
|
| - if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
|
| - !GetHelper(enums[ii], results, &num_written)) {
|
| - DoGetIntegerv(enums[ii], results);
|
| - }
|
| - results += num_written;
|
| - }
|
| -
|
| - // Just to verify. Should this be a DCHECK?
|
| - if (static_cast<uint32>(results - start) != num_results) {
|
| - return error::kOutOfBounds;
|
| - }
|
| -
|
| - return error::kNoError;
|
| -}
|
| -
|
| error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
|
| uint32 immediate_data_size,
|
| const void* cmd_data) {
|
| @@ -9817,11 +9904,11 @@ void GLES2DecoderImpl::DeleteQueriesEXTHelper(
|
| }
|
| }
|
|
|
| -bool GLES2DecoderImpl::ProcessPendingQueries() {
|
| +bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
|
| if (query_manager_.get() == NULL) {
|
| return false;
|
| }
|
| - if (!query_manager_->ProcessPendingQueries()) {
|
| + if (!query_manager_->ProcessPendingQueries(did_finish)) {
|
| current_decoder_error_ = error::kOutOfBounds;
|
| }
|
| return query_manager_->HavePendingQueries();
|
| @@ -10696,6 +10783,73 @@ void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
|
| texture_ref = texture_manager()->Consume(client_id, texture);
|
| }
|
|
|
| +bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
|
| + const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
|
| + return valuebuffer && valuebuffer->IsValid();
|
| +}
|
| +
|
| +void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
|
| + GLuint client_id) {
|
| + Valuebuffer* valuebuffer = NULL;
|
| + if (client_id != 0) {
|
| + valuebuffer = GetValuebuffer(client_id);
|
| + if (!valuebuffer) {
|
| + if (!group_->bind_generates_resource()) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
|
| + "id not generated by glBindValuebufferCHROMIUM");
|
| + return;
|
| + }
|
| +
|
| + // It's a new id so make a valuebuffer for it.
|
| + CreateValuebuffer(client_id);
|
| + valuebuffer = GetValuebuffer(client_id);
|
| + }
|
| + valuebuffer->MarkAsValid();
|
| + }
|
| + state_.bound_valuebuffer = valuebuffer;
|
| +}
|
| +
|
| +void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
|
| + GLenum subscription) {
|
| + if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
|
| + return;
|
| + }
|
| + state_.bound_valuebuffer.get()->AddSubscription(subscription);
|
| +}
|
| +
|
| +void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
|
| + if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
|
| + return;
|
| + }
|
| + valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
|
| +}
|
| +
|
| +void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
|
| + GLenum target,
|
| + GLenum subscription) {
|
| + if (!CheckCurrentValuebufferForSubscription(
|
| + subscription, "glPopulateSubscribedValuesCHROMIUM")) {
|
| + return;
|
| + }
|
| + if (!CheckSubscriptionTarget(location, subscription,
|
| + "glPopulateSubscribedValuesCHROMIUM")) {
|
| + return;
|
| + }
|
| + const ValueState* state =
|
| + state_.bound_valuebuffer.get()->GetState(subscription);
|
| + if (state) {
|
| + switch (subscription) {
|
| + case GL_MOUSE_POSITION_CHROMIUM:
|
| + DoUniform2iv(location, 1, state->int_value);
|
| + break;
|
| + default:
|
| + NOTREACHED() << "Unhandled uniform subscription target "
|
| + << subscription;
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| void GLES2DecoderImpl::DoInsertEventMarkerEXT(
|
| GLsizei length, const GLchar* marker) {
|
| if (!marker) {
|
|
|