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. |