Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| index a2822fc7e4816cc7e4b4db4e180dbd0c6e3b23ef..3fc3dfc8f5660eefa917be90b10d5a2da7cd1b44 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -48,6 +48,7 @@ |
| #include "gpu/command_buffer/service/image_manager.h" |
| #include "gpu/command_buffer/service/mailbox_manager.h" |
| #include "gpu/command_buffer/service/memory_tracking.h" |
| +#include "gpu/command_buffer/service/path_manager.h" |
| #include "gpu/command_buffer/service/program_manager.h" |
| #include "gpu/command_buffer/service/query_manager.h" |
| #include "gpu/command_buffer/service/renderbuffer_manager.h" |
| @@ -739,6 +740,8 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); |
| bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); |
| void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); |
| + bool GenPathsCHROMIUMHelper(GLsizei range, const GLuint* client_ids); |
| + void DeletePathsCHROMIUMHelper(GLuint path, GLsizei range); |
| // Helper for async upload token completion notification callback. |
| base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token, |
| @@ -764,6 +767,8 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| return group_->framebuffer_manager(); |
| } |
| + PathManager* path_manager() { return group_->path_manager(); } |
| + |
| ProgramManager* program_manager() { |
| return group_->program_manager(); |
| } |
| @@ -828,6 +833,8 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| texture_manager()->RemoveTexture(client_id); |
| } |
| + GLuint GetPath(GLuint client_id, error::Error* path_error); |
| + |
| // Get the size (in pixels) of the currently bound frame buffer (either FBO |
| // or regular back buffer). |
| gfx::Size GetBoundReadFrameBufferSize(); |
| @@ -1628,6 +1635,16 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| void ProcessPendingReadPixels(); |
| void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); |
| + error::Error PrepareInstancedPathCommand(uint32 num_paths, |
| + uint32 paths_shm_id, |
| + uint32 paths_shm_offset, |
| + GLuint path_base, |
| + GLenum transform_type, |
| + uint32 transforms_shm_id, |
| + uint32 transforms_shm_offset, |
| + GLuint** out_paths, |
| + const GLfloat** out_transforms); |
| + |
| // Generate a member function prototype for each command in an automated and |
| // typesafe way. |
| #define GLES2_CMD_OP(name) \ |
| @@ -2758,6 +2775,14 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() { |
| #if (ANGLE_SH_VERSION >= 123) |
| resources.EXT_shader_texture_lod = |
| features().ext_shader_texture_lod ? 1 : 0; |
| +#if (ANGLE_SH_VERSION >= 124) |
| + if (features().chromium_path_rendering) { |
| + resources.CHROMIUM_path_rendering = 1; |
| + GLint value = 0; |
| + glGetIntegerv(GL_MAX_TEXTURE_COORDS, &value); |
| + resources.MaxTextureCoords = value; |
| + } |
| +#endif |
| #endif |
| } |
| @@ -2870,6 +2895,25 @@ bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) { |
| return true; |
| } |
| +bool GLES2DecoderImpl::GenPathsCHROMIUMHelper(GLsizei range, |
| + const GLuint* client_ids) { |
| + for (GLsizei ii = 0; ii < range; ++ii) { |
| + if (path_manager()->GetPath(client_ids[ii])) { |
| + return false; |
| + } |
| + } |
| + |
| + GLuint n = glGenPathsNV(range); |
| + for (GLsizei ii = 0; ii < range; ++ii) { |
| + path_manager()->CreatePath(client_ids[ii], n + ii); |
| + } |
| + return true; |
| +} |
| + |
| +void GLES2DecoderImpl::DeletePathsCHROMIUMHelper(GLuint path, GLsizei range) { |
| + path_manager()->RemovePaths(path, range); |
| +} |
| + |
| void GLES2DecoderImpl::DeleteBuffersHelper( |
| GLsizei n, const GLuint* client_ids) { |
| for (GLsizei ii = 0; ii < n; ++ii) { |
| @@ -4342,6 +4386,12 @@ bool GLES2DecoderImpl::GetHelper( |
| params[0] = renderbuffer_manager()->max_renderbuffer_size(); |
| } |
| return true; |
| + case GL_MAX_TEXTURE_COORDS: |
|
piman
2014/04/24 22:26:36
_CHROMIUM
piman
2014/04/24 22:26:36
can you DCHECK that the extension is present in th
|
| + *num_written = 1; |
| + if (params) { |
| + glGetIntegerv(GL_MAX_TEXTURE_COORDS, params); |
| + } |
| + return true; |
| case GL_MAX_TEXTURE_SIZE: |
| *num_written = 1; |
| if (params) { |
| @@ -10785,6 +10835,675 @@ void GLES2DecoderImpl::OnOutOfMemoryError() { |
| } |
| } |
| +GLuint GLES2DecoderImpl::GetPath(GLuint client_id, error::Error* path_error) { |
| + GLuint service_id = 0; |
| + // FIXME: currently we do not create paths if they are not present. |
| + if (!path_manager()->GetPath(client_id, &service_id)) { |
| + *path_error = error::kInvalidArguments; |
| + return 0; |
| + } |
| + return service_id; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandleGenPathsCHROMIUM( |
|
piman
2014/04/24 22:26:36
We'll want unit tests for all these new functions,
|
| + uint32 immediate_data_size, |
| + const gles2::cmds::GenPathsCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGenPathsCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + |
| + GLsizei range = static_cast<GLsizei>(c.range); |
| + uint32 data_size; |
| + if (!SafeMultiplyUint32(range, sizeof(GLuint), &data_size)) { |
| + return error::kOutOfBounds; |
| + } |
| + GLuint* client_ids = GetSharedMemoryAs<GLuint*>( |
| + c.client_ids_shm_id, c.client_ids_shm_offset, data_size); |
| + if (client_ids == NULL) { |
| + return error::kOutOfBounds; |
| + } |
| + if (!GenPathsCHROMIUMHelper(range, client_ids)) { |
| + return error::kInvalidArguments; |
| + } |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandlePathCommandsCHROMIUM( |
| + uint32 immediate_data_size, |
| + const cmds::PathCommandsCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glPathCommandsCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + |
| + error::Error path_error = error::kNoError; |
| + GLuint service_id = GetPath(static_cast<GLuint>(c.path), &path_error); |
| + if (path_error != error::kNoError) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glPathCommandsCHROMIUM", |
| + "invalid path name"); |
| + return error::kNoError; |
| + } |
| + |
| + GLsizei numCommands = static_cast<GLsizei>(c.numCommands); |
|
piman
2014/04/24 22:26:36
nit: please use unix_style for local variables (he
|
| + uint32 commands_shm_id = static_cast<uint32>(c.commands_shm_id); |
| + uint32 commands_shm_offset = static_cast<uint32>(c.commands_shm_offset); |
| + |
| + const GLubyte* commands = NULL; |
| + if (commands_shm_id != 0 || commands_shm_offset != 0) { |
| + commands = GetSharedMemoryAs<const GLubyte*>( |
| + commands_shm_id, commands_shm_offset, numCommands); |
| + if (!commands) { |
| + return error::kOutOfBounds; |
| + } |
| + } |
| + |
| + GLenum coordType = static_cast<GLenum>(c.coordType); |
| + GLsizei numCoords = static_cast<GLsizei>(c.numCoords); |
| + uint32 coords_shm_id = static_cast<uint32>(c.coords_shm_id); |
| + uint32 coords_shm_offset = static_cast<uint32>(c.coords_shm_offset); |
| + uint32 coords_size = |
| + GLES2Util::GetGLTypeSizeForTexturesAndBuffers(coordType) * numCoords; |
| + |
| + const void* coords = NULL; |
| + if (coords_shm_id != 0 || coords_shm_offset != 0) { |
| + coords = GetSharedMemoryAs<const void*>( |
| + coords_shm_id, coords_shm_offset, coords_size); |
| + if (!coords) { |
| + return error::kOutOfBounds; |
| + } |
| + } |
| + |
| + glPathCommandsNV( |
| + service_id, numCommands, commands, numCoords, coordType, coords); |
|
piman
2014/04/24 22:26:36
I would like us to validate the syntax of the comm
|
| + |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandlePathParameterfCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::PathParameterfCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glPathParameterfCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + |
| + error::Error path_error = error::kNoError; |
| + GLuint service_id = GetPath(static_cast<GLuint>(c.path), &path_error); |
| + if (path_error != error::kNoError) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glPathParameterfCHROMIUM", |
| + "invalid path name"); |
| + return error::kNoError; |
| + } |
| + |
| + GLenum pname = static_cast<GLenum>(c.pname); |
| + GLfloat value = static_cast<GLfloat>(c.value); |
| + |
| + if (!validators_->path_parameter.IsValid(pname)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glPathParameterfCHROMIUM", |
| + pname, "pname"); |
| + return error::kNoError; |
| + } |
| + |
| + // TODO: value not checked. |
|
piman
2014/04/24 22:26:36
We need to.
|
| + |
| + glPathParameterfNV(service_id, pname, value); |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandlePathParameteriCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::PathParameteriCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glPathParameteriCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + |
| + error::Error path_error = error::kNoError; |
| + GLuint service_id = GetPath(static_cast<GLuint>(c.path), &path_error); |
| + if (path_error != error::kNoError) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glPathParameteriCHROMIUM", |
| + "invalid path name"); |
| + return error::kNoError; |
| + } |
| + |
| + GLenum pname = static_cast<GLenum>(c.pname); |
| + GLint value = static_cast<GLint>(c.value); |
| + |
| + if (!validators_->path_parameter.IsValid(pname)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glPathParameteriCHROMIUM", |
| + pname, "pname"); |
| + return error::kNoError; |
| + } |
| + |
| + // TODO: value not checked. |
|
piman
2014/04/24 22:26:36
We need to.
|
| + |
| + glPathParameteriNV(service_id, pname, value); |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandleStencilFillPathCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::StencilFillPathCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glStencilFillPathCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + error::Error path_error = error::kNoError; |
| + GLuint service_id = GetPath(static_cast<GLuint>(c.path), &path_error); |
| + if (path_error != error::kNoError) { |
| + return error::kNoError; |
| + } |
| + |
| + GLenum fillMode = static_cast<GLenum>(c.fillMode); |
| + if (!validators_->path_fill_mode.IsValid(fillMode)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilFillPathCHROMIUM", |
| + fillMode, "fillMode"); |
| + return error::kNoError; |
| + } |
| + |
| + GLuint mask = static_cast<GLuint>(c.mask); |
| + ApplyDirtyState(); |
| + glStencilFillPathNV(service_id, fillMode, mask); |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::PrepareInstancedPathCommand( |
| + uint32 num_paths, |
| + uint32 paths_shm_id, |
| + uint32 paths_shm_offset, |
| + GLuint path_base, |
| + GLenum transform_type, |
| + uint32 transforms_shm_id, |
| + uint32 transforms_shm_offset, |
| + GLuint** out_paths, |
| + const GLfloat** out_transforms) { |
| + GLuint* paths = NULL; |
| + if (paths_shm_id != 0 || paths_shm_offset != 0) { |
| + paths = GetSharedMemoryAs<GLuint*>( |
| + paths_shm_id, paths_shm_offset, sizeof(GLuint) * num_paths); |
| + } |
| + if (!paths) { |
| + return error::kOutOfBounds; |
| + } |
| + |
| + uint32 num_transform_elements = |
| + GLES2Util::GetComponentCountForGLTransformType(transform_type) * |
| + num_paths; |
| + |
| + const GLfloat* transforms = NULL; |
| + if (transforms_shm_id != 0 || transforms_shm_offset != 0) { |
| + transforms = GetSharedMemoryAs<const GLfloat*>( |
| + transforms_shm_id, |
| + transforms_shm_offset, |
| + sizeof(GLfloat) * num_transform_elements); |
| + } |
| + if (!transforms) { |
| + return error::kOutOfBounds; |
| + } |
| + |
| + for (uint32_t i = 0; i < num_paths; ++i) { |
| + error::Error path_error; |
| + GLuint service_id = GetPath(paths[i] + path_base, &path_error); |
| + // Will use path 0 if the path is not found. This is in line |
| + // of the spec: missing paths will produce nothing, but does |
| + // not stop the instanced draw. |
| + paths[i] = service_id; |
| + } |
| + |
| + DCHECK((reinterpret_cast<uintptr_t>(paths) & 0x3) == 0); |
| + DCHECK((reinterpret_cast<uintptr_t>(transforms) & 0x3) == 0); |
| + |
| + *out_paths = paths; |
| + *out_transforms = transforms; |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandleStencilFillPathInstancedCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::StencilFillPathInstancedCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| + "glStencilFillPathInstancedCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + |
| + TRACE_EVENT0("gpu", |
| + "GLES2DecoderImpl::HandleStencilFillPathInstancedCHROMIUM"); |
| + |
| + GLsizei numPaths = static_cast<GLsizei>(c.numPaths); |
| + GLenum pathNameType = static_cast<GLenum>(c.pathNameType); |
| + uint32 paths_shm_id = static_cast<uint32>(c.paths_shm_id); |
| + uint32 paths_shm_offset = static_cast<uint32>(c.paths_shm_offset); |
| + GLuint pathBase = static_cast<GLuint>(c.pathBase); |
| + GLenum fillMode = static_cast<GLenum>(c.fillMode); |
| + GLuint mask = static_cast<GLuint>(c.mask); |
| + GLenum transformType = static_cast<GLenum>(c.transformType); |
| + uint32 transforms_shm_id = static_cast<uint32>(c.transformValues_shm_id); |
| + uint32 transforms_shm_offset = |
| + static_cast<uint32>(c.transformValues_shm_offset); |
| + |
| + if (numPaths < 0) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, |
| + "glCoverStrokePathInstancedCHROMIUM", |
| + "numPaths < 0"); |
| + return error::kNoError; |
| + } |
| + |
| + if (!validators_->path_name_type.IsValid(pathNameType)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilFillPathInstancedCHROMIUM", |
| + pathNameType, "pathNameType"); |
| + return error::kNoError; |
| + } |
| + |
| + if (!validators_->path_fill_mode.IsValid(fillMode)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilFillPathInstancedCHROMIUM", |
| + fillMode, "fillMode"); |
| + return error::kNoError; |
| + } |
| + |
| + |
| + if (!validators_->path_transform_type.IsValid(transformType)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilFillPathInstancedCHROMIUM", |
| + transformType, "transformType"); |
| + return error::kNoError; |
| + } |
| + |
| + DCHECK(pathNameType == GL_UNSIGNED_INT); |
| + |
| + GLuint* paths; |
| + const GLfloat* transforms; |
|
piman
2014/04/24 22:26:36
nit: there are paths in PrepareInstancedPathComman
|
| + |
| + error::Error prepare_error = |
| + PrepareInstancedPathCommand(static_cast<uint32_t>(numPaths), |
| + paths_shm_id, |
| + paths_shm_offset, |
| + pathBase, |
| + transformType, |
| + transforms_shm_id, |
| + transforms_shm_offset, |
| + &paths, |
| + &transforms); |
| + |
| + if (prepare_error != error::kNoError) { |
| + return prepare_error; |
| + } |
| + |
| + ApplyDirtyState(); |
| + glStencilFillPathInstancedNV(numPaths, |
| + GL_UNSIGNED_INT, |
| + paths, |
| + 0, |
| + fillMode, |
| + mask, |
| + transformType, |
| + transforms); |
| + |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandleStencilStrokePathCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::StencilStrokePathCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glStencilStrokePathCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + |
| + error::Error path_error = error::kNoError; |
| + GLuint service_id = GetPath(static_cast<GLuint>(c.path), &path_error); |
| + if (path_error != error::kNoError) { |
| + return error::kNoError; |
| + } |
| + GLint reference = static_cast<GLint>(c.reference); |
| + GLuint mask = static_cast<GLuint>(c.mask); |
| + ApplyDirtyState(); |
| + glStencilStrokePathNV(service_id, reference, mask); |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandleStencilStrokePathInstancedCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::StencilStrokePathInstancedCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| + "glStencilStrokePathInstancedCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + |
| + TRACE_EVENT0("gpu", |
| + "GLES2DecoderImpl::HandleStencilStrokePathInstancedCHROMIUM"); |
| + |
| + GLsizei numPaths = static_cast<GLsizei>(c.numPaths); |
| + GLenum pathNameType = static_cast<GLenum>(c.pathNameType); |
| + uint32 paths_shm_id = static_cast<uint32>(c.paths_shm_id); |
| + uint32 paths_shm_offset = static_cast<uint32>(c.paths_shm_offset); |
| + GLuint pathBase = static_cast<GLuint>(c.pathBase); |
| + GLuint ref = static_cast<GLuint>(c.ref); |
| + GLuint mask = static_cast<GLuint>(c.mask); |
| + GLenum transformType = static_cast<GLenum>(c.transformType); |
| + uint32 transforms_shm_id = static_cast<uint32>(c.transformValues_shm_id); |
| + uint32 transforms_shm_offset = |
| + static_cast<uint32>(c.transformValues_shm_offset); |
| + |
| + if (numPaths < 0) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, |
| + "glCoverStrokePathInstancedCHROMIUM", |
| + "numPaths < 0"); |
| + return error::kNoError; |
| + } |
| + |
| + if (!validators_->path_name_type.IsValid(pathNameType)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilStrokePathInstancedCHROMIUM", |
| + pathNameType, "pathNameType"); |
| + return error::kNoError; |
| + } |
| + |
| + if (!validators_->path_transform_type.IsValid(transformType)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilStrokePathInstancedCHROMIUM", |
| + transformType, "transformType"); |
| + return error::kNoError; |
| + } |
| + |
| + |
| + DCHECK(pathNameType == GL_UNSIGNED_INT); |
| + |
| + GLuint* paths; |
| + const GLfloat* transforms; |
| + |
| + error::Error prepare_error = |
| + PrepareInstancedPathCommand(static_cast<uint32_t>(numPaths), |
| + paths_shm_id, |
| + paths_shm_offset, |
| + pathBase, |
| + transformType, |
| + transforms_shm_id, |
| + transforms_shm_offset, |
| + &paths, |
| + &transforms); |
| + |
| + if (prepare_error != error::kNoError) { |
| + return prepare_error; |
| + } |
| + |
| + ApplyDirtyState(); |
| + glStencilStrokePathInstancedNV(numPaths, |
| + GL_UNSIGNED_INT, |
| + paths, |
| + 0, |
| + ref, |
| + mask, |
| + transformType, |
| + transforms); |
| + |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandlePathTexGenCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::PathTexGenCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glPathTexGenCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + |
| + TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePathTexGenCHROMIUM"); |
| + GLenum texCoordSet = static_cast<GLenum>(c.texCoordSet); |
| + GLenum genMode = static_cast<GLenum>(c.genMode); |
| + GLint components = static_cast<GLint>(c.components); |
| + uint32 buffer_shm_id = static_cast<uint32>(c.coeffs_shm_id); |
| + uint32 buffer_shm_offset = static_cast<uint32>(c.coeffs_shm_offset); |
| + |
| + if (!validators_->path_gen_mode.IsValid(genMode)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glPathTexGenCHROMIUM", |
| + genMode, "genMode"); |
| + return error::kNoError; |
| + } |
| + |
| + if (components < 0 || components > 4) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glPathTexGenCHROMIUM", |
| + "4 < components < 0"); |
| + return error::kNoError; |
| + } |
| + |
| + uint32 coeffs_size = |
| + sizeof(GLfloat) * components * (genMode == GL_EYE_LINEAR_CHROMIUM ? 4 : 3); |
|
piman
2014/04/24 22:26:36
We'll want a safe multiply here. base::CheckedNume
|
| + |
| + if (coeffs_size < 0) { |
|
piman
2014/04/24 22:26:36
This can't happen.
|
| + return error::kOutOfBounds; |
| + } |
| + const GLfloat* coeffs = NULL; |
| + if (buffer_shm_id != 0 || buffer_shm_offset != 0) { |
| + coeffs = GetSharedMemoryAs<const GLfloat*>( |
| + buffer_shm_id, buffer_shm_offset, coeffs_size); |
| + if (!coeffs) { |
| + return error::kOutOfBounds; |
| + } |
| + } |
| + glPathTexGenNV(texCoordSet, genMode, components, coeffs); |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandleCoverFillPathCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::CoverFillPathCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCoverFillPathCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + |
| + GLenum coverMode = static_cast<GLenum>(c.coverMode); |
| + if (!validators_->path_cover_mode.IsValid(coverMode)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glCoverFillPathCHROMIUM", |
| + coverMode, "coverMode"); |
| + return error::kNoError; |
| + } |
| + |
| + error::Error path_error = error::kNoError; |
| + GLuint service_id = GetPath(static_cast<GLuint>(c.path), &path_error); |
| + if (path_error != error::kNoError) { |
| + return error::kNoError; |
| + } |
| + |
| + ApplyDirtyState(); |
| + glCoverFillPathNV(service_id, coverMode); |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandleCoverFillPathInstancedCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::CoverFillPathInstancedCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCoverFillPathInstancedCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + |
| + TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleCoverFillPathInstancedCHROMIUM"); |
| + |
| + GLsizei numPaths = static_cast<GLsizei>(c.numPaths); |
| + GLenum pathNameType = static_cast<GLenum>(c.pathNameType); |
| + uint32 paths_shm_id = static_cast<uint32>(c.paths_shm_id); |
| + uint32 paths_shm_offset = static_cast<uint32>(c.paths_shm_offset); |
| + GLuint pathBase = static_cast<GLuint>(c.pathBase); |
| + GLenum coverMode = static_cast<GLuint>(c.coverMode); |
| + GLenum transformType = static_cast<GLenum>(c.transformType); |
| + uint32 transforms_shm_id = static_cast<uint32>(c.transformValues_shm_id); |
| + uint32 transforms_shm_offset = |
| + static_cast<uint32>(c.transformValues_shm_offset); |
| + |
| + if (numPaths < 0) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, |
| + "glCoverStrokePathInstancedCHROMIUM", |
| + "numPaths < 0"); |
| + return error::kNoError; |
| + } |
| + |
| + if (!validators_->path_name_type.IsValid(pathNameType)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glCoverFillPathInstancedCHROMIUM", |
| + pathNameType, "pathNameType"); |
| + return error::kNoError; |
| + } |
| + |
| + if (!validators_->path_cover_mode_instanced.IsValid(coverMode)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glCoverFillPathInstancedCHROMIUM", |
| + coverMode, "coverMode"); |
| + return error::kNoError; |
| + } |
| + |
| + if (!validators_->path_transform_type.IsValid(transformType)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glCoverFillPathInstancedCHROMIUM", |
| + transformType, "transformType"); |
| + return error::kNoError; |
| + } |
| + |
| + DCHECK(pathNameType == GL_UNSIGNED_INT); |
| + |
| + GLuint* paths; |
| + const GLfloat* transforms; |
| + |
| + error::Error prepare_error = |
| + PrepareInstancedPathCommand(static_cast<uint32_t>(numPaths), |
| + paths_shm_id, |
| + paths_shm_offset, |
| + pathBase, |
| + transformType, |
| + transforms_shm_id, |
| + transforms_shm_offset, |
| + &paths, |
| + &transforms); |
| + |
| + if (prepare_error != error::kNoError) { |
| + return prepare_error; |
| + } |
| + |
| + ApplyDirtyState(); |
| + glCoverFillPathInstancedNV(numPaths, |
| + GL_UNSIGNED_INT, |
| + paths, |
| + 0, |
| + coverMode, |
| + transformType, |
| + transforms); |
| + |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandleCoverStrokePathCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::CoverStrokePathCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCoverStrokePathCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + error::Error path_error = error::kNoError; |
| + GLuint service_id = GetPath(static_cast<GLuint>(c.path), &path_error); |
| + if (path_error != error::kNoError) { |
| + return error::kNoError; |
| + } |
| + |
| + GLenum coverMode = static_cast<GLenum>(c.coverMode); |
| + if (!validators_->path_cover_mode.IsValid(coverMode)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glCoverStrokePathCHROMIUM", |
| + coverMode, "coverMode"); |
| + return error::kNoError; |
| + } |
| + |
| + ApplyDirtyState(); |
| + glCoverStrokePathNV(service_id, coverMode); |
| + return error::kNoError; |
| +} |
| + |
| +error::Error GLES2DecoderImpl::HandleCoverStrokePathInstancedCHROMIUM( |
| + uint32 immediate_data_size, |
| + const gles2::cmds::CoverStrokePathInstancedCHROMIUM& c) { |
| + if (!features().chromium_path_rendering) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| + "glCoverStrokePathInstancedCHROMIUM", |
| + "function not available"); |
| + return error::kNoError; |
| + } |
| + TRACE_EVENT0("gpu", |
| + "GLES2DecoderImpl::HandleCoverStrokePathInstancedCHROMIUM"); |
| + |
| + GLsizei numPaths = static_cast<GLsizei>(c.numPaths); |
| + GLenum pathNameType = static_cast<GLenum>(c.pathNameType); |
| + uint32 paths_shm_id = static_cast<uint32>(c.paths_shm_id); |
| + uint32 paths_shm_offset = static_cast<uint32>(c.paths_shm_offset); |
| + GLuint pathBase = static_cast<GLuint>(c.pathBase); |
| + GLenum coverMode = static_cast<GLuint>(c.coverMode); |
| + GLenum transformType = static_cast<GLenum>(c.transformType); |
| + uint32 transforms_shm_id = static_cast<uint32>(c.transformValues_shm_id); |
| + uint32 transforms_shm_offset = |
| + static_cast<uint32>(c.transformValues_shm_offset); |
| + |
| + if (numPaths < 0) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, |
| + "glCoverStrokePathInstancedCHROMIUM", |
| + "numPaths < 0"); |
| + return error::kNoError; |
| + } |
| + |
| + if (!validators_->path_name_type.IsValid(pathNameType)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glCoverStrokePathInstancedCHROMIUM", |
| + pathNameType, "pathNameType"); |
| + return error::kNoError; |
| + } |
| + |
| + if (!validators_->path_cover_mode_instanced.IsValid(coverMode)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glCoverStrokePathInstancedCHROMIUM", |
| + coverMode, "coverMode"); |
| + return error::kNoError; |
| + } |
| + |
| + if (!validators_->path_transform_type.IsValid(transformType)) { |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glCoverStrokePathInstancedCHROMIUM", |
| + transformType, "transformType"); |
| + return error::kNoError; |
| + } |
| + |
| + DCHECK(pathNameType == GL_UNSIGNED_INT); |
| + |
| + GLuint* paths; |
| + const GLfloat* transforms; |
| + |
| + error::Error prepare_error = |
| + PrepareInstancedPathCommand(static_cast<uint32_t>(numPaths), |
| + paths_shm_id, |
| + paths_shm_offset, |
| + pathBase, |
| + transformType, |
| + transforms_shm_id, |
| + transforms_shm_offset, |
| + &paths, |
| + &transforms); |
| + |
| + if (prepare_error != error::kNoError) { |
| + return prepare_error; |
| + } |
| + |
| + ApplyDirtyState(); |
| + glCoverStrokePathInstancedNV(numPaths, |
| + GL_UNSIGNED_INT, |
| + paths, |
| + 0, |
| + coverMode, |
| + transformType, |
| + transforms); |
| + return error::kNoError; |
| +} |
| + |
| // Include the auto-generated part of this file. We split this because it means |
| // we can easily edit the non-auto generated parts right here in this file |
| // instead of having to edit some template or the code generator. |