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 004029b2e7700c0133befe856394f7c2ab88f5b7..4469c7dc17da03926853cb762cf0ffdcbad30f34 100644 |
--- a/gpu/command_buffer/client/gles2_implementation.cc |
+++ b/gpu/command_buffer/client/gles2_implementation.cc |
@@ -256,6 +256,11 @@ IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { |
return share_group_->GetIdHandler(namespace_id); |
} |
+RangeIdHandlerInterface* GLES2Implementation::GetRangeIdHandler( |
+ int namespace_id) const { |
+ return share_group_->GetRangeIdHandler(namespace_id); |
+} |
+ |
IdAllocator* GLES2Implementation::GetIdAllocator(int namespace_id) const { |
if (namespace_id == id_namespaces::kQueries) |
return query_id_allocator_.get(); |
@@ -5749,6 +5754,164 @@ void GLES2Implementation::GetInternalformativ( |
CheckGLError(); |
} |
+GLuint GLES2Implementation::GenPathsCHROMIUM(GLsizei range) { |
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenPathsCHROMIUM(" << range |
+ << ")"); |
+ GPU_CLIENT_SINGLE_THREAD_CHECK(); |
+ static const char kFunctionName[] = "glGenPathsCHROMIUM"; |
+ if (range < 0) { |
+ SetGLError(GL_INVALID_VALUE, kFunctionName, "range < 0"); |
+ return 0; |
+ } |
+ if (!base::IsValueInRangeForNumericType<int32_t>(range)) { |
+ SetGLError(GL_INVALID_OPERATION, kFunctionName, "range more than 32-bit"); |
+ return 0; |
+ } |
+ if (range == 0) |
+ return 0; |
+ |
+ GLuint first_client_id = 0; |
+ GetRangeIdHandler(id_namespaces::kPaths) |
+ ->MakeIdRange(this, range, &first_client_id); |
+ |
+ if (first_client_id == 0) { |
+ // Ran out of id space. Is not specified to raise any gl errors. |
+ return 0; |
+ } |
+ |
+ helper_->GenPathsCHROMIUM(first_client_id, range); |
+ |
+ GPU_CLIENT_LOG_CODE_BLOCK({ |
+ for (GLsizei i = 0; i < range; ++i) { |
+ GPU_CLIENT_LOG(" " << i << ": " << (first_client_id + i)); |
+ } |
+ }); |
+ CheckGLError(); |
+ return first_client_id; |
+} |
+ |
+void GLES2Implementation::DeletePathsCHROMIUM(GLuint first_client_id, |
+ GLsizei range) { |
+ GPU_CLIENT_SINGLE_THREAD_CHECK(); |
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeletePathsCHROMIUM(" |
+ << first_client_id << ", " << range << ")"); |
+ static const char kFunctionName[] = "glDeletePathsCHROMIUM"; |
+ |
+ if (range < 0) { |
+ SetGLError(GL_INVALID_VALUE, kFunctionName, "range < 0"); |
+ return; |
+ } |
+ if (!base::IsValueInRangeForNumericType<int32_t>(range)) { |
+ SetGLError(GL_INVALID_OPERATION, kFunctionName, "range more than 32-bit"); |
+ return; |
+ } |
+ if (range == 0) |
+ return; |
+ |
+ GLuint last_client_id; |
+ if (!SafeAddUint32(first_client_id, range - 1, &last_client_id)) { |
+ SetGLError(GL_INVALID_OPERATION, kFunctionName, "overflow"); |
+ return; |
+ } |
+ |
+ GetRangeIdHandler(id_namespaces::kPaths) |
+ ->FreeIdRange(this, first_client_id, range, |
+ &GLES2Implementation::DeletePathsCHROMIUMStub); |
+ CheckGLError(); |
+} |
+ |
+void GLES2Implementation::DeletePathsCHROMIUMStub(GLuint first_client_id, |
+ GLsizei range) { |
+ helper_->DeletePathsCHROMIUM(first_client_id, range); |
+} |
+ |
+void GLES2Implementation::PathCommandsCHROMIUM(GLuint path, |
+ GLsizei num_commands, |
+ const GLubyte* commands, |
+ GLsizei num_coords, |
+ GLenum coord_type, |
+ const void* coords) { |
+ GPU_CLIENT_SINGLE_THREAD_CHECK(); |
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPathCommandsCHROMIUM(" << path |
+ << ", " << num_commands << ", " << commands << ", " |
+ << num_coords << ", " << coords << ")"); |
+ static const char kFunctionName[] = "glPathCommandsCHROMIUM"; |
+ if (path == 0) { |
+ SetGLError(GL_INVALID_VALUE, kFunctionName, "invalid path object"); |
+ return; |
+ } |
+ if (num_commands < 0) { |
+ SetGLError(GL_INVALID_VALUE, kFunctionName, "numCommands < 0"); |
+ return; |
+ } |
+ if (num_commands != 0 && !commands) { |
+ SetGLError(GL_INVALID_VALUE, kFunctionName, "missing commands"); |
+ return; |
+ } |
+ if (num_coords < 0) { |
+ SetGLError(GL_INVALID_VALUE, kFunctionName, "numCoords < 0"); |
+ return; |
+ } |
+ if (num_coords != 0 && !coords) { |
+ SetGLError(GL_INVALID_VALUE, kFunctionName, "missing coords"); |
+ return; |
+ } |
+ uint32 coord_type_size = GLES2Util::GetGLTypeSizeForPathCoordType(coord_type); |
+ if (coord_type_size == 0) { |
+ SetGLError(GL_INVALID_ENUM, kFunctionName, "invalid coordType"); |
+ return; |
+ } |
+ if (num_commands == 0) { |
+ // No commands must mean no coords, thus nothing to memcpy. Let |
+ // the service validate the call. Validate coord_type above, so |
+ // that the parameters will be checked the in the same order |
+ // regardless of num_commands. |
+ helper_->PathCommandsCHROMIUM(path, num_commands, 0, 0, num_coords, |
+ coord_type, 0, 0); |
+ CheckGLError(); |
+ return; |
+ } |
+ |
+ uint32 coords_size; |
+ if (!SafeMultiplyUint32(num_coords, coord_type_size, &coords_size)) { |
+ SetGLError(GL_INVALID_OPERATION, kFunctionName, "overflow"); |
+ return; |
+ } |
+ |
+ uint32 required_buffer_size; |
+ if (!SafeAddUint32(coords_size, num_commands, &required_buffer_size)) { |
+ SetGLError(GL_INVALID_OPERATION, kFunctionName, "overflow"); |
+ return; |
+ } |
+ |
+ ScopedTransferBufferPtr buffer(required_buffer_size, helper_, |
+ transfer_buffer_); |
+ if (!buffer.valid() || buffer.size() < required_buffer_size) { |
+ SetGLError(GL_OUT_OF_MEMORY, kFunctionName, "too large"); |
+ return; |
+ } |
+ |
+ uint32 coords_shm_id = 0; |
+ uint32 coords_shm_offset = 0; |
+ // Copy coords first because they need more strict alignment. |
+ if (coords_size > 0) { |
+ unsigned char* coords_addr = static_cast<unsigned char*>(buffer.address()); |
+ memcpy(coords_addr, coords, coords_size); |
+ coords_shm_id = buffer.shm_id(); |
+ coords_shm_offset = buffer.offset(); |
+ } |
+ |
+ DCHECK(num_commands > 0); |
+ unsigned char* commands_addr = |
+ static_cast<unsigned char*>(buffer.address()) + coords_size; |
+ memcpy(commands_addr, commands, num_commands); |
+ |
+ helper_->PathCommandsCHROMIUM(path, num_commands, buffer.shm_id(), |
+ buffer.offset() + coords_size, num_coords, |
+ coord_type, coords_shm_id, coords_shm_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. |