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 8574d5fca57e1ee2900d1fa12f8b5098776b4c3a..a0804c4291cb3188e4e6bda2c60a8060e8a83916 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); |
Zhenyao Mo
2015/10/06 22:51:01
overflow check for mask + 1
Kimmo Kinnunen
2015/10/08 09:28:29
While not terribly useful, I think overflow is int
|
+} |
+ |
} // namespace |
class GLES2DecoderImpl; |
@@ -1913,6 +1923,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) \ |
@@ -14901,9 +14936,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; |
@@ -15010,9 +15043,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; |
@@ -15059,6 +15090,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) { |
Zhenyao Mo
2015/10/06 22:51:00
A switch (path_name_type) is much cleaner here.
Kimmo Kinnunen
2015/10/08 09:28:29
Done.
|
+ 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; |
Zhenyao Mo
2015/10/06 22:51:00
const T*
Kimmo Kinnunen
2015/10/08 09:28:29
Still left this as is, see below. (The optimizatio
|
+ 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)) { |
Zhenyao Mo
2015/10/06 22:51:00
I think this optimization is unnecessary and makes
Kimmo Kinnunen
2015/10/08 09:28:28
I tried to make this less ugly. If it is still ugl
|
+ 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; |
Zhenyao Mo
2015/10/06 22:51:01
This is incorrect. You should generate an INVALID
Kimmo Kinnunen
2015/10/08 09:28:29
Done.
|
+ 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, |
Zhenyao Mo
2015/10/06 22:51:01
no GL error, but return error::kUnknownCommand ins
Kimmo Kinnunen
2015/10/08 09:28:29
Done.
|
+ "function not available"); |
+ return error::kNoError; |
+ } |
+ |
+ GLsizei num_paths = static_cast<GLsizei>(c.numPaths); |
+ if (num_paths < 0) { |
Zhenyao Mo
2015/10/06 22:51:00
It looks to me that the validation of num_paths, p
Kimmo Kinnunen
2015/10/08 09:28:28
The order of the error checking is significant.
I
|
+ 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+1 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, |
Zhenyao Mo
2015/10/06 22:51:01
Should you always use GL_UNSIGNED_INT here as the
Kimmo Kinnunen
2015/10/08 09:28:29
Done.
|
+ 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, |
Zhenyao Mo
2015/10/06 22:51:01
Same here, no GL error, but return error::kUnknown
Kimmo Kinnunen
2015/10/08 09:28:29
Done.
|
+ "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); |
Zhenyao Mo
2015/10/06 22:51:00
In the spec, reference is defined as GLint, not GL
Kimmo Kinnunen
2015/10/08 09:28:29
Done.
|
+ 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, |
Zhenyao Mo
2015/10/06 22:51:01
Same here, no GL error, but return error::kUnknown
Kimmo Kinnunen
2015/10/08 09:28:28
Done.
|
+ "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, |
Zhenyao Mo
2015/10/06 22:51:01
Same here, no GL error, but return error::kUnknown
Kimmo Kinnunen
2015/10/08 09:28:29
Done.
|
+ "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, |
Zhenyao Mo
2015/10/06 22:51:01
Same here, no GL error, but return error::kUnknown
Kimmo Kinnunen
2015/10/08 09:28:28
Done.
|
+ "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+1 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, |
Zhenyao Mo
2015/10/06 22:51:00
Same here, no GL error, but return error::kUnknown
Kimmo Kinnunen
2015/10/08 09:28:29
Done.
|
+ "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); |
Zhenyao Mo
2015/10/06 22:51:00
GLint instead of GLuint
Kimmo Kinnunen
2015/10/08 09:28:29
Done.
|
+ 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. |