summaryrefslogtreecommitdiffstats
path: root/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
committerZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
commit679147eead574d186ebf3069647b4c23e8ccace6 (patch)
treefc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
Initial import.
Diffstat (limited to 'chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h')
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h3368
1 files changed, 3368 insertions, 0 deletions
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
new file mode 100644
index 00000000000..393c90292c8
--- /dev/null
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -0,0 +1,3368 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is auto-generated from
+// gpu/command_buffer/build_gles2_cmd_buffer.py
+// DO NOT EDIT!
+
+// It is included by gles2_cmd_decoder.cc
+#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_
+#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_
+
+error::Error GLES2DecoderImpl::HandleActiveTexture(
+ uint32 immediate_data_size, const gles2::cmds::ActiveTexture& c) {
+ GLenum texture = static_cast<GLenum>(c.texture);
+ DoActiveTexture(texture);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleAttachShader(
+ uint32 immediate_data_size, const gles2::cmds::AttachShader& c) {
+ GLuint program = c.program;
+ GLuint shader = c.shader;
+ DoAttachShader(program, shader);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBindBuffer(
+ uint32 immediate_data_size, const gles2::cmds::BindBuffer& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLuint buffer = c.buffer;
+ if (!validators_->buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindBuffer", target, "target");
+ return error::kNoError;
+ }
+ DoBindBuffer(target, buffer);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBindFramebuffer(
+ uint32 immediate_data_size, const gles2::cmds::BindFramebuffer& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLuint framebuffer = c.framebuffer;
+ if (!validators_->frame_buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindFramebuffer", target, "target");
+ return error::kNoError;
+ }
+ DoBindFramebuffer(target, framebuffer);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBindRenderbuffer(
+ uint32 immediate_data_size, const gles2::cmds::BindRenderbuffer& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLuint renderbuffer = c.renderbuffer;
+ if (!validators_->render_buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindRenderbuffer", target, "target");
+ return error::kNoError;
+ }
+ DoBindRenderbuffer(target, renderbuffer);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBindTexture(
+ uint32 immediate_data_size, const gles2::cmds::BindTexture& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLuint texture = c.texture;
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindTexture", target, "target");
+ return error::kNoError;
+ }
+ DoBindTexture(target, texture);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBlendColor(
+ uint32 immediate_data_size, const gles2::cmds::BlendColor& c) {
+ GLclampf red = static_cast<GLclampf>(c.red);
+ GLclampf green = static_cast<GLclampf>(c.green);
+ GLclampf blue = static_cast<GLclampf>(c.blue);
+ GLclampf alpha = static_cast<GLclampf>(c.alpha);
+ if (state_.blend_color_red != red ||
+ state_.blend_color_green != green ||
+ state_.blend_color_blue != blue ||
+ state_.blend_color_alpha != alpha) {
+ state_.blend_color_red = red;
+ state_.blend_color_green = green;
+ state_.blend_color_blue = blue;
+ state_.blend_color_alpha = alpha;
+ glBlendColor(red, green, blue, alpha);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBlendEquation(
+ uint32 immediate_data_size, const gles2::cmds::BlendEquation& c) {
+ GLenum mode = static_cast<GLenum>(c.mode);
+ if (!validators_->equation.IsValid(mode)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendEquation", mode, "mode");
+ return error::kNoError;
+ }
+ if (state_.blend_equation_rgb != mode ||
+ state_.blend_equation_alpha != mode) {
+ state_.blend_equation_rgb = mode;
+ state_.blend_equation_alpha = mode;
+ glBlendEquation(mode);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBlendEquationSeparate(
+ uint32 immediate_data_size, const gles2::cmds::BlendEquationSeparate& c) {
+ GLenum modeRGB = static_cast<GLenum>(c.modeRGB);
+ GLenum modeAlpha = static_cast<GLenum>(c.modeAlpha);
+ if (!validators_->equation.IsValid(modeRGB)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendEquationSeparate", modeRGB,
+ "modeRGB");
+ return error::kNoError;
+ }
+ if (!validators_->equation.IsValid(modeAlpha)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendEquationSeparate", modeAlpha,
+ "modeAlpha");
+ return error::kNoError;
+ }
+ if (state_.blend_equation_rgb != modeRGB ||
+ state_.blend_equation_alpha != modeAlpha) {
+ state_.blend_equation_rgb = modeRGB;
+ state_.blend_equation_alpha = modeAlpha;
+ glBlendEquationSeparate(modeRGB, modeAlpha);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBlendFunc(
+ uint32 immediate_data_size, const gles2::cmds::BlendFunc& c) {
+ GLenum sfactor = static_cast<GLenum>(c.sfactor);
+ GLenum dfactor = static_cast<GLenum>(c.dfactor);
+ if (!validators_->src_blend_factor.IsValid(sfactor)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFunc", sfactor, "sfactor");
+ return error::kNoError;
+ }
+ if (!validators_->dst_blend_factor.IsValid(dfactor)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFunc", dfactor, "dfactor");
+ return error::kNoError;
+ }
+ if (state_.blend_source_rgb != sfactor ||
+ state_.blend_dest_rgb != dfactor ||
+ state_.blend_source_alpha != sfactor ||
+ state_.blend_dest_alpha != dfactor) {
+ state_.blend_source_rgb = sfactor;
+ state_.blend_dest_rgb = dfactor;
+ state_.blend_source_alpha = sfactor;
+ state_.blend_dest_alpha = dfactor;
+ glBlendFunc(sfactor, dfactor);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBlendFuncSeparate(
+ uint32 immediate_data_size, const gles2::cmds::BlendFuncSeparate& c) {
+ GLenum srcRGB = static_cast<GLenum>(c.srcRGB);
+ GLenum dstRGB = static_cast<GLenum>(c.dstRGB);
+ GLenum srcAlpha = static_cast<GLenum>(c.srcAlpha);
+ GLenum dstAlpha = static_cast<GLenum>(c.dstAlpha);
+ if (!validators_->src_blend_factor.IsValid(srcRGB)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFuncSeparate", srcRGB, "srcRGB");
+ return error::kNoError;
+ }
+ if (!validators_->dst_blend_factor.IsValid(dstRGB)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFuncSeparate", dstRGB, "dstRGB");
+ return error::kNoError;
+ }
+ if (!validators_->src_blend_factor.IsValid(srcAlpha)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFuncSeparate", srcAlpha,
+ "srcAlpha");
+ return error::kNoError;
+ }
+ if (!validators_->dst_blend_factor.IsValid(dstAlpha)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFuncSeparate", dstAlpha,
+ "dstAlpha");
+ return error::kNoError;
+ }
+ if (state_.blend_source_rgb != srcRGB ||
+ state_.blend_dest_rgb != dstRGB ||
+ state_.blend_source_alpha != srcAlpha ||
+ state_.blend_dest_alpha != dstAlpha) {
+ state_.blend_source_rgb = srcRGB;
+ state_.blend_dest_rgb = dstRGB;
+ state_.blend_source_alpha = srcAlpha;
+ state_.blend_dest_alpha = dstAlpha;
+ glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBufferSubData(
+ uint32 immediate_data_size, const gles2::cmds::BufferSubData& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLintptr offset = static_cast<GLintptr>(c.offset);
+ GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
+ uint32 data_size = size;
+ const void* data = GetSharedMemoryAs<const void*>(
+ c.data_shm_id, c.data_shm_offset, data_size);
+ if (!validators_->buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferSubData", target, "target");
+ return error::kNoError;
+ }
+ if (size < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferSubData", "size < 0");
+ return error::kNoError;
+ }
+ if (data == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoBufferSubData(target, offset, size, data);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBufferSubDataImmediate(
+ uint32 immediate_data_size, const gles2::cmds::BufferSubDataImmediate& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLintptr offset = static_cast<GLintptr>(c.offset);
+ GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
+ uint32 data_size = size;
+ const void* data = GetImmediateDataAs<const void*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferSubData", target, "target");
+ return error::kNoError;
+ }
+ if (size < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferSubData", "size < 0");
+ return error::kNoError;
+ }
+ if (data == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoBufferSubData(target, offset, size, data);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCheckFramebufferStatus(
+ uint32 immediate_data_size, const gles2::cmds::CheckFramebufferStatus& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ typedef cmds::CheckFramebufferStatus::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ if (!validators_->frame_buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCheckFramebufferStatus", target,
+ "target");
+ return error::kNoError;
+ }
+ *result_dst = DoCheckFramebufferStatus(target);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleClear(
+ uint32 immediate_data_size, const gles2::cmds::Clear& c) {
+ if (ShouldDeferDraws())
+ return error::kDeferCommandUntilLater;
+ GLbitfield mask = static_cast<GLbitfield>(c.mask);
+ DoClear(mask);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleClearColor(
+ uint32 immediate_data_size, const gles2::cmds::ClearColor& c) {
+ GLclampf red = static_cast<GLclampf>(c.red);
+ GLclampf green = static_cast<GLclampf>(c.green);
+ GLclampf blue = static_cast<GLclampf>(c.blue);
+ GLclampf alpha = static_cast<GLclampf>(c.alpha);
+ if (state_.color_clear_red != red ||
+ state_.color_clear_green != green ||
+ state_.color_clear_blue != blue ||
+ state_.color_clear_alpha != alpha) {
+ state_.color_clear_red = red;
+ state_.color_clear_green = green;
+ state_.color_clear_blue = blue;
+ state_.color_clear_alpha = alpha;
+ glClearColor(red, green, blue, alpha);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleClearDepthf(
+ uint32 immediate_data_size, const gles2::cmds::ClearDepthf& c) {
+ GLclampf depth = static_cast<GLclampf>(c.depth);
+ if (state_.depth_clear != depth) {
+ state_.depth_clear = depth;
+ glClearDepth(depth);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleClearStencil(
+ uint32 immediate_data_size, const gles2::cmds::ClearStencil& c) {
+ GLint s = static_cast<GLint>(c.s);
+ if (state_.stencil_clear != s) {
+ state_.stencil_clear = s;
+ glClearStencil(s);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleColorMask(
+ uint32 immediate_data_size, const gles2::cmds::ColorMask& c) {
+ GLboolean red = static_cast<GLboolean>(c.red);
+ GLboolean green = static_cast<GLboolean>(c.green);
+ GLboolean blue = static_cast<GLboolean>(c.blue);
+ GLboolean alpha = static_cast<GLboolean>(c.alpha);
+ if (state_.color_mask_red != red ||
+ state_.color_mask_green != green ||
+ state_.color_mask_blue != blue ||
+ state_.color_mask_alpha != alpha) {
+ state_.color_mask_red = red;
+ state_.color_mask_green = green;
+ state_.color_mask_blue = blue;
+ state_.color_mask_alpha = alpha;
+ framebuffer_state_.clear_state_dirty = true;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCompileShader(
+ uint32 immediate_data_size, const gles2::cmds::CompileShader& c) {
+ GLuint shader = c.shader;
+ DoCompileShader(shader);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2D(
+ uint32 immediate_data_size,
+ const gles2::cmds::CompressedTexSubImage2D& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLint level = static_cast<GLint>(c.level);
+ GLint xoffset = static_cast<GLint>(c.xoffset);
+ GLint yoffset = static_cast<GLint>(c.yoffset);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ GLenum format = static_cast<GLenum>(c.format);
+ GLsizei imageSize = static_cast<GLsizei>(c.imageSize);
+ uint32 data_size = imageSize;
+ const void* data = GetSharedMemoryAs<const void*>(
+ c.data_shm_id, c.data_shm_offset, data_size);
+ if (!validators_->texture_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCompressedTexSubImage2D", target,
+ "target");
+ return error::kNoError;
+ }
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
+ return error::kNoError;
+ }
+ if (!validators_->compressed_texture_format.IsValid(format)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCompressedTexSubImage2D", format,
+ "format");
+ return error::kNoError;
+ }
+ if (imageSize < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
+ return error::kNoError;
+ }
+ if (data == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoCompressedTexSubImage2D(
+ target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::CompressedTexSubImage2DImmediate& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLint level = static_cast<GLint>(c.level);
+ GLint xoffset = static_cast<GLint>(c.xoffset);
+ GLint yoffset = static_cast<GLint>(c.yoffset);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ GLenum format = static_cast<GLenum>(c.format);
+ GLsizei imageSize = static_cast<GLsizei>(c.imageSize);
+ uint32 data_size = imageSize;
+ const void* data = GetImmediateDataAs<const void*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->texture_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCompressedTexSubImage2D", target,
+ "target");
+ return error::kNoError;
+ }
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
+ return error::kNoError;
+ }
+ if (!validators_->compressed_texture_format.IsValid(format)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCompressedTexSubImage2D", format,
+ "format");
+ return error::kNoError;
+ }
+ if (imageSize < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
+ return error::kNoError;
+ }
+ if (data == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoCompressedTexSubImage2D(
+ target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCopyTexImage2D(
+ uint32 immediate_data_size, const gles2::cmds::CopyTexImage2D& c) {
+ if (ShouldDeferReads())
+ return error::kDeferCommandUntilLater;
+ GLenum target = static_cast<GLenum>(c.target);
+ GLint level = static_cast<GLint>(c.level);
+ GLenum internalformat = static_cast<GLenum>(c.internalformat);
+ GLint x = static_cast<GLint>(c.x);
+ GLint y = static_cast<GLint>(c.y);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ GLint border = static_cast<GLint>(c.border);
+ if (!validators_->texture_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCopyTexImage2D", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->texture_internal_format.IsValid(internalformat)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCopyTexImage2D", internalformat,
+ "internalformat");
+ return error::kNoError;
+ }
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyTexImage2D", "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyTexImage2D", "height < 0");
+ return error::kNoError;
+ }
+ if (!validators_->texture_border.IsValid(border)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glCopyTexImage2D", "border GL_INVALID_VALUE");
+ return error::kNoError;
+ }
+ DoCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCopyTexSubImage2D(
+ uint32 immediate_data_size, const gles2::cmds::CopyTexSubImage2D& c) {
+ if (ShouldDeferReads())
+ return error::kDeferCommandUntilLater;
+ GLenum target = static_cast<GLenum>(c.target);
+ GLint level = static_cast<GLint>(c.level);
+ GLint xoffset = static_cast<GLint>(c.xoffset);
+ GLint yoffset = static_cast<GLint>(c.yoffset);
+ GLint x = static_cast<GLint>(c.x);
+ GLint y = static_cast<GLint>(c.y);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ if (!validators_->texture_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCopyTexSubImage2D", target, "target");
+ return error::kNoError;
+ }
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyTexSubImage2D", "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyTexSubImage2D", "height < 0");
+ return error::kNoError;
+ }
+ DoCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCreateProgram(
+ uint32 immediate_data_size, const gles2::cmds::CreateProgram& c) {
+ uint32 client_id = c.client_id;
+ if (!CreateProgramHelper(client_id)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCreateShader(
+ uint32 immediate_data_size, const gles2::cmds::CreateShader& c) {
+ GLenum type = static_cast<GLenum>(c.type);
+ if (!validators_->shader_type.IsValid(type)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCreateShader", type, "type");
+ return error::kNoError;
+ }
+ uint32 client_id = c.client_id;
+ if (!CreateShaderHelper(type, client_id)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCullFace(
+ uint32 immediate_data_size, const gles2::cmds::CullFace& c) {
+ GLenum mode = static_cast<GLenum>(c.mode);
+ if (!validators_->face_type.IsValid(mode)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCullFace", mode, "mode");
+ return error::kNoError;
+ }
+ if (state_.cull_mode != mode) {
+ state_.cull_mode = mode;
+ glCullFace(mode);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteBuffers(
+ uint32 immediate_data_size, const gles2::cmds::DeleteBuffers& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* buffers = GetSharedMemoryAs<const GLuint*>(
+ c.buffers_shm_id, c.buffers_shm_offset, data_size);
+ if (buffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteBuffersHelper(n, buffers);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteBuffersImmediate(
+ uint32 immediate_data_size, const gles2::cmds::DeleteBuffersImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* buffers = GetImmediateDataAs<const GLuint*>(
+ c, data_size, immediate_data_size);
+ if (buffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteBuffersHelper(n, buffers);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteFramebuffers(
+ uint32 immediate_data_size, const gles2::cmds::DeleteFramebuffers& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* framebuffers = GetSharedMemoryAs<const GLuint*>(
+ c.framebuffers_shm_id, c.framebuffers_shm_offset, data_size);
+ if (framebuffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteFramebuffersHelper(n, framebuffers);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteFramebuffersImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::DeleteFramebuffersImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* framebuffers = GetImmediateDataAs<const GLuint*>(
+ c, data_size, immediate_data_size);
+ if (framebuffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteFramebuffersHelper(n, framebuffers);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteRenderbuffers(
+ uint32 immediate_data_size, const gles2::cmds::DeleteRenderbuffers& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* renderbuffers = GetSharedMemoryAs<const GLuint*>(
+ c.renderbuffers_shm_id, c.renderbuffers_shm_offset, data_size);
+ if (renderbuffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteRenderbuffersHelper(n, renderbuffers);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteRenderbuffersImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::DeleteRenderbuffersImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* renderbuffers = GetImmediateDataAs<const GLuint*>(
+ c, data_size, immediate_data_size);
+ if (renderbuffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteRenderbuffersHelper(n, renderbuffers);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteTextures(
+ uint32 immediate_data_size, const gles2::cmds::DeleteTextures& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* textures = GetSharedMemoryAs<const GLuint*>(
+ c.textures_shm_id, c.textures_shm_offset, data_size);
+ if (textures == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteTexturesHelper(n, textures);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteTexturesImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::DeleteTexturesImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* textures = GetImmediateDataAs<const GLuint*>(
+ c, data_size, immediate_data_size);
+ if (textures == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteTexturesHelper(n, textures);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDepthFunc(
+ uint32 immediate_data_size, const gles2::cmds::DepthFunc& c) {
+ GLenum func = static_cast<GLenum>(c.func);
+ if (!validators_->cmp_function.IsValid(func)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glDepthFunc", func, "func");
+ return error::kNoError;
+ }
+ if (state_.depth_func != func) {
+ state_.depth_func = func;
+ glDepthFunc(func);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDepthMask(
+ uint32 immediate_data_size, const gles2::cmds::DepthMask& c) {
+ GLboolean flag = static_cast<GLboolean>(c.flag);
+ if (state_.depth_mask != flag) {
+ state_.depth_mask = flag;
+ framebuffer_state_.clear_state_dirty = true;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDepthRangef(
+ uint32 immediate_data_size, const gles2::cmds::DepthRangef& c) {
+ GLclampf zNear = static_cast<GLclampf>(c.zNear);
+ GLclampf zFar = static_cast<GLclampf>(c.zFar);
+ DoDepthRangef(zNear, zFar);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDetachShader(
+ uint32 immediate_data_size, const gles2::cmds::DetachShader& c) {
+ GLuint program = c.program;
+ GLuint shader = c.shader;
+ DoDetachShader(program, shader);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDisable(
+ uint32 immediate_data_size, const gles2::cmds::Disable& c) {
+ GLenum cap = static_cast<GLenum>(c.cap);
+ if (!validators_->capability.IsValid(cap)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glDisable", cap, "cap");
+ return error::kNoError;
+ }
+ DoDisable(cap);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDisableVertexAttribArray(
+ uint32 immediate_data_size,
+ const gles2::cmds::DisableVertexAttribArray& c) {
+ GLuint index = static_cast<GLuint>(c.index);
+ DoDisableVertexAttribArray(index);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleEnable(
+ uint32 immediate_data_size, const gles2::cmds::Enable& c) {
+ GLenum cap = static_cast<GLenum>(c.cap);
+ if (!validators_->capability.IsValid(cap)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glEnable", cap, "cap");
+ return error::kNoError;
+ }
+ DoEnable(cap);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleEnableVertexAttribArray(
+ uint32 immediate_data_size,
+ const gles2::cmds::EnableVertexAttribArray& c) {
+ GLuint index = static_cast<GLuint>(c.index);
+ DoEnableVertexAttribArray(index);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleFinish(
+ uint32 immediate_data_size, const gles2::cmds::Finish& c) {
+ if (ShouldDeferReads())
+ return error::kDeferCommandUntilLater;
+ DoFinish();
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleFlush(
+ uint32 immediate_data_size, const gles2::cmds::Flush& c) {
+ DoFlush();
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleFramebufferRenderbuffer(
+ uint32 immediate_data_size,
+ const gles2::cmds::FramebufferRenderbuffer& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum attachment = static_cast<GLenum>(c.attachment);
+ GLenum renderbuffertarget = static_cast<GLenum>(c.renderbuffertarget);
+ GLuint renderbuffer = c.renderbuffer;
+ if (!validators_->frame_buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferRenderbuffer", target,
+ "target");
+ return error::kNoError;
+ }
+ if (!validators_->attachment.IsValid(attachment)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferRenderbuffer", attachment,
+ "attachment");
+ return error::kNoError;
+ }
+ if (!validators_->render_buffer_target.IsValid(renderbuffertarget)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferRenderbuffer", renderbuffertarget, "renderbuffertarget"); // NOLINT
+ return error::kNoError;
+ }
+ DoFramebufferRenderbuffer(
+ target, attachment, renderbuffertarget, renderbuffer);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleFramebufferTexture2D(
+ uint32 immediate_data_size, const gles2::cmds::FramebufferTexture2D& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum attachment = static_cast<GLenum>(c.attachment);
+ GLenum textarget = static_cast<GLenum>(c.textarget);
+ GLuint texture = c.texture;
+ GLint level = static_cast<GLint>(c.level);
+ if (!validators_->frame_buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2D", target,
+ "target");
+ return error::kNoError;
+ }
+ if (!validators_->attachment.IsValid(attachment)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2D", attachment,
+ "attachment");
+ return error::kNoError;
+ }
+ if (!validators_->texture_target.IsValid(textarget)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2D", textarget,
+ "textarget");
+ return error::kNoError;
+ }
+ if (!validators_->zero_only.IsValid(level)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glFramebufferTexture2D", "level GL_INVALID_VALUE");
+ return error::kNoError;
+ }
+ DoFramebufferTexture2D(target, attachment, textarget, texture, level);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleFrontFace(
+ uint32 immediate_data_size, const gles2::cmds::FrontFace& c) {
+ GLenum mode = static_cast<GLenum>(c.mode);
+ if (!validators_->face_mode.IsValid(mode)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glFrontFace", mode, "mode");
+ return error::kNoError;
+ }
+ if (state_.front_face != mode) {
+ state_.front_face = mode;
+ glFrontFace(mode);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenBuffers(
+ uint32 immediate_data_size, const gles2::cmds::GenBuffers& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* buffers = GetSharedMemoryAs<GLuint*>(
+ c.buffers_shm_id, c.buffers_shm_offset, data_size);
+ if (buffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenBuffersHelper(n, buffers)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenBuffersImmediate(
+ uint32 immediate_data_size, const gles2::cmds::GenBuffersImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* buffers = GetImmediateDataAs<GLuint*>(
+ c, data_size, immediate_data_size);
+ if (buffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenBuffersHelper(n, buffers)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenerateMipmap(
+ uint32 immediate_data_size, const gles2::cmds::GenerateMipmap& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGenerateMipmap", target, "target");
+ return error::kNoError;
+ }
+ DoGenerateMipmap(target);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenFramebuffers(
+ uint32 immediate_data_size, const gles2::cmds::GenFramebuffers& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* framebuffers = GetSharedMemoryAs<GLuint*>(
+ c.framebuffers_shm_id, c.framebuffers_shm_offset, data_size);
+ if (framebuffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenFramebuffersHelper(n, framebuffers)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenFramebuffersImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::GenFramebuffersImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* framebuffers = GetImmediateDataAs<GLuint*>(
+ c, data_size, immediate_data_size);
+ if (framebuffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenFramebuffersHelper(n, framebuffers)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenRenderbuffers(
+ uint32 immediate_data_size, const gles2::cmds::GenRenderbuffers& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* renderbuffers = GetSharedMemoryAs<GLuint*>(
+ c.renderbuffers_shm_id, c.renderbuffers_shm_offset, data_size);
+ if (renderbuffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenRenderbuffersHelper(n, renderbuffers)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenRenderbuffersImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::GenRenderbuffersImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* renderbuffers = GetImmediateDataAs<GLuint*>(
+ c, data_size, immediate_data_size);
+ if (renderbuffers == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenRenderbuffersHelper(n, renderbuffers)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenTextures(
+ uint32 immediate_data_size, const gles2::cmds::GenTextures& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* textures = GetSharedMemoryAs<GLuint*>(
+ c.textures_shm_id, c.textures_shm_offset, data_size);
+ if (textures == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenTexturesHelper(n, textures)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenTexturesImmediate(
+ uint32 immediate_data_size, const gles2::cmds::GenTexturesImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* textures = GetImmediateDataAs<GLuint*>(
+ c, data_size, immediate_data_size);
+ if (textures == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenTexturesHelper(n, textures)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetBooleanv(
+ uint32 immediate_data_size, const gles2::cmds::GetBooleanv& c) {
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetBooleanv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLboolean* params = result ? result->GetData() : NULL;
+ if (!validators_->g_l_state.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetBooleanv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetBooleanv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ DoGetBooleanv(pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetBooleanv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetBufferParameteriv(
+ uint32 immediate_data_size, const gles2::cmds::GetBufferParameteriv& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetBufferParameteriv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLint* params = result ? result->GetData() : NULL;
+ if (!validators_->buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetBufferParameteriv", target,
+ "target");
+ return error::kNoError;
+ }
+ if (!validators_->buffer_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetBufferParameteriv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ DoGetBufferParameteriv(target, pname, params);
+ result->SetNumResults(num_values);
+ return error::kNoError;
+}
+error::Error GLES2DecoderImpl::HandleGetError(
+ uint32 immediate_data_size, const gles2::cmds::GetError& c) {
+ typedef cmds::GetError::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ *result_dst = GetErrorState()->GetGLError();
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetFloatv(
+ uint32 immediate_data_size, const gles2::cmds::GetFloatv& c) {
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetFloatv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLfloat* params = result ? result->GetData() : NULL;
+ if (!validators_->g_l_state.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetFloatv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetFloatv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ DoGetFloatv(pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetFloatv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetFramebufferAttachmentParameteriv(
+ uint32 immediate_data_size,
+ const gles2::cmds::GetFramebufferAttachmentParameteriv& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum attachment = static_cast<GLenum>(c.attachment);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetFramebufferAttachmentParameteriv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLint* params = result ? result->GetData() : NULL;
+ if (!validators_->frame_buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetFramebufferAttachmentParameteriv", target, "target"); // NOLINT
+ return error::kNoError;
+ }
+ if (!validators_->attachment.IsValid(attachment)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetFramebufferAttachmentParameteriv", attachment, "attachment"); // NOLINT
+ return error::kNoError;
+ }
+ if (!validators_->frame_buffer_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetFramebufferAttachmentParameteriv", pname, "pname"); // NOLINT
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetFramebufferAttachmentParameteriv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ DoGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetFramebufferAttachmentParameteriv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetIntegerv(
+ uint32 immediate_data_size, const gles2::cmds::GetIntegerv& c) {
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetIntegerv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLint* params = result ? result->GetData() : NULL;
+ if (!validators_->g_l_state.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetIntegerv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetIntegerv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ DoGetIntegerv(pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetIntegerv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetProgramiv(
+ uint32 immediate_data_size, const gles2::cmds::GetProgramiv& c) {
+ GLuint program = c.program;
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetProgramiv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLint* params = result ? result->GetData() : NULL;
+ if (!validators_->program_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetProgramiv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetProgramiv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ DoGetProgramiv(program, pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetProgramiv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetRenderbufferParameteriv(
+ uint32 immediate_data_size,
+ const gles2::cmds::GetRenderbufferParameteriv& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetRenderbufferParameteriv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLint* params = result ? result->GetData() : NULL;
+ if (!validators_->render_buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetRenderbufferParameteriv", target,
+ "target");
+ return error::kNoError;
+ }
+ if (!validators_->render_buffer_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetRenderbufferParameteriv", pname,
+ "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetRenderbufferParameteriv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ DoGetRenderbufferParameteriv(target, pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetRenderbufferParameteriv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetShaderiv(
+ uint32 immediate_data_size, const gles2::cmds::GetShaderiv& c) {
+ GLuint shader = c.shader;
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetShaderiv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLint* params = result ? result->GetData() : NULL;
+ if (!validators_->shader_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetShaderiv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetShaderiv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ DoGetShaderiv(shader, pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetShaderiv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetTexParameterfv(
+ uint32 immediate_data_size, const gles2::cmds::GetTexParameterfv& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetTexParameterfv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLfloat* params = result ? result->GetData() : NULL;
+ if (!validators_->get_tex_param_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetTexParameterfv", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->texture_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetTexParameterfv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTexParameterfv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ glGetTexParameterfv(target, pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetTexParameterfv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetTexParameteriv(
+ uint32 immediate_data_size, const gles2::cmds::GetTexParameteriv& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetTexParameteriv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLint* params = result ? result->GetData() : NULL;
+ if (!validators_->get_tex_param_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetTexParameteriv", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->texture_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetTexParameteriv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTexParameteriv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ glGetTexParameteriv(target, pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetTexParameteriv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetVertexAttribfv(
+ uint32 immediate_data_size, const gles2::cmds::GetVertexAttribfv& c) {
+ GLuint index = static_cast<GLuint>(c.index);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetVertexAttribfv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLfloat* params = result ? result->GetData() : NULL;
+ if (!validators_->vertex_attribute.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetVertexAttribfv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetVertexAttribfv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ DoGetVertexAttribfv(index, pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetVertexAttribfv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetVertexAttribiv(
+ uint32 immediate_data_size, const gles2::cmds::GetVertexAttribiv& c) {
+ GLuint index = static_cast<GLuint>(c.index);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetVertexAttribiv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLint* params = result ? result->GetData() : NULL;
+ if (!validators_->vertex_attribute.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetVertexAttribiv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetVertexAttribiv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ DoGetVertexAttribiv(index, pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetVertexAttribiv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleHint(
+ uint32 immediate_data_size, const gles2::cmds::Hint& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum mode = static_cast<GLenum>(c.mode);
+ if (!validators_->hint_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glHint", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->hint_mode.IsValid(mode)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glHint", mode, "mode");
+ return error::kNoError;
+ }
+ switch (target) {
+ case GL_GENERATE_MIPMAP_HINT:
+ if (state_.hint_generate_mipmap != mode) {
+ state_.hint_generate_mipmap = mode;
+ glHint(target, mode);
+ }
+ break;
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+ if (state_.hint_fragment_shader_derivative != mode) {
+ state_.hint_fragment_shader_derivative = mode;
+ glHint(target, mode);
+ }
+ break;
+ default:
+ NOTREACHED();
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleIsBuffer(
+ uint32 immediate_data_size, const gles2::cmds::IsBuffer& c) {
+ GLuint buffer = c.buffer;
+ typedef cmds::IsBuffer::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ *result_dst = DoIsBuffer(buffer);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleIsEnabled(
+ uint32 immediate_data_size, const gles2::cmds::IsEnabled& c) {
+ GLenum cap = static_cast<GLenum>(c.cap);
+ typedef cmds::IsEnabled::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ if (!validators_->capability.IsValid(cap)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glIsEnabled", cap, "cap");
+ return error::kNoError;
+ }
+ *result_dst = DoIsEnabled(cap);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleIsFramebuffer(
+ uint32 immediate_data_size, const gles2::cmds::IsFramebuffer& c) {
+ GLuint framebuffer = c.framebuffer;
+ typedef cmds::IsFramebuffer::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ *result_dst = DoIsFramebuffer(framebuffer);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleIsProgram(
+ uint32 immediate_data_size, const gles2::cmds::IsProgram& c) {
+ GLuint program = c.program;
+ typedef cmds::IsProgram::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ *result_dst = DoIsProgram(program);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleIsRenderbuffer(
+ uint32 immediate_data_size, const gles2::cmds::IsRenderbuffer& c) {
+ GLuint renderbuffer = c.renderbuffer;
+ typedef cmds::IsRenderbuffer::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ *result_dst = DoIsRenderbuffer(renderbuffer);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleIsShader(
+ uint32 immediate_data_size, const gles2::cmds::IsShader& c) {
+ GLuint shader = c.shader;
+ typedef cmds::IsShader::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ *result_dst = DoIsShader(shader);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleIsTexture(
+ uint32 immediate_data_size, const gles2::cmds::IsTexture& c) {
+ GLuint texture = c.texture;
+ typedef cmds::IsTexture::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ *result_dst = DoIsTexture(texture);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleLineWidth(
+ uint32 immediate_data_size, const gles2::cmds::LineWidth& c) {
+ GLfloat width = static_cast<GLfloat>(c.width);
+ if (width <= 0.0f) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "LineWidth", "width out of range");
+ return error::kNoError;
+ }
+ if (state_.line_width != width) {
+ state_.line_width = width;
+ glLineWidth(width);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleLinkProgram(
+ uint32 immediate_data_size, const gles2::cmds::LinkProgram& c) {
+ GLuint program = c.program;
+ DoLinkProgram(program);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandlePolygonOffset(
+ uint32 immediate_data_size, const gles2::cmds::PolygonOffset& c) {
+ GLfloat factor = static_cast<GLfloat>(c.factor);
+ GLfloat units = static_cast<GLfloat>(c.units);
+ if (state_.polygon_offset_factor != factor ||
+ state_.polygon_offset_units != units) {
+ state_.polygon_offset_factor = factor;
+ state_.polygon_offset_units = units;
+ glPolygonOffset(factor, units);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleReleaseShaderCompiler(
+ uint32 immediate_data_size, const gles2::cmds::ReleaseShaderCompiler& c) {
+ DoReleaseShaderCompiler();
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleRenderbufferStorage(
+ uint32 immediate_data_size, const gles2::cmds::RenderbufferStorage& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum internalformat = static_cast<GLenum>(c.internalformat);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ if (!validators_->render_buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glRenderbufferStorage", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->render_buffer_format.IsValid(internalformat)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glRenderbufferStorage", internalformat,
+ "internalformat");
+ return error::kNoError;
+ }
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRenderbufferStorage", "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glRenderbufferStorage", "height < 0");
+ return error::kNoError;
+ }
+ DoRenderbufferStorage(target, internalformat, width, height);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleSampleCoverage(
+ uint32 immediate_data_size, const gles2::cmds::SampleCoverage& c) {
+ GLclampf value = static_cast<GLclampf>(c.value);
+ GLboolean invert = static_cast<GLboolean>(c.invert);
+ DoSampleCoverage(value, invert);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleScissor(
+ uint32 immediate_data_size, const gles2::cmds::Scissor& c) {
+ GLint x = static_cast<GLint>(c.x);
+ GLint y = static_cast<GLint>(c.y);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScissor", "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScissor", "height < 0");
+ return error::kNoError;
+ }
+ if (state_.scissor_x != x ||
+ state_.scissor_y != y ||
+ state_.scissor_width != width ||
+ state_.scissor_height != height) {
+ state_.scissor_x = x;
+ state_.scissor_y = y;
+ state_.scissor_width = width;
+ state_.scissor_height = height;
+ glScissor(x, y, width, height);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleStencilFunc(
+ uint32 immediate_data_size, const gles2::cmds::StencilFunc& c) {
+ GLenum func = static_cast<GLenum>(c.func);
+ GLint ref = static_cast<GLint>(c.ref);
+ GLuint mask = static_cast<GLuint>(c.mask);
+ if (!validators_->cmp_function.IsValid(func)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilFunc", func, "func");
+ return error::kNoError;
+ }
+ if (state_.stencil_front_func != func ||
+ state_.stencil_front_ref != ref ||
+ state_.stencil_front_mask != mask ||
+ state_.stencil_back_func != func ||
+ state_.stencil_back_ref != ref ||
+ state_.stencil_back_mask != mask) {
+ state_.stencil_front_func = func;
+ state_.stencil_front_ref = ref;
+ state_.stencil_front_mask = mask;
+ state_.stencil_back_func = func;
+ state_.stencil_back_ref = ref;
+ state_.stencil_back_mask = mask;
+ glStencilFunc(func, ref, mask);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleStencilFuncSeparate(
+ uint32 immediate_data_size, const gles2::cmds::StencilFuncSeparate& c) {
+ GLenum face = static_cast<GLenum>(c.face);
+ GLenum func = static_cast<GLenum>(c.func);
+ GLint ref = static_cast<GLint>(c.ref);
+ GLuint mask = static_cast<GLuint>(c.mask);
+ if (!validators_->face_type.IsValid(face)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilFuncSeparate", face, "face");
+ return error::kNoError;
+ }
+ if (!validators_->cmp_function.IsValid(func)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilFuncSeparate", func, "func");
+ return error::kNoError;
+ }
+ bool changed = false;
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ changed |= state_.stencil_front_func != func ||
+ state_.stencil_front_ref != ref ||
+ state_.stencil_front_mask != mask;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ changed |= state_.stencil_back_func != func ||
+ state_.stencil_back_ref != ref ||
+ state_.stencil_back_mask != mask;
+ }
+ if (changed) {
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ state_.stencil_front_func = func;
+ state_.stencil_front_ref = ref;
+ state_.stencil_front_mask = mask;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ state_.stencil_back_func = func;
+ state_.stencil_back_ref = ref;
+ state_.stencil_back_mask = mask;
+ }
+ glStencilFuncSeparate(face, func, ref, mask);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleStencilMask(
+ uint32 immediate_data_size, const gles2::cmds::StencilMask& c) {
+ GLuint mask = static_cast<GLuint>(c.mask);
+ if (state_.stencil_front_writemask != mask ||
+ state_.stencil_back_writemask != mask) {
+ state_.stencil_front_writemask = mask;
+ state_.stencil_back_writemask = mask;
+ framebuffer_state_.clear_state_dirty = true;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleStencilMaskSeparate(
+ uint32 immediate_data_size, const gles2::cmds::StencilMaskSeparate& c) {
+ GLenum face = static_cast<GLenum>(c.face);
+ GLuint mask = static_cast<GLuint>(c.mask);
+ if (!validators_->face_type.IsValid(face)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilMaskSeparate", face, "face");
+ return error::kNoError;
+ }
+ bool changed = false;
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ changed |= state_.stencil_front_writemask != mask;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ changed |= state_.stencil_back_writemask != mask;
+ }
+ if (changed) {
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ state_.stencil_front_writemask = mask;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ state_.stencil_back_writemask = mask;
+ }
+ framebuffer_state_.clear_state_dirty = true;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleStencilOp(
+ uint32 immediate_data_size, const gles2::cmds::StencilOp& c) {
+ GLenum fail = static_cast<GLenum>(c.fail);
+ GLenum zfail = static_cast<GLenum>(c.zfail);
+ GLenum zpass = static_cast<GLenum>(c.zpass);
+ if (!validators_->stencil_op.IsValid(fail)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOp", fail, "fail");
+ return error::kNoError;
+ }
+ if (!validators_->stencil_op.IsValid(zfail)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOp", zfail, "zfail");
+ return error::kNoError;
+ }
+ if (!validators_->stencil_op.IsValid(zpass)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOp", zpass, "zpass");
+ return error::kNoError;
+ }
+ if (state_.stencil_front_fail_op != fail ||
+ state_.stencil_front_z_fail_op != zfail ||
+ state_.stencil_front_z_pass_op != zpass ||
+ state_.stencil_back_fail_op != fail ||
+ state_.stencil_back_z_fail_op != zfail ||
+ state_.stencil_back_z_pass_op != zpass) {
+ state_.stencil_front_fail_op = fail;
+ state_.stencil_front_z_fail_op = zfail;
+ state_.stencil_front_z_pass_op = zpass;
+ state_.stencil_back_fail_op = fail;
+ state_.stencil_back_z_fail_op = zfail;
+ state_.stencil_back_z_pass_op = zpass;
+ glStencilOp(fail, zfail, zpass);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleStencilOpSeparate(
+ uint32 immediate_data_size, const gles2::cmds::StencilOpSeparate& c) {
+ GLenum face = static_cast<GLenum>(c.face);
+ GLenum fail = static_cast<GLenum>(c.fail);
+ GLenum zfail = static_cast<GLenum>(c.zfail);
+ GLenum zpass = static_cast<GLenum>(c.zpass);
+ if (!validators_->face_type.IsValid(face)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOpSeparate", face, "face");
+ return error::kNoError;
+ }
+ if (!validators_->stencil_op.IsValid(fail)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOpSeparate", fail, "fail");
+ return error::kNoError;
+ }
+ if (!validators_->stencil_op.IsValid(zfail)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOpSeparate", zfail, "zfail");
+ return error::kNoError;
+ }
+ if (!validators_->stencil_op.IsValid(zpass)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOpSeparate", zpass, "zpass");
+ return error::kNoError;
+ }
+ bool changed = false;
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ changed |= state_.stencil_front_fail_op != fail ||
+ state_.stencil_front_z_fail_op != zfail ||
+ state_.stencil_front_z_pass_op != zpass;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ changed |= state_.stencil_back_fail_op != fail ||
+ state_.stencil_back_z_fail_op != zfail ||
+ state_.stencil_back_z_pass_op != zpass;
+ }
+ if (changed) {
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ state_.stencil_front_fail_op = fail;
+ state_.stencil_front_z_fail_op = zfail;
+ state_.stencil_front_z_pass_op = zpass;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ state_.stencil_back_fail_op = fail;
+ state_.stencil_back_z_fail_op = zfail;
+ state_.stencil_back_z_pass_op = zpass;
+ }
+ glStencilOpSeparate(face, fail, zfail, zpass);
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleTexParameterf(
+ uint32 immediate_data_size, const gles2::cmds::TexParameterf& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ GLfloat param = static_cast<GLfloat>(c.param);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterf", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->texture_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterf", pname, "pname");
+ return error::kNoError;
+ }
+ DoTexParameterf(target, pname, param);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleTexParameterfv(
+ uint32 immediate_data_size, const gles2::cmds::TexParameterfv& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* params = GetSharedMemoryAs<const GLfloat*>(
+ c.params_shm_id, c.params_shm_offset, data_size);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterfv", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->texture_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterfv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoTexParameterfv(target, pname, params);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleTexParameterfvImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::TexParameterfvImmediate& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* params = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterfv", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->texture_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterfv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoTexParameterfv(target, pname, params);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleTexParameteri(
+ uint32 immediate_data_size, const gles2::cmds::TexParameteri& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ GLint param = static_cast<GLint>(c.param);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteri", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->texture_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteri", pname, "pname");
+ return error::kNoError;
+ }
+ DoTexParameteri(target, pname, param);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleTexParameteriv(
+ uint32 immediate_data_size, const gles2::cmds::TexParameteriv& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLint* params = GetSharedMemoryAs<const GLint*>(
+ c.params_shm_id, c.params_shm_offset, data_size);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteriv", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->texture_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteriv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoTexParameteriv(target, pname, params);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleTexParameterivImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::TexParameterivImmediate& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum pname = static_cast<GLenum>(c.pname);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLint* params = GetImmediateDataAs<const GLint*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteriv", target, "target");
+ return error::kNoError;
+ }
+ if (!validators_->texture_parameter.IsValid(pname)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteriv", pname, "pname");
+ return error::kNoError;
+ }
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoTexParameteriv(target, pname, params);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform1f(
+ uint32 immediate_data_size, const gles2::cmds::Uniform1f& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLfloat x = static_cast<GLfloat>(c.x);
+ GLfloat temp[1] = { x, };
+ DoUniform1fv(location, 1, &temp[0]);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform1fv(
+ uint32 immediate_data_size, const gles2::cmds::Uniform1fv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
+ c.v_shm_id, c.v_shm_offset, data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform1fv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform1fvImmediate(
+ uint32 immediate_data_size, const gles2::cmds::Uniform1fvImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform1fv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform1i(
+ uint32 immediate_data_size, const gles2::cmds::Uniform1i& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLint x = static_cast<GLint>(c.x);
+ DoUniform1i(location, x);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform1iv(
+ uint32 immediate_data_size, const gles2::cmds::Uniform1iv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLint), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLint* v = GetSharedMemoryAs<const GLint*>(
+ c.v_shm_id, c.v_shm_offset, data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform1iv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform1ivImmediate(
+ uint32 immediate_data_size, const gles2::cmds::Uniform1ivImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLint), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLint* v = GetImmediateDataAs<const GLint*>(
+ c, data_size, immediate_data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform1iv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform2f(
+ uint32 immediate_data_size, const gles2::cmds::Uniform2f& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLfloat x = static_cast<GLfloat>(c.x);
+ GLfloat y = static_cast<GLfloat>(c.y);
+ GLfloat temp[2] = { x, y, };
+ DoUniform2fv(location, 1, &temp[0]);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform2fv(
+ uint32 immediate_data_size, const gles2::cmds::Uniform2fv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
+ c.v_shm_id, c.v_shm_offset, data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform2fv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform2fvImmediate(
+ uint32 immediate_data_size, const gles2::cmds::Uniform2fvImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform2fv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform2i(
+ uint32 immediate_data_size, const gles2::cmds::Uniform2i& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLint x = static_cast<GLint>(c.x);
+ GLint y = static_cast<GLint>(c.y);
+ GLint temp[2] = { x, y, };
+ DoUniform2iv(location, 1, &temp[0]);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform2iv(
+ uint32 immediate_data_size, const gles2::cmds::Uniform2iv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLint), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLint* v = GetSharedMemoryAs<const GLint*>(
+ c.v_shm_id, c.v_shm_offset, data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform2iv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform2ivImmediate(
+ uint32 immediate_data_size, const gles2::cmds::Uniform2ivImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLint), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLint* v = GetImmediateDataAs<const GLint*>(
+ c, data_size, immediate_data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform2iv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform3f(
+ uint32 immediate_data_size, const gles2::cmds::Uniform3f& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLfloat x = static_cast<GLfloat>(c.x);
+ GLfloat y = static_cast<GLfloat>(c.y);
+ GLfloat z = static_cast<GLfloat>(c.z);
+ GLfloat temp[3] = { x, y, z, };
+ DoUniform3fv(location, 1, &temp[0]);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform3fv(
+ uint32 immediate_data_size, const gles2::cmds::Uniform3fv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
+ c.v_shm_id, c.v_shm_offset, data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform3fv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform3fvImmediate(
+ uint32 immediate_data_size, const gles2::cmds::Uniform3fvImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform3fv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform3i(
+ uint32 immediate_data_size, const gles2::cmds::Uniform3i& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLint x = static_cast<GLint>(c.x);
+ GLint y = static_cast<GLint>(c.y);
+ GLint z = static_cast<GLint>(c.z);
+ GLint temp[3] = { x, y, z, };
+ DoUniform3iv(location, 1, &temp[0]);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform3iv(
+ uint32 immediate_data_size, const gles2::cmds::Uniform3iv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLint), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLint* v = GetSharedMemoryAs<const GLint*>(
+ c.v_shm_id, c.v_shm_offset, data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform3iv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform3ivImmediate(
+ uint32 immediate_data_size, const gles2::cmds::Uniform3ivImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLint), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLint* v = GetImmediateDataAs<const GLint*>(
+ c, data_size, immediate_data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform3iv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform4f(
+ uint32 immediate_data_size, const gles2::cmds::Uniform4f& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLfloat x = static_cast<GLfloat>(c.x);
+ GLfloat y = static_cast<GLfloat>(c.y);
+ GLfloat z = static_cast<GLfloat>(c.z);
+ GLfloat w = static_cast<GLfloat>(c.w);
+ GLfloat temp[4] = { x, y, z, w, };
+ DoUniform4fv(location, 1, &temp[0]);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform4fv(
+ uint32 immediate_data_size, const gles2::cmds::Uniform4fv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
+ c.v_shm_id, c.v_shm_offset, data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform4fv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform4fvImmediate(
+ uint32 immediate_data_size, const gles2::cmds::Uniform4fvImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform4fv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform4i(
+ uint32 immediate_data_size, const gles2::cmds::Uniform4i& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLint x = static_cast<GLint>(c.x);
+ GLint y = static_cast<GLint>(c.y);
+ GLint z = static_cast<GLint>(c.z);
+ GLint w = static_cast<GLint>(c.w);
+ GLint temp[4] = { x, y, z, w, };
+ DoUniform4iv(location, 1, &temp[0]);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform4iv(
+ uint32 immediate_data_size, const gles2::cmds::Uniform4iv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLint), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLint* v = GetSharedMemoryAs<const GLint*>(
+ c.v_shm_id, c.v_shm_offset, data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform4iv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniform4ivImmediate(
+ uint32 immediate_data_size, const gles2::cmds::Uniform4ivImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLint), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLint* v = GetImmediateDataAs<const GLint*>(
+ c, data_size, immediate_data_size);
+ if (v == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniform4iv(location, count, v);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniformMatrix2fv(
+ uint32 immediate_data_size, const gles2::cmds::UniformMatrix2fv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ GLboolean transpose = static_cast<GLboolean>(c.transpose);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* value = GetSharedMemoryAs<const GLfloat*>(
+ c.value_shm_id, c.value_shm_offset, data_size);
+ if (!validators_->false_only.IsValid(transpose)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glUniformMatrix2fv", "transpose GL_INVALID_VALUE");
+ return error::kNoError;
+ }
+ if (value == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniformMatrix2fv(location, count, transpose, value);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniformMatrix2fvImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::UniformMatrix2fvImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ GLboolean transpose = static_cast<GLboolean>(c.transpose);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* value = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->false_only.IsValid(transpose)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glUniformMatrix2fv", "transpose GL_INVALID_VALUE");
+ return error::kNoError;
+ }
+ if (value == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniformMatrix2fv(location, count, transpose, value);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniformMatrix3fv(
+ uint32 immediate_data_size, const gles2::cmds::UniformMatrix3fv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ GLboolean transpose = static_cast<GLboolean>(c.transpose);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 9, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* value = GetSharedMemoryAs<const GLfloat*>(
+ c.value_shm_id, c.value_shm_offset, data_size);
+ if (!validators_->false_only.IsValid(transpose)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glUniformMatrix3fv", "transpose GL_INVALID_VALUE");
+ return error::kNoError;
+ }
+ if (value == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniformMatrix3fv(location, count, transpose, value);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniformMatrix3fvImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::UniformMatrix3fvImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ GLboolean transpose = static_cast<GLboolean>(c.transpose);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 9, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* value = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->false_only.IsValid(transpose)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glUniformMatrix3fv", "transpose GL_INVALID_VALUE");
+ return error::kNoError;
+ }
+ if (value == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniformMatrix3fv(location, count, transpose, value);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniformMatrix4fv(
+ uint32 immediate_data_size, const gles2::cmds::UniformMatrix4fv& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ GLboolean transpose = static_cast<GLboolean>(c.transpose);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 16, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* value = GetSharedMemoryAs<const GLfloat*>(
+ c.value_shm_id, c.value_shm_offset, data_size);
+ if (!validators_->false_only.IsValid(transpose)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glUniformMatrix4fv", "transpose GL_INVALID_VALUE");
+ return error::kNoError;
+ }
+ if (value == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniformMatrix4fv(location, count, transpose, value);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUniformMatrix4fvImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::UniformMatrix4fvImmediate& c) {
+ GLint location = static_cast<GLint>(c.location);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ GLboolean transpose = static_cast<GLboolean>(c.transpose);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLfloat), 16, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* value = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->false_only.IsValid(transpose)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glUniformMatrix4fv", "transpose GL_INVALID_VALUE");
+ return error::kNoError;
+ }
+ if (value == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoUniformMatrix4fv(location, count, transpose, value);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUseProgram(
+ uint32 immediate_data_size, const gles2::cmds::UseProgram& c) {
+ GLuint program = c.program;
+ DoUseProgram(program);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleValidateProgram(
+ uint32 immediate_data_size, const gles2::cmds::ValidateProgram& c) {
+ GLuint program = c.program;
+ DoValidateProgram(program);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib1f(
+ uint32 immediate_data_size, const gles2::cmds::VertexAttrib1f& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ GLfloat x = static_cast<GLfloat>(c.x);
+ DoVertexAttrib1f(indx, x);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib1fv(
+ uint32 immediate_data_size, const gles2::cmds::VertexAttrib1fv& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
+ c.values_shm_id, c.values_shm_offset, data_size);
+ if (values == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoVertexAttrib1fv(indx, values);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib1fvImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::VertexAttrib1fvImmediate& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (values == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoVertexAttrib1fv(indx, values);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib2f(
+ uint32 immediate_data_size, const gles2::cmds::VertexAttrib2f& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ GLfloat x = static_cast<GLfloat>(c.x);
+ GLfloat y = static_cast<GLfloat>(c.y);
+ DoVertexAttrib2f(indx, x, y);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib2fv(
+ uint32 immediate_data_size, const gles2::cmds::VertexAttrib2fv& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
+ c.values_shm_id, c.values_shm_offset, data_size);
+ if (values == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoVertexAttrib2fv(indx, values);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib2fvImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::VertexAttrib2fvImmediate& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (values == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoVertexAttrib2fv(indx, values);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib3f(
+ uint32 immediate_data_size, const gles2::cmds::VertexAttrib3f& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ GLfloat x = static_cast<GLfloat>(c.x);
+ GLfloat y = static_cast<GLfloat>(c.y);
+ GLfloat z = static_cast<GLfloat>(c.z);
+ DoVertexAttrib3f(indx, x, y, z);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib3fv(
+ uint32 immediate_data_size, const gles2::cmds::VertexAttrib3fv& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
+ c.values_shm_id, c.values_shm_offset, data_size);
+ if (values == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoVertexAttrib3fv(indx, values);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib3fvImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::VertexAttrib3fvImmediate& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (values == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoVertexAttrib3fv(indx, values);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib4f(
+ uint32 immediate_data_size, const gles2::cmds::VertexAttrib4f& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ GLfloat x = static_cast<GLfloat>(c.x);
+ GLfloat y = static_cast<GLfloat>(c.y);
+ GLfloat z = static_cast<GLfloat>(c.z);
+ GLfloat w = static_cast<GLfloat>(c.w);
+ DoVertexAttrib4f(indx, x, y, z, w);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib4fv(
+ uint32 immediate_data_size, const gles2::cmds::VertexAttrib4fv& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
+ c.values_shm_id, c.values_shm_offset, data_size);
+ if (values == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoVertexAttrib4fv(indx, values);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleVertexAttrib4fvImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::VertexAttrib4fvImmediate& c) {
+ GLuint indx = static_cast<GLuint>(c.indx);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
+ c, data_size, immediate_data_size);
+ if (values == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoVertexAttrib4fv(indx, values);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleViewport(
+ uint32 immediate_data_size, const gles2::cmds::Viewport& c) {
+ GLint x = static_cast<GLint>(c.x);
+ GLint y = static_cast<GLint>(c.y);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glViewport", "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glViewport", "height < 0");
+ return error::kNoError;
+ }
+ DoViewport(x, y, width, height);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBlitFramebufferEXT(
+ uint32 immediate_data_size, const gles2::cmds::BlitFramebufferEXT& c) {
+ if (ShouldDeferDraws() || ShouldDeferReads())
+ return error::kDeferCommandUntilLater;
+ GLint srcX0 = static_cast<GLint>(c.srcX0);
+ GLint srcY0 = static_cast<GLint>(c.srcY0);
+ GLint srcX1 = static_cast<GLint>(c.srcX1);
+ GLint srcY1 = static_cast<GLint>(c.srcY1);
+ GLint dstX0 = static_cast<GLint>(c.dstX0);
+ GLint dstY0 = static_cast<GLint>(c.dstY0);
+ GLint dstX1 = static_cast<GLint>(c.dstX1);
+ GLint dstY1 = static_cast<GLint>(c.dstY1);
+ GLbitfield mask = static_cast<GLbitfield>(c.mask);
+ GLenum filter = static_cast<GLenum>(c.filter);
+ if (!validators_->blit_filter.IsValid(filter)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlitFramebufferEXT", filter, "filter");
+ return error::kNoError;
+ }
+ DoBlitFramebufferEXT(
+ srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleEXT(
+ uint32 immediate_data_size,
+ const gles2::cmds::RenderbufferStorageMultisampleEXT& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLsizei samples = static_cast<GLsizei>(c.samples);
+ GLenum internalformat = static_cast<GLenum>(c.internalformat);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ if (!validators_->render_buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glRenderbufferStorageMultisampleEXT", target, "target"); // NOLINT
+ return error::kNoError;
+ }
+ if (samples < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "samples < 0");
+ return error::kNoError;
+ }
+ if (!validators_->render_buffer_format.IsValid(internalformat)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glRenderbufferStorageMultisampleEXT", internalformat, "internalformat"); // NOLINT
+ return error::kNoError;
+ }
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "height < 0");
+ return error::kNoError;
+ }
+ DoRenderbufferStorageMultisample(
+ target, samples, internalformat, width, height);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleFramebufferTexture2DMultisampleEXT(
+ uint32 immediate_data_size,
+ const gles2::cmds::FramebufferTexture2DMultisampleEXT& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum attachment = static_cast<GLenum>(c.attachment);
+ GLenum textarget = static_cast<GLenum>(c.textarget);
+ GLuint texture = c.texture;
+ GLint level = static_cast<GLint>(c.level);
+ GLsizei samples = static_cast<GLsizei>(c.samples);
+ if (!validators_->frame_buffer_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2DMultisampleEXT", target, "target"); // NOLINT
+ return error::kNoError;
+ }
+ if (!validators_->attachment.IsValid(attachment)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2DMultisampleEXT", attachment, "attachment"); // NOLINT
+ return error::kNoError;
+ }
+ if (!validators_->texture_target.IsValid(textarget)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2DMultisampleEXT", textarget, "textarget"); // NOLINT
+ return error::kNoError;
+ }
+ if (!validators_->zero_only.IsValid(level)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glFramebufferTexture2DMultisampleEXT", "level GL_INVALID_VALUE"); // NOLINT
+ return error::kNoError;
+ }
+ if (samples < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glFramebufferTexture2DMultisampleEXT", "samples < 0"); // NOLINT
+ return error::kNoError;
+ }
+ DoFramebufferTexture2DMultisample(
+ target, attachment, textarget, texture, level, samples);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleTexStorage2DEXT(
+ uint32 immediate_data_size, const gles2::cmds::TexStorage2DEXT& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLsizei levels = static_cast<GLsizei>(c.levels);
+ GLenum internalFormat = static_cast<GLenum>(c.internalFormat);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ if (!validators_->texture_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexStorage2DEXT", target, "target");
+ return error::kNoError;
+ }
+ if (levels < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage2DEXT", "levels < 0");
+ return error::kNoError;
+ }
+ if (!validators_->texture_internal_format_storage.IsValid(internalFormat)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexStorage2DEXT", internalFormat,
+ "internalFormat");
+ return error::kNoError;
+ }
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage2DEXT", "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage2DEXT", "height < 0");
+ return error::kNoError;
+ }
+ DoTexStorage2DEXT(target, levels, internalFormat, width, height);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenQueriesEXT(
+ uint32 immediate_data_size, const gles2::cmds::GenQueriesEXT& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* queries = GetSharedMemoryAs<GLuint*>(
+ c.queries_shm_id, c.queries_shm_offset, data_size);
+ if (queries == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenQueriesEXTHelper(n, queries)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenQueriesEXTImmediate(
+ uint32 immediate_data_size, const gles2::cmds::GenQueriesEXTImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* queries = GetImmediateDataAs<GLuint*>(
+ c, data_size, immediate_data_size);
+ if (queries == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenQueriesEXTHelper(n, queries)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteQueriesEXT(
+ uint32 immediate_data_size, const gles2::cmds::DeleteQueriesEXT& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* queries = GetSharedMemoryAs<const GLuint*>(
+ c.queries_shm_id, c.queries_shm_offset, data_size);
+ if (queries == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteQueriesEXTHelper(n, queries);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteQueriesEXTImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::DeleteQueriesEXTImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* queries = GetImmediateDataAs<const GLuint*>(
+ c, data_size, immediate_data_size);
+ if (queries == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteQueriesEXTHelper(n, queries);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleInsertEventMarkerEXT(
+ uint32 immediate_data_size, const gles2::cmds::InsertEventMarkerEXT& c) {
+ GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
+ Bucket* bucket = GetBucket(bucket_id);
+ if (!bucket || bucket->size() == 0) {
+ return error::kInvalidArguments;
+ }
+ std::string str;
+ if (!bucket->GetAsString(&str)) {
+ return error::kInvalidArguments;
+ }
+ DoInsertEventMarkerEXT(0, str.c_str());
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandlePushGroupMarkerEXT(
+ uint32 immediate_data_size, const gles2::cmds::PushGroupMarkerEXT& c) {
+ GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
+ Bucket* bucket = GetBucket(bucket_id);
+ if (!bucket || bucket->size() == 0) {
+ return error::kInvalidArguments;
+ }
+ std::string str;
+ if (!bucket->GetAsString(&str)) {
+ return error::kInvalidArguments;
+ }
+ DoPushGroupMarkerEXT(0, str.c_str());
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandlePopGroupMarkerEXT(
+ uint32 immediate_data_size, const gles2::cmds::PopGroupMarkerEXT& c) {
+ DoPopGroupMarkerEXT();
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenVertexArraysOES(
+ uint32 immediate_data_size, const gles2::cmds::GenVertexArraysOES& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* arrays = GetSharedMemoryAs<GLuint*>(
+ c.arrays_shm_id, c.arrays_shm_offset, data_size);
+ if (arrays == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenVertexArraysOESHelper(n, arrays)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGenVertexArraysOESImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::GenVertexArraysOESImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* arrays = GetImmediateDataAs<GLuint*>(
+ c, data_size, immediate_data_size);
+ if (arrays == NULL) {
+ return error::kOutOfBounds;
+ }
+ if (!GenVertexArraysOESHelper(n, arrays)) {
+ return error::kInvalidArguments;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteVertexArraysOES(
+ uint32 immediate_data_size, const gles2::cmds::DeleteVertexArraysOES& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* arrays = GetSharedMemoryAs<const GLuint*>(
+ c.arrays_shm_id, c.arrays_shm_offset, data_size);
+ if (arrays == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteVertexArraysOESHelper(n, arrays);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteVertexArraysOESImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::DeleteVertexArraysOESImmediate& c) {
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* arrays = GetImmediateDataAs<const GLuint*>(
+ c, data_size, immediate_data_size);
+ if (arrays == NULL) {
+ return error::kOutOfBounds;
+ }
+ DeleteVertexArraysOESHelper(n, arrays);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleIsVertexArrayOES(
+ uint32 immediate_data_size, const gles2::cmds::IsVertexArrayOES& c) {
+ GLuint array = c.array;
+ typedef cmds::IsVertexArrayOES::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ *result_dst = DoIsVertexArrayOES(array);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBindVertexArrayOES(
+ uint32 immediate_data_size, const gles2::cmds::BindVertexArrayOES& c) {
+ GLuint array = c.array;
+ DoBindVertexArrayOES(array);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleSwapBuffers(
+ uint32 immediate_data_size, const gles2::cmds::SwapBuffers& c) {
+ DoSwapBuffers();
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetMaxValueInBufferCHROMIUM(
+ uint32 immediate_data_size,
+ const gles2::cmds::GetMaxValueInBufferCHROMIUM& c) {
+ GLuint buffer_id = c.buffer_id;
+ GLsizei count = static_cast<GLsizei>(c.count);
+ GLenum type = static_cast<GLenum>(c.type);
+ GLuint offset = static_cast<GLuint>(c.offset);
+ typedef cmds::GetMaxValueInBufferCHROMIUM::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ if (count < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glGetMaxValueInBufferCHROMIUM", "count < 0");
+ return error::kNoError;
+ }
+ if (!validators_->get_max_index_type.IsValid(type)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetMaxValueInBufferCHROMIUM", type,
+ "type");
+ return error::kNoError;
+ }
+ *result_dst = DoGetMaxValueInBufferCHROMIUM(buffer_id, count, type, offset);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleTexImageIOSurface2DCHROMIUM(
+ uint32 immediate_data_size,
+ const gles2::cmds::TexImageIOSurface2DCHROMIUM& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ GLuint ioSurfaceId = static_cast<GLuint>(c.ioSurfaceId);
+ GLuint plane = static_cast<GLuint>(c.plane);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexImageIOSurface2DCHROMIUM", target,
+ "target");
+ return error::kNoError;
+ }
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glTexImageIOSurface2DCHROMIUM", "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glTexImageIOSurface2DCHROMIUM", "height < 0");
+ return error::kNoError;
+ }
+ DoTexImageIOSurface2DCHROMIUM(target, width, height, ioSurfaceId, plane);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCopyTextureCHROMIUM(
+ uint32 immediate_data_size, const gles2::cmds::CopyTextureCHROMIUM& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum source_id = static_cast<GLenum>(c.source_id);
+ GLenum dest_id = static_cast<GLenum>(c.dest_id);
+ GLint level = static_cast<GLint>(c.level);
+ GLint internalformat = static_cast<GLint>(c.internalformat);
+ GLenum dest_type = static_cast<GLenum>(c.dest_type);
+ if (!validators_->texture_internal_format.IsValid(internalformat)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "internalformat GL_INVALID_VALUE"); // NOLINT
+ return error::kNoError;
+ }
+ if (!validators_->pixel_type.IsValid(dest_type)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glCopyTextureCHROMIUM", dest_type,
+ "dest_type");
+ return error::kNoError;
+ }
+ DoCopyTextureCHROMIUM(
+ target, source_id, dest_id, level, internalformat, dest_type);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleProduceTextureCHROMIUM(
+ uint32 immediate_data_size, const gles2::cmds::ProduceTextureCHROMIUM& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLbyte* mailbox = GetSharedMemoryAs<const GLbyte*>(
+ c.mailbox_shm_id, c.mailbox_shm_offset, data_size);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glProduceTextureCHROMIUM", target,
+ "target");
+ return error::kNoError;
+ }
+ if (mailbox == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoProduceTextureCHROMIUM(target, mailbox);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleProduceTextureCHROMIUMImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::ProduceTextureCHROMIUMImmediate& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLbyte* mailbox = GetImmediateDataAs<const GLbyte*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glProduceTextureCHROMIUM", target,
+ "target");
+ return error::kNoError;
+ }
+ if (mailbox == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoProduceTextureCHROMIUM(target, mailbox);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleConsumeTextureCHROMIUM(
+ uint32 immediate_data_size, const gles2::cmds::ConsumeTextureCHROMIUM& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLbyte* mailbox = GetSharedMemoryAs<const GLbyte*>(
+ c.mailbox_shm_id, c.mailbox_shm_offset, data_size);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glConsumeTextureCHROMIUM", target,
+ "target");
+ return error::kNoError;
+ }
+ if (mailbox == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoConsumeTextureCHROMIUM(target, mailbox);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleConsumeTextureCHROMIUMImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::ConsumeTextureCHROMIUMImmediate& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLbyte* mailbox = GetImmediateDataAs<const GLbyte*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glConsumeTextureCHROMIUM", target,
+ "target");
+ return error::kNoError;
+ }
+ if (mailbox == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoConsumeTextureCHROMIUM(target, mailbox);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBindTexImage2DCHROMIUM(
+ uint32 immediate_data_size, const gles2::cmds::BindTexImage2DCHROMIUM& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLint imageId = static_cast<GLint>(c.imageId);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindTexImage2DCHROMIUM", target,
+ "target");
+ return error::kNoError;
+ }
+ DoBindTexImage2DCHROMIUM(target, imageId);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleReleaseTexImage2DCHROMIUM(
+ uint32 immediate_data_size,
+ const gles2::cmds::ReleaseTexImage2DCHROMIUM& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLint imageId = static_cast<GLint>(c.imageId);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM("glReleaseTexImage2DCHROMIUM", target,
+ "target");
+ return error::kNoError;
+ }
+ DoReleaseTexImage2DCHROMIUM(target, imageId);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleTraceEndCHROMIUM(
+ uint32 immediate_data_size, const gles2::cmds::TraceEndCHROMIUM& c) {
+ DoTraceEndCHROMIUM();
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDiscardFramebufferEXT(
+ uint32 immediate_data_size, const gles2::cmds::DiscardFramebufferEXT& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLenum* attachments = GetSharedMemoryAs<const GLenum*>(
+ c.attachments_shm_id, c.attachments_shm_offset, data_size);
+ if (count < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glDiscardFramebufferEXT", "count < 0");
+ return error::kNoError;
+ }
+ if (attachments == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoDiscardFramebufferEXT(target, count, attachments);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDiscardFramebufferEXTImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::DiscardFramebufferEXTImmediate& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLenum* attachments = GetImmediateDataAs<const GLenum*>(
+ c, data_size, immediate_data_size);
+ if (count < 0) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "glDiscardFramebufferEXT", "count < 0");
+ return error::kNoError;
+ }
+ if (attachments == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoDiscardFramebufferEXT(target, count, attachments);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDrawBuffersEXT(
+ uint32 immediate_data_size, const gles2::cmds::DrawBuffersEXT& c) {
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLenum* bufs = GetSharedMemoryAs<const GLenum*>(
+ c.bufs_shm_id, c.bufs_shm_offset, data_size);
+ if (count < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDrawBuffersEXT", "count < 0");
+ return error::kNoError;
+ }
+ if (bufs == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoDrawBuffersEXT(count, bufs);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDrawBuffersEXTImmediate(
+ uint32 immediate_data_size,
+ const gles2::cmds::DrawBuffersEXTImmediate& c) {
+ GLsizei count = static_cast<GLsizei>(c.count);
+ uint32 data_size;
+ if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLenum* bufs = GetImmediateDataAs<const GLenum*>(
+ c, data_size, immediate_data_size);
+ if (count < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDrawBuffersEXT", "count < 0");
+ return error::kNoError;
+ }
+ if (bufs == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoDrawBuffersEXT(count, bufs);
+ return error::kNoError;
+}
+
+
+bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) {
+ switch (cap) {
+ case GL_BLEND:
+ state_.enable_flags.blend = enabled;
+ return true;
+ case GL_CULL_FACE:
+ state_.enable_flags.cull_face = enabled;
+ return true;
+ case GL_DEPTH_TEST:
+ if (state_.enable_flags.depth_test != enabled) {
+ state_.enable_flags.depth_test = enabled;
+ framebuffer_state_.clear_state_dirty = true;
+ }
+ return false;
+ case GL_DITHER:
+ state_.enable_flags.dither = enabled;
+ return true;
+ case GL_POLYGON_OFFSET_FILL:
+ state_.enable_flags.polygon_offset_fill = enabled;
+ return true;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE:
+ state_.enable_flags.sample_alpha_to_coverage = enabled;
+ return true;
+ case GL_SAMPLE_COVERAGE:
+ state_.enable_flags.sample_coverage = enabled;
+ return true;
+ case GL_SCISSOR_TEST:
+ if (state_.enable_flags.scissor_test != enabled) {
+ state_.enable_flags.scissor_test = enabled;
+ framebuffer_state_.clear_state_dirty = true;
+ }
+ return false;
+ case GL_STENCIL_TEST:
+ if (state_.enable_flags.stencil_test != enabled) {
+ state_.enable_flags.stencil_test = enabled;
+ framebuffer_state_.clear_state_dirty = true;
+ }
+ return false;
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_
+