| 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 805cd70a0838bd2f0dc35f069bb52d0c98cd2c8d..e0b9112adf15ec09c0b0ec291f6194e3072430ac 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -217,6 +217,16 @@ bool CombineAdjacentRects(const gfx::Rect& rect1,
|
| return false;
|
| }
|
|
|
| +bool IsValidPathCommandMask(GLenum fill_mode, GLuint mask) {
|
| + /* The error INVALID_VALUE
|
| + is generated if /fillMode/ is COUNT_UP_CHROMIUM or COUNT_DOWN_CHROMIUM and
|
| + the effective /mask/+1 is not an integer power of two
|
| + */
|
| + return (fill_mode != GL_COUNT_UP_CHROMIUM &&
|
| + fill_mode != GL_COUNT_DOWN_CHROMIUM) ||
|
| + !GLES2Util::IsNPOT(mask + 1);
|
| +}
|
| +
|
| } // namespace
|
|
|
| class GLES2DecoderImpl;
|
| @@ -1877,6 +1887,31 @@ class GLES2DecoderImpl : public GLES2Decoder,
|
| void ProcessPendingReadPixels(bool did_finish);
|
| void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
|
|
|
| + bool PrepareInstancedPathCommand(GLsizei num_paths,
|
| + GLenum path_name_type,
|
| + uint32 paths_shm_id,
|
| + uint32 paths_shm_offset,
|
| + GLuint path_base,
|
| + GLenum transform_type,
|
| + uint32 transforms_shm_id,
|
| + uint32 transforms_shm_offset,
|
| + error::Error* out_error,
|
| + GLuint** out_paths,
|
| + const GLfloat** out_transforms,
|
| + scoped_ptr<GLuint[]>* out_temp_path_buffer);
|
| + template <typename T>
|
| + bool PrepareInstancedPathCommand(GLsizei num_paths,
|
| + uint32 paths_shm_id,
|
| + uint32 paths_shm_offset,
|
| + GLuint path_base,
|
| + GLenum transform_type,
|
| + uint32 transforms_shm_id,
|
| + uint32 transforms_shm_offset,
|
| + error::Error* out_error,
|
| + GLuint** out_paths,
|
| + const GLfloat** out_transforms,
|
| + scoped_ptr<GLuint[]>* out_temp_path_buffer);
|
| +
|
| // Generate a member function prototype for each command in an automated and
|
| // typesafe way.
|
| #define GLES2_CMD_OP(name) \
|
| @@ -14509,9 +14544,7 @@ error::Error GLES2DecoderImpl::HandleStencilFillPathCHROMIUM(
|
| return error::kNoError;
|
| }
|
| GLuint mask = static_cast<GLuint>(c.mask);
|
| - if ((fill_mode == GL_COUNT_UP_CHROMIUM ||
|
| - fill_mode == GL_COUNT_DOWN_CHROMIUM) &&
|
| - GLES2Util::IsNPOT(mask + 1)) {
|
| + if (!IsValidPathCommandMask(fill_mode, mask)) {
|
| LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
|
| "mask + 1 is not power of two");
|
| return error::kNoError;
|
| @@ -14618,9 +14651,7 @@ error::Error GLES2DecoderImpl::HandleStencilThenCoverFillPathCHROMIUM(
|
| return error::kNoError;
|
| }
|
| GLuint mask = static_cast<GLuint>(c.mask);
|
| - if ((fill_mode == GL_COUNT_UP_CHROMIUM ||
|
| - fill_mode == GL_COUNT_DOWN_CHROMIUM) &&
|
| - GLES2Util::IsNPOT(mask + 1)) {
|
| + if (!IsValidPathCommandMask(fill_mode, mask)) {
|
| LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
|
| "mask + 1 is not power of two");
|
| return error::kNoError;
|
| @@ -14667,6 +14698,572 @@ error::Error GLES2DecoderImpl::HandleStencilThenCoverStrokePathCHROMIUM(
|
| return error::kNoError;
|
| }
|
|
|
| +bool GLES2DecoderImpl::PrepareInstancedPathCommand(
|
| + GLsizei num_paths,
|
| + GLenum path_name_type,
|
| + uint32 paths_shm_id,
|
| + uint32 paths_shm_offset,
|
| + GLuint path_base,
|
| + GLenum transform_type,
|
| + uint32 transforms_shm_id,
|
| + uint32 transforms_shm_offset,
|
| + error::Error* out_error,
|
| + GLuint** out_paths,
|
| + const GLfloat** out_transforms,
|
| + scoped_ptr<GLuint[]>* out_temp_path_buffer) {
|
| + if (path_name_type == GL_BYTE) {
|
| + DCHECK(validators_->path_name_type.IsValid(path_name_type));
|
| + return PrepareInstancedPathCommand<GLbyte>(
|
| + num_paths, paths_shm_id, paths_shm_offset, path_base, transform_type,
|
| + transforms_shm_id, transforms_shm_offset, out_error, out_paths,
|
| + out_transforms, out_temp_path_buffer);
|
| + } else if (path_name_type == GL_UNSIGNED_BYTE) {
|
| + DCHECK(validators_->path_name_type.IsValid(path_name_type));
|
| + return PrepareInstancedPathCommand<GLubyte>(
|
| + num_paths, paths_shm_id, paths_shm_offset, path_base, transform_type,
|
| + transforms_shm_id, transforms_shm_offset, out_error, out_paths,
|
| + out_transforms, out_temp_path_buffer);
|
| + } else if (path_name_type == GL_SHORT) {
|
| + DCHECK(validators_->path_name_type.IsValid(path_name_type));
|
| + return PrepareInstancedPathCommand<GLshort>(
|
| + num_paths, paths_shm_id, paths_shm_offset, path_base, transform_type,
|
| + transforms_shm_id, transforms_shm_offset, out_error, out_paths,
|
| + out_transforms, out_temp_path_buffer);
|
| + } else if (path_name_type == GL_UNSIGNED_SHORT) {
|
| + DCHECK(validators_->path_name_type.IsValid(path_name_type));
|
| + return PrepareInstancedPathCommand<GLushort>(
|
| + num_paths, paths_shm_id, paths_shm_offset, path_base, transform_type,
|
| + transforms_shm_id, transforms_shm_offset, out_error, out_paths,
|
| + out_transforms, out_temp_path_buffer);
|
| + } else if (path_name_type == GL_INT) {
|
| + DCHECK(validators_->path_name_type.IsValid(path_name_type));
|
| + return PrepareInstancedPathCommand<GLint>(
|
| + num_paths, paths_shm_id, paths_shm_offset, path_base, transform_type,
|
| + transforms_shm_id, transforms_shm_offset, out_error, out_paths,
|
| + out_transforms, out_temp_path_buffer);
|
| + } else if (path_name_type == GL_UNSIGNED_INT) {
|
| + DCHECK(validators_->path_name_type.IsValid(path_name_type));
|
| + return PrepareInstancedPathCommand<GLuint>(
|
| + num_paths, paths_shm_id, paths_shm_offset, path_base, transform_type,
|
| + transforms_shm_id, transforms_shm_offset, out_error, out_paths,
|
| + out_transforms, out_temp_path_buffer);
|
| + }
|
| +
|
| + DCHECK(!validators_->path_name_type.IsValid(path_name_type));
|
| + NOTREACHED();
|
| +
|
| + *out_error = error::kOutOfBounds;
|
| + return false;
|
| +}
|
| +
|
| +template <typename T>
|
| +bool GLES2DecoderImpl::PrepareInstancedPathCommand(
|
| + GLsizei num_paths,
|
| + uint32 paths_shm_id,
|
| + uint32 paths_shm_offset,
|
| + GLuint path_base,
|
| + GLenum transform_type,
|
| + uint32 transforms_shm_id,
|
| + uint32 transforms_shm_offset,
|
| + error::Error* out_error,
|
| + GLuint** out_paths,
|
| + const GLfloat** out_transforms,
|
| + scoped_ptr<GLuint[]>* out_temp_path_buffer) {
|
| + if (num_paths == 0) {
|
| + // No GL error, just nothing to do.
|
| + *out_error = error::kNoError;
|
| + return false;
|
| + }
|
| + uint32 paths_size = 0;
|
| + if (!SafeMultiplyUint32(num_paths, sizeof(T), &paths_size)) {
|
| + *out_error = error::kOutOfBounds;
|
| + return false;
|
| + }
|
| +
|
| + T* paths = NULL;
|
| + if (paths_shm_id != 0 || paths_shm_offset != 0)
|
| + paths = GetSharedMemoryAs<T*>(paths_shm_id, paths_shm_offset, paths_size);
|
| +
|
| + if (!paths) {
|
| + *out_error = error::kOutOfBounds;
|
| + return false;
|
| + }
|
| +
|
| + const GLfloat* transforms = NULL;
|
| +
|
| + if (transform_type != GL_NONE) {
|
| + uint32 transforms_component_count =
|
| + GLES2Util::GetComponentCountForGLTransformType(transform_type);
|
| + // Below multiplication will not overflow.
|
| + DCHECK(transforms_component_count <= 12);
|
| + uint32 one_transform_size = sizeof(GLfloat) * transforms_component_count;
|
| +
|
| + uint32 transforms_size = 0;
|
| + if (!SafeMultiplyUint32(one_transform_size, num_paths, &transforms_size)) {
|
| + *out_error = error::kOutOfBounds;
|
| + return false;
|
| + }
|
| + if (transforms_shm_id != 0 || transforms_shm_offset != 0)
|
| + transforms = GetSharedMemoryAs<const GLfloat*>(
|
| + transforms_shm_id, transforms_shm_offset, transforms_size);
|
| +
|
| + if (!transforms) {
|
| + *out_error = error::kOutOfBounds;
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + scoped_ptr<GLuint[]> temp_path_buffer;
|
| + GLuint* result_paths;
|
| + if (sizeof(T) == sizeof(GLuint)) {
|
| + result_paths = reinterpret_cast<GLuint*>(paths);
|
| + } else {
|
| + result_paths = new GLuint[num_paths];
|
| + temp_path_buffer.reset(result_paths);
|
| + }
|
| + bool has_paths = false;
|
| + for (GLsizei i = 0; i < num_paths; ++i) {
|
| + GLuint service_id = 0;
|
| + uint32 client_id = 0;
|
| + if (!SafeAddUint32(paths[i], path_base, &client_id)) {
|
| + *out_error = error::kOutOfBounds;
|
| + return false;
|
| + }
|
| +
|
| + if (path_manager()->GetPath(client_id, &service_id))
|
| + has_paths = true;
|
| +
|
| + // Will use path 0 if the path is not found. This is in line
|
| + // of the spec: missing paths will produce nothing, let
|
| + // the instanced draw continue.
|
| + result_paths[i] = service_id;
|
| + }
|
| +
|
| + if (!has_paths) {
|
| + *out_error = error::kNoError;
|
| + return false;
|
| + }
|
| + *out_error = error::kNoError;
|
| + *out_paths = result_paths;
|
| + *out_transforms = transforms;
|
| + out_temp_path_buffer->swap(temp_path_buffer);
|
| + return true;
|
| +}
|
| +
|
| +error::Error GLES2DecoderImpl::HandleStencilFillPathInstancedCHROMIUM(
|
| + uint32 immediate_data_size,
|
| + const void* cmd_data) {
|
| + static const char kFunctionName[] = "glStencilFillPathInstancedCHROMIUM";
|
| + const gles2::cmds::StencilFillPathInstancedCHROMIUM& c =
|
| + *static_cast<const gles2::cmds::StencilFillPathInstancedCHROMIUM*>(
|
| + cmd_data);
|
| + if (!features().chromium_path_rendering) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
|
| + "function not available");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
|
| + if (num_paths < 0) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "numPaths < 0");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum path_name_type = static_cast<GLsizei>(c.pathNameType);
|
| + if (!validators_->path_name_type.IsValid(path_name_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, path_name_type,
|
| + "pathNameType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum fill_mode = static_cast<GLenum>(c.fillMode);
|
| + if (!validators_->path_fill_mode.IsValid(fill_mode)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, fill_mode, "fillMode");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLuint mask = static_cast<GLuint>(c.mask);
|
| + if (!IsValidPathCommandMask(fill_mode, mask)) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
|
| + "mask is not power of two");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum transform_type = static_cast<GLenum>(c.transformType);
|
| + if (!validators_->path_transform_type.IsValid(transform_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, transform_type,
|
| + "transformType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLuint path_base = static_cast<GLuint>(c.pathBase);
|
| +
|
| + uint32 paths_shm_id = static_cast<uint32>(c.paths_shm_id);
|
| + uint32 paths_shm_offset = static_cast<uint32>(c.paths_shm_offset);
|
| + uint32 transforms_shm_id = static_cast<uint32>(c.transformValues_shm_id);
|
| + uint32 transforms_shm_offset =
|
| + static_cast<uint32>(c.transformValues_shm_offset);
|
| +
|
| + GLuint* paths = NULL;
|
| + const GLfloat* transforms = NULL;
|
| + error::Error prepare_error = error::kNoError;
|
| + scoped_ptr<GLuint[]> temp_path_buffer;
|
| + if (!PrepareInstancedPathCommand(
|
| + num_paths, path_name_type, paths_shm_id, paths_shm_offset, path_base,
|
| + transform_type, transforms_shm_id, transforms_shm_offset,
|
| + &prepare_error, &paths, &transforms, &temp_path_buffer)) {
|
| + return prepare_error;
|
| + }
|
| +
|
| + ApplyDirtyState();
|
| + glStencilFillPathInstancedNV(num_paths, path_name_type, paths, 0, fill_mode,
|
| + mask, transform_type, transforms);
|
| +
|
| + return error::kNoError;
|
| +}
|
| +
|
| +error::Error GLES2DecoderImpl::HandleStencilStrokePathInstancedCHROMIUM(
|
| + uint32 immediate_data_size,
|
| + const void* cmd_data) {
|
| + static const char kFunctionName[] = "glStencilStrokePathInstancedCHROMIUM";
|
| + const gles2::cmds::StencilStrokePathInstancedCHROMIUM& c =
|
| + *static_cast<const gles2::cmds::StencilStrokePathInstancedCHROMIUM*>(
|
| + cmd_data);
|
| + if (!features().chromium_path_rendering) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
|
| + "function not available");
|
| + return error::kNoError;
|
| + }
|
| + GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
|
| + if (num_paths < 0) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "numPaths < 0");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum path_name_type = static_cast<GLsizei>(c.pathNameType);
|
| + if (!validators_->path_name_type.IsValid(path_name_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, path_name_type,
|
| + "pathNameType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum transform_type = static_cast<GLenum>(c.transformType);
|
| + if (!validators_->path_transform_type.IsValid(transform_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, transform_type,
|
| + "transformType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLuint path_base = static_cast<GLuint>(c.pathBase);
|
| + GLuint ref = static_cast<GLuint>(c.reference);
|
| + GLuint mask = static_cast<GLuint>(c.mask);
|
| +
|
| + uint32 paths_shm_id = static_cast<uint32>(c.paths_shm_id);
|
| + uint32 paths_shm_offset = static_cast<uint32>(c.paths_shm_offset);
|
| + uint32 transforms_shm_id = static_cast<uint32>(c.transformValues_shm_id);
|
| + uint32 transforms_shm_offset =
|
| + static_cast<uint32>(c.transformValues_shm_offset);
|
| +
|
| + GLuint* paths = NULL;
|
| + const GLfloat* transforms = NULL;
|
| + error::Error prepare_error = error::kNoError;
|
| + scoped_ptr<GLuint[]> temp_path_buffer;
|
| + if (!PrepareInstancedPathCommand(
|
| + num_paths, path_name_type, paths_shm_id, paths_shm_offset, path_base,
|
| + transform_type, transforms_shm_id, transforms_shm_offset,
|
| + &prepare_error, &paths, &transforms, &temp_path_buffer)) {
|
| + return prepare_error;
|
| + }
|
| +
|
| + ApplyDirtyState();
|
| + glStencilStrokePathInstancedNV(num_paths, path_name_type, paths, 0, ref, mask,
|
| + transform_type, transforms);
|
| +
|
| + return error::kNoError;
|
| +}
|
| +
|
| +error::Error GLES2DecoderImpl::HandleCoverFillPathInstancedCHROMIUM(
|
| + uint32 immediate_data_size,
|
| + const void* cmd_data) {
|
| + static const char kFunctionName[] = "glCoverFillPathInstancedCHROMIUM";
|
| + const gles2::cmds::CoverFillPathInstancedCHROMIUM& c =
|
| + *static_cast<const gles2::cmds::CoverFillPathInstancedCHROMIUM*>(
|
| + cmd_data);
|
| + if (!features().chromium_path_rendering) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
|
| + "function not available");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
|
| + if (num_paths < 0) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "numPaths < 0");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum path_name_type = static_cast<GLsizei>(c.pathNameType);
|
| + if (!validators_->path_name_type.IsValid(path_name_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, path_name_type,
|
| + "pathNameType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum cover_mode = static_cast<GLuint>(c.coverMode);
|
| + if (!validators_->path_instanced_cover_mode.IsValid(cover_mode)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum transform_type = static_cast<GLenum>(c.transformType);
|
| + if (!validators_->path_transform_type.IsValid(transform_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, transform_type,
|
| + "transformType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLuint path_base = static_cast<GLuint>(c.pathBase);
|
| +
|
| + uint32 paths_shm_id = static_cast<uint32>(c.paths_shm_id);
|
| + uint32 paths_shm_offset = static_cast<uint32>(c.paths_shm_offset);
|
| + uint32 transforms_shm_id = static_cast<uint32>(c.transformValues_shm_id);
|
| + uint32 transforms_shm_offset =
|
| + static_cast<uint32>(c.transformValues_shm_offset);
|
| +
|
| + GLuint* paths = NULL;
|
| + const GLfloat* transforms = NULL;
|
| + error::Error prepare_error = error::kNoError;
|
| + scoped_ptr<GLuint[]> temp_path_buffer;
|
| + if (!PrepareInstancedPathCommand(
|
| + num_paths, path_name_type, paths_shm_id, paths_shm_offset, path_base,
|
| + transform_type, transforms_shm_id, transforms_shm_offset,
|
| + &prepare_error, &paths, &transforms, &temp_path_buffer)) {
|
| + return prepare_error;
|
| + }
|
| +
|
| + ApplyDirtyState();
|
| + glCoverFillPathInstancedNV(num_paths, path_name_type, paths, 0, cover_mode,
|
| + transform_type, transforms);
|
| +
|
| + return error::kNoError;
|
| +}
|
| +
|
| +error::Error GLES2DecoderImpl::HandleCoverStrokePathInstancedCHROMIUM(
|
| + uint32 immediate_data_size,
|
| + const void* cmd_data) {
|
| + static const char kFunctionName[] = "glCoverStrokePathInstancedCHROMIUM";
|
| + const gles2::cmds::CoverStrokePathInstancedCHROMIUM& c =
|
| + *static_cast<const gles2::cmds::CoverStrokePathInstancedCHROMIUM*>(
|
| + cmd_data);
|
| + if (!features().chromium_path_rendering) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
|
| + "function not available");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
|
| + if (num_paths < 0) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "numPaths < 0");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum path_name_type = static_cast<GLsizei>(c.pathNameType);
|
| + if (!validators_->path_name_type.IsValid(path_name_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, path_name_type,
|
| + "pathNameType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum cover_mode = static_cast<GLenum>(c.coverMode);
|
| + if (!validators_->path_instanced_cover_mode.IsValid(cover_mode)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum transform_type = static_cast<GLenum>(c.transformType);
|
| + if (!validators_->path_transform_type.IsValid(transform_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, transform_type,
|
| + "transformType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLuint path_base = static_cast<GLuint>(c.pathBase);
|
| +
|
| + uint32 paths_shm_id = static_cast<uint32>(c.paths_shm_id);
|
| + uint32 paths_shm_offset = static_cast<uint32>(c.paths_shm_offset);
|
| + uint32 transforms_shm_id = static_cast<uint32>(c.transformValues_shm_id);
|
| + uint32 transforms_shm_offset =
|
| + static_cast<uint32>(c.transformValues_shm_offset);
|
| +
|
| + GLuint* paths = NULL;
|
| + const GLfloat* transforms = NULL;
|
| + error::Error prepare_error = error::kNoError;
|
| + scoped_ptr<GLuint[]> temp_path_buffer;
|
| + if (!PrepareInstancedPathCommand(
|
| + num_paths, path_name_type, paths_shm_id, paths_shm_offset, path_base,
|
| + transform_type, transforms_shm_id, transforms_shm_offset,
|
| + &prepare_error, &paths, &transforms, &temp_path_buffer)) {
|
| + return prepare_error;
|
| + }
|
| +
|
| + ApplyDirtyState();
|
| + glCoverStrokePathInstancedNV(num_paths, path_name_type, paths, 0, cover_mode,
|
| + transform_type, transforms);
|
| +
|
| + return error::kNoError;
|
| +}
|
| +
|
| +error::Error GLES2DecoderImpl::HandleStencilThenCoverFillPathInstancedCHROMIUM(
|
| + uint32 immediate_data_size,
|
| + const void* cmd_data) {
|
| + static const char kFunctionName[] =
|
| + "glStencilThenCoverFillPathInstancedCHROMIUM";
|
| + const gles2::cmds::StencilThenCoverFillPathInstancedCHROMIUM& c =
|
| + *static_cast<
|
| + const gles2::cmds::StencilThenCoverFillPathInstancedCHROMIUM*>(
|
| + cmd_data);
|
| + if (!features().chromium_path_rendering) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
|
| + "function not available");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
|
| + if (num_paths < 0) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "numPaths < 0");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum path_name_type = static_cast<GLsizei>(c.pathNameType);
|
| + if (!validators_->path_name_type.IsValid(path_name_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, path_name_type,
|
| + "pathNameType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum fill_mode = static_cast<GLenum>(c.fillMode);
|
| + if (!validators_->path_fill_mode.IsValid(fill_mode)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, fill_mode, "fillMode");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLuint mask = static_cast<GLuint>(c.mask);
|
| + if (!IsValidPathCommandMask(fill_mode, mask)) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
|
| + "mask is not power of two");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum cover_mode = static_cast<GLenum>(c.coverMode);
|
| + if (!validators_->path_instanced_cover_mode.IsValid(cover_mode)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum transform_type = static_cast<GLenum>(c.transformType);
|
| + if (!validators_->path_transform_type.IsValid(transform_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, transform_type,
|
| + "transformType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLuint path_base = static_cast<GLuint>(c.pathBase);
|
| +
|
| + uint32 paths_shm_id = static_cast<uint32>(c.paths_shm_id);
|
| + uint32 paths_shm_offset = static_cast<uint32>(c.paths_shm_offset);
|
| + uint32 transforms_shm_id = static_cast<uint32>(c.transformValues_shm_id);
|
| + uint32 transforms_shm_offset =
|
| + static_cast<uint32>(c.transformValues_shm_offset);
|
| +
|
| + GLuint* paths = NULL;
|
| + const GLfloat* transforms = NULL;
|
| + error::Error prepare_error = error::kNoError;
|
| + scoped_ptr<GLuint[]> temp_path_buffer;
|
| + if (!PrepareInstancedPathCommand(
|
| + num_paths, path_name_type, paths_shm_id, paths_shm_offset, path_base,
|
| + transform_type, transforms_shm_id, transforms_shm_offset,
|
| + &prepare_error, &paths, &transforms, &temp_path_buffer)) {
|
| + return prepare_error;
|
| + }
|
| +
|
| + ApplyDirtyState();
|
| + glStencilThenCoverFillPathInstancedNV(num_paths, path_name_type, paths, 0,
|
| + fill_mode, mask, cover_mode,
|
| + transform_type, transforms);
|
| +
|
| + return error::kNoError;
|
| +}
|
| +
|
| +error::Error
|
| +GLES2DecoderImpl::HandleStencilThenCoverStrokePathInstancedCHROMIUM(
|
| + uint32 immediate_data_size,
|
| + const void* cmd_data) {
|
| + static const char kFunctionName[] =
|
| + "glStencilThenCoverStrokeInstancedCHROMIUM";
|
| + const gles2::cmds::StencilThenCoverStrokePathInstancedCHROMIUM& c =
|
| + *static_cast<
|
| + const gles2::cmds::StencilThenCoverStrokePathInstancedCHROMIUM*>(
|
| + cmd_data);
|
| + if (!features().chromium_path_rendering) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
|
| + "function not available");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLsizei num_paths = static_cast<GLsizei>(c.numPaths);
|
| + if (num_paths < 0) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "numPaths < 0");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum path_name_type = static_cast<GLsizei>(c.pathNameType);
|
| + if (!validators_->path_name_type.IsValid(path_name_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, path_name_type,
|
| + "pathNameType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum cover_mode = static_cast<GLenum>(c.coverMode);
|
| + if (!validators_->path_instanced_cover_mode.IsValid(cover_mode)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLenum transform_type = static_cast<GLenum>(c.transformType);
|
| + if (!validators_->path_transform_type.IsValid(transform_type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, transform_type,
|
| + "transformType");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + GLuint path_base = static_cast<GLuint>(c.pathBase);
|
| + GLuint reference = static_cast<GLuint>(c.reference);
|
| + GLuint mask = static_cast<GLuint>(c.mask);
|
| +
|
| + uint32 paths_shm_id = static_cast<uint32>(c.paths_shm_id);
|
| + uint32 paths_shm_offset = static_cast<uint32>(c.paths_shm_offset);
|
| + uint32 transforms_shm_id = static_cast<uint32>(c.transformValues_shm_id);
|
| + uint32 transforms_shm_offset =
|
| + static_cast<uint32>(c.transformValues_shm_offset);
|
| +
|
| + GLuint* paths = NULL;
|
| + const GLfloat* transforms = NULL;
|
| + error::Error prepare_error = error::kNoError;
|
| + scoped_ptr<GLuint[]> temp_path_buffer;
|
| + if (!PrepareInstancedPathCommand(
|
| + num_paths, path_name_type, paths_shm_id, paths_shm_offset, path_base,
|
| + transform_type, transforms_shm_id, transforms_shm_offset,
|
| + &prepare_error, &paths, &transforms, &temp_path_buffer)) {
|
| + return prepare_error;
|
| + }
|
| +
|
| + ApplyDirtyState();
|
| + glStencilThenCoverStrokePathInstancedNV(num_paths, path_name_type, paths, 0,
|
| + reference, mask, cover_mode,
|
| + transform_type, 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.
|
|
|