Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 169403005: command_buffer: Implement path rendering functions for CHROMIUM_path_rendering (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@nv-pr-02-texgen
Patch Set: improve parameter validation and write up the extension .txt file Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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.

Powered by Google App Engine
This is Rietveld 408576698