Chromium Code Reviews| Index: gpu/command_buffer/client/gles2_implementation.cc |
| diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc |
| index 5635f2678a20595343d402764cf997a6b3385f72..2964c4ce0b2ceb1ddc1bbcb5277dbe9ce784b110 100644 |
| --- a/gpu/command_buffer/client/gles2_implementation.cc |
| +++ b/gpu/command_buffer/client/gles2_implementation.cc |
| @@ -5880,6 +5880,323 @@ void GLES2Implementation::PathCommandsCHROMIUM(GLuint path, |
| CheckGLError(); |
| } |
| +bool GLES2Implementation::PrepareInstancedPathCommand( |
| + const char* function_name, |
| + GLsizei num_paths, |
| + GLenum path_name_type, |
| + const void* paths, |
| + GLenum transform_type, |
| + const GLfloat* transform_values, |
| + ScopedTransferBufferPtr* buffer, |
| + uint32* out_paths_shm_id, |
| + size_t* out_paths_offset, |
| + uint32* out_transforms_shm_id, |
| + size_t* out_transforms_offset) { |
| + if (num_paths < 0) { |
| + SetGLError(GL_INVALID_VALUE, function_name, "numPaths < 0"); |
| + return false; |
| + } |
| + uint32 path_name_size = |
| + GLES2Util::GetGLTypeSizeForGLPathNameType(path_name_type); |
| + |
| + if (path_name_size == 0) { |
| + SetGLError(GL_INVALID_ENUM, function_name, "invalid pathNameType"); |
| + return false; |
| + } |
| + |
| + uint32 transforms_component_count = |
| + GLES2Util::GetComponentCountForGLTransformType(transform_type); |
| + |
| + if (transform_type != GL_NONE && transforms_component_count == 0) { |
| + SetGLError(GL_INVALID_ENUM, function_name, "invalid transformType"); |
| + return false; |
| + } |
| + |
| + if (num_paths == 0) { |
| + // Make an empty call to check the rest of the parameters. We |
| + // check the above parameters client-side, in order to get |
| + // same GL errors whether num_paths == 0 or not. |
| + *out_paths_shm_id = 0; |
| + *out_paths_offset = 0; |
| + *out_transforms_shm_id = 0; |
| + *out_transforms_offset = 0; |
| + return true; |
|
vmiura
2015/08/28 20:02:32
Why don't we set GL_ERROR here?
Kimmo Kinnunen
2015/08/31 07:36:53
It is not an error to draw 0 paths?
Returning 'tru
|
| + } |
| + |
| + if (!paths) { |
| + SetGLError(GL_INVALID_VALUE, function_name, "missing paths"); |
| + return false; |
| + } |
| + |
| + if (transform_type != GL_NONE && !transform_values) { |
| + SetGLError(GL_INVALID_VALUE, function_name, "missing transforms"); |
| + return false; |
| + } |
| + |
| + uint32 paths_size; |
| + if (!SafeMultiplyUint32(path_name_size, num_paths, &paths_size)) { |
| + SetGLError(GL_INVALID_OPERATION, function_name, "overflow"); |
| + return false; |
| + } |
| + |
| + // The multiplication below will not overflow. |
| + DCHECK(transforms_component_count <= 12); |
| + uint32 one_transform_size = sizeof(GLfloat) * transforms_component_count; |
| + |
| + uint32 transforms_size; |
| + if (!SafeMultiplyUint32(one_transform_size, num_paths, &transforms_size)) { |
| + SetGLError(GL_INVALID_VALUE, function_name, "overflow"); |
| + return false; |
| + } |
| + |
| + uint32 required_buffer_size; |
| + if (!SafeAddUint32(transforms_size, paths_size, &required_buffer_size)) { |
| + SetGLError(GL_INVALID_OPERATION, function_name, "overflow"); |
| + return false; |
| + } |
| + |
| + buffer->Reset(required_buffer_size); |
| + |
| + if (!buffer->valid() || buffer->size() < required_buffer_size) { |
| + SetGLError(GL_OUT_OF_MEMORY, function_name, "too large"); |
| + return false; |
| + } |
| + |
| + // Copy transforms first, they may have more strict alignment. |
| + if (transforms_size > 0) { |
| + unsigned char* transforms_addr = |
| + static_cast<unsigned char*>(buffer->address()); |
| + memcpy(transforms_addr, transform_values, transforms_size); |
| + *out_transforms_shm_id = buffer->shm_id(); |
| + *out_transforms_offset = buffer->offset(); |
| + } else { |
| + *out_transforms_shm_id = 0; |
| + *out_transforms_offset = 0; |
| + } |
| + |
| + DCHECK(paths_size > 0); |
| + unsigned char* paths_addr = |
| + static_cast<unsigned char*>(buffer->address()) + transforms_size; |
| + memcpy(paths_addr, paths, paths_size); |
| + *out_paths_shm_id = buffer->shm_id(); |
| + *out_paths_offset = buffer->offset() + transforms_size; |
| + |
| + return true; |
| +} |
| + |
| +void GLES2Implementation::StencilFillPathInstancedCHROMIUM( |
| + GLsizei num_paths, |
| + GLenum path_name_type, |
| + const GLvoid* paths, |
| + GLuint path_base, |
| + GLenum fill_mode, |
| + GLuint mask, |
| + GLenum transform_type, |
| + const GLfloat* transform_values) { |
| + GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| + GPU_CLIENT_LOG("[" << GetLogPrefix() |
| + << "] glStencilFillPathInstancedCHROMIUM(" << num_paths |
| + << ", " << path_name_type << ", " << paths << ", " |
| + << path_base << ", " << fill_mode << ", " << mask << ", " |
| + << transform_type << ", " << transform_values << ")"); |
| + |
| + ScopedTransferBufferPtr buffer(helper_, transfer_buffer_); |
| + uint32 paths_shm_id = 0; |
| + size_t paths_offset = 0; |
| + uint32 transforms_shm_id = 0; |
| + size_t transforms_offset = 0; |
| + if (!PrepareInstancedPathCommand( |
| + "glStencilFillPathInstancedCHROMIUM", num_paths, path_name_type, |
| + paths, transform_type, transform_values, &buffer, &paths_shm_id, |
| + &paths_offset, &transforms_shm_id, &transforms_offset)) { |
| + return; |
| + } |
| + |
| + helper_->StencilFillPathInstancedCHROMIUM( |
| + num_paths, path_name_type, paths_shm_id, paths_offset, path_base, |
| + fill_mode, mask, transform_type, transforms_shm_id, transforms_offset); |
| + |
| + CheckGLError(); |
| +} |
| + |
| +void GLES2Implementation::StencilStrokePathInstancedCHROMIUM( |
| + GLsizei num_paths, |
| + GLenum path_name_type, |
| + const GLvoid* paths, |
| + GLuint path_base, |
| + GLint ref, |
| + GLuint mask, |
| + GLenum transform_type, |
| + const GLfloat* transform_values) { |
| + GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| + GPU_CLIENT_LOG("[" << GetLogPrefix() |
| + << "] glStencilStrokePathInstancedCHROMIUM(" << num_paths |
| + << ", " << path_name_type << ", " << paths << ", " |
| + << path_base << ", " << ref << ", " << mask << ", " |
| + << transform_type << ", " << transform_values << ")"); |
| + |
| + ScopedTransferBufferPtr buffer(helper_, transfer_buffer_); |
| + uint32 paths_shm_id = 0; |
| + size_t paths_offset = 0; |
| + uint32 transforms_shm_id = 0; |
| + size_t transforms_offset = 0; |
| + if (!PrepareInstancedPathCommand( |
| + "glStencilStrokePathInstancedCHROMIUM", num_paths, path_name_type, |
| + paths, transform_type, transform_values, &buffer, &paths_shm_id, |
| + &paths_offset, &transforms_shm_id, &transforms_offset)) { |
| + return; |
| + } |
| + |
| + helper_->StencilStrokePathInstancedCHROMIUM( |
| + num_paths, path_name_type, paths_shm_id, paths_offset, path_base, ref, |
| + mask, transform_type, transforms_shm_id, transforms_offset); |
| + |
| + CheckGLError(); |
| +} |
| + |
| +void GLES2Implementation::CoverFillPathInstancedCHROMIUM( |
| + GLsizei num_paths, |
| + GLenum path_name_type, |
| + const GLvoid* paths, |
| + GLuint path_base, |
| + GLenum cover_mode, |
| + GLenum transform_type, |
| + const GLfloat* transform_values) { |
| + GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCoverFillPathInstancedCHROMIUM(" |
| + << num_paths << ", " << path_name_type << ", " << paths |
| + << ", " << path_base << ", " << cover_mode << ", " |
| + << transform_type << ", " << transform_values << ")"); |
| + |
| + ScopedTransferBufferPtr buffer(helper_, transfer_buffer_); |
| + uint32 paths_shm_id = 0; |
| + size_t paths_offset = 0; |
| + uint32 transforms_shm_id = 0; |
| + size_t transforms_offset = 0; |
| + if (!PrepareInstancedPathCommand( |
| + "glCoverFillPathInstancedCHROMIUM", num_paths, path_name_type, paths, |
| + transform_type, transform_values, &buffer, &paths_shm_id, |
| + &paths_offset, &transforms_shm_id, &transforms_offset)) { |
| + return; |
| + } |
| + |
| + helper_->CoverFillPathInstancedCHROMIUM( |
| + num_paths, path_name_type, paths_shm_id, paths_offset, path_base, |
| + cover_mode, transform_type, transforms_shm_id, transforms_offset); |
| + |
| + CheckGLError(); |
| +} |
| + |
| +void GLES2Implementation::CoverStrokePathInstancedCHROMIUM( |
| + GLsizei num_paths, |
| + GLenum path_name_type, |
| + const GLvoid* paths, |
| + GLuint path_base, |
| + GLenum cover_mode, |
| + GLenum transform_type, |
| + const GLfloat* transform_values) { |
| + GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| + GPU_CLIENT_LOG("[" << GetLogPrefix() |
| + << "] glCoverStrokePathInstancedCHROMIUM(" << num_paths |
| + << ", " << path_name_type << ", " << paths << ", " |
| + << path_base << ", " << cover_mode << ", " |
| + << transform_type << ", " << transform_values << ")"); |
| + |
| + ScopedTransferBufferPtr buffer(helper_, transfer_buffer_); |
| + uint32 paths_shm_id = 0; |
| + size_t paths_offset = 0; |
| + uint32 transforms_shm_id = 0; |
| + size_t transforms_offset = 0; |
| + if (!PrepareInstancedPathCommand( |
| + "glCoverStrokePathInstancedCHROMIUM", num_paths, path_name_type, |
| + paths, transform_type, transform_values, &buffer, &paths_shm_id, |
| + &paths_offset, &transforms_shm_id, &transforms_offset)) { |
| + return; |
| + } |
| + |
| + helper_->CoverStrokePathInstancedCHROMIUM( |
| + num_paths, path_name_type, paths_shm_id, paths_offset, path_base, |
| + cover_mode, transform_type, transforms_shm_id, transforms_offset); |
| + |
| + CheckGLError(); |
| +} |
| + |
| +void GLES2Implementation::StencilThenCoverFillPathInstancedCHROMIUM( |
| + GLsizei num_paths, |
| + GLenum path_name_type, |
| + const GLvoid* paths, |
| + GLuint path_base, |
| + GLenum fill_mode, |
| + GLuint mask, |
| + GLenum cover_mode, |
| + GLenum transform_type, |
| + const GLfloat* transform_values) { |
| + GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| + GPU_CLIENT_LOG( |
| + "[" << GetLogPrefix() << "] glStencilThenCoverFillPathInstancedCHROMIUM(" |
| + << num_paths << ", " << path_name_type << ", " << paths << ", " |
| + << path_base << ", " << cover_mode << ", " << fill_mode << ", " |
| + << mask << ", " << transform_type << ", " << transform_values << ")"); |
| + |
| + ScopedTransferBufferPtr buffer(helper_, transfer_buffer_); |
| + uint32 paths_shm_id = 0; |
| + size_t paths_offset = 0; |
| + uint32 transforms_shm_id = 0; |
| + size_t transforms_offset = 0; |
| + if (!PrepareInstancedPathCommand( |
| + "glStencilThenCoverFillPathInstancedCHROMIUM", num_paths, |
| + path_name_type, paths, transform_type, transform_values, &buffer, |
| + &paths_shm_id, &paths_offset, &transforms_shm_id, |
| + &transforms_offset)) { |
| + return; |
| + } |
| + |
| + helper_->StencilThenCoverFillPathInstancedCHROMIUM( |
| + num_paths, path_name_type, paths_shm_id, paths_offset, path_base, |
| + fill_mode, mask, cover_mode, transform_type, transforms_shm_id, |
| + transforms_offset); |
| + |
| + CheckGLError(); |
| +} |
| + |
| +void GLES2Implementation::StencilThenCoverStrokePathInstancedCHROMIUM( |
| + GLsizei num_paths, |
| + GLenum path_name_type, |
| + const GLvoid* paths, |
| + GLuint path_base, |
| + GLint ref, |
| + GLuint mask, |
| + GLenum cover_mode, |
| + GLenum transform_type, |
| + const GLfloat* transform_values) { |
| + GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| + GPU_CLIENT_LOG("[" << GetLogPrefix() |
| + << "] glStencilThenCoverStrokePathInstancedCHROMIUM(" |
| + << num_paths << ", " << path_name_type << ", " << paths |
| + << ", " << path_base << ", " << cover_mode << ", " << ref |
| + << ", " << mask << ", " << transform_type << ", " |
| + << transform_values << ")"); |
| + |
| + ScopedTransferBufferPtr buffer(helper_, transfer_buffer_); |
| + uint32 paths_shm_id = 0; |
| + size_t paths_offset = 0; |
| + uint32 transforms_shm_id = 0; |
| + size_t transforms_offset = 0; |
| + if (!PrepareInstancedPathCommand( |
| + "glStencilThenCoverStrokePathInstancedCHROMIUM", num_paths, |
| + path_name_type, paths, transform_type, transform_values, &buffer, |
| + &paths_shm_id, &paths_offset, &transforms_shm_id, |
| + &transforms_offset)) { |
| + return; |
| + } |
| + |
| + helper_->StencilThenCoverStrokePathInstancedCHROMIUM( |
| + num_paths, path_name_type, paths_shm_id, paths_offset, path_base, ref, |
| + mask, cover_mode, transform_type, transforms_shm_id, transforms_offset); |
| + |
| + CheckGLError(); |
| +} |
| + |
| // 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. |