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

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

Issue 477623004: command_buffer: Support instanced path rendering in gpu command buffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@new-03-path-funcs
Patch Set: rebase Created 5 years, 3 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 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.

Powered by Google App Engine
This is Rietveld 408576698