| 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 5cc28ddc0a4912ad64922fe19a42a5e3f7451b2c..5dcc9dd3844c32e51eb7b6c1b1fd240c5bebb135 100644
|
| --- a/gpu/command_buffer/client/gles2_implementation.cc
|
| +++ b/gpu/command_buffer/client/gles2_implementation.cc
|
| @@ -255,6 +255,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();
|
| @@ -5824,6 +5829,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.
|
|
|