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 140d612c36d3eb6d10bfed351baf2505aed4470a..7edf4a302000c4d73c93963a917b4c1472ac3644 100644 |
| --- a/gpu/command_buffer/client/gles2_implementation.cc |
| +++ b/gpu/command_buffer/client/gles2_implementation.cc |
| @@ -14,6 +14,7 @@ |
| #include <stdio.h> |
| #include <string.h> |
| #include <GLES2/gl2ext.h> |
| +#include "../client/buffer_tracker.h" |
| #include "../client/mapped_memory.h" |
| #include "../client/program_info_manager.h" |
| #include "../client/query_tracker.h" |
| @@ -440,6 +441,7 @@ GLES2Implementation::GLES2Implementation( |
| current_program_(0), |
| bound_array_buffer_id_(0), |
| bound_element_array_buffer_id_(0), |
| + bound_pixel_unpack_transfer_buffer_id_(0), |
| client_side_array_id_(0), |
| client_side_element_array_id_(0), |
| bound_vertex_array_id_(0), |
| @@ -517,6 +519,7 @@ bool GLES2Implementation::Initialize( |
| static_state_.int_state.max_combined_texture_image_units]); |
| query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
| + buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); |
| #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
| @@ -542,6 +545,8 @@ GLES2Implementation::~GLES2Implementation() { |
| #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); |
| #endif |
| + buffer_tracker_.reset(); |
| + |
| // The share group needs to be able to use a command buffer to talk |
| // to service if it's destroyed so set one for it then release the reference. |
| // If it's destroyed it will use this GLES2Implemenation. |
| @@ -903,6 +908,12 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { |
| return true; |
| } |
| return false; |
| + case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: |
| + if (share_group_->bind_generates_resource()) { |
|
greggman
2012/11/19 04:50:14
don't need this if. As this is a client side imple
reveman
2012/11/20 16:49:30
Done.
|
| + *params = bound_pixel_unpack_transfer_buffer_id_; |
| + return true; |
| + } |
| + return false; |
| case GL_ACTIVE_TEXTURE: |
| *params = active_texture_unit_ + GL_TEXTURE0; |
| return true; |
| @@ -1208,6 +1219,19 @@ void GLES2Implementation::BindAttribLocation( |
| helper_->SetBucketSize(kResultBucketId, 0); |
| } |
| +void GLES2Implementation::BindBuffer(GLenum target, GLuint buffer) { |
| + GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| + GPU_CLIENT_LOG("[" << this << "] glBindBuffer(" << |
| + GLES2Util::GetStringBufferTarget(target) << ", " << buffer << ")"); |
| + if (IsBufferReservedId(buffer)) { |
| + SetGLError(GL_INVALID_OPERATION, "BindBuffer", "buffer reserved id"); |
| + return; |
| + } |
| + BindBufferHelper(target, buffer); |
| + if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) |
|
greggman
2012/11/19 04:50:14
this is redundant. You already set this in BindBuf
reveman
2012/11/20 16:49:30
Done.
|
| + helper_->BindBuffer(target, buffer); |
| +} |
| + |
| void GLES2Implementation::BindUniformLocationCHROMIUM( |
| GLuint program, GLint location, const char* name) { |
| GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| @@ -1567,6 +1591,30 @@ void GLES2Implementation::BufferDataHelper( |
| return; |
| } |
| + if (target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { |
| + GLuint buffer_id = bound_pixel_unpack_transfer_buffer_id_; |
| + if (!buffer_id) { |
| + SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); |
| + return; |
| + } |
| + |
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| + if (buffer) { |
| + // Free buffer memory, pending the passage of a token. |
| + buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
| + |
| + // Remove old buffer. |
| + buffer_tracker_->RemoveBuffer(buffer_id); |
| + } |
| + |
| + // Create new buffer. |
| + buffer = buffer_tracker_->CreateBuffer(buffer_id, size); |
| + GPU_DCHECK(buffer); |
| + if (data) |
| + memcpy(buffer->address(), data, size); |
| + return; |
| + } |
| + |
| // If there is no data just send BufferData |
| if (!data) { |
| helper_->BufferData(target, size, 0, 0, usage); |
| @@ -1673,6 +1721,26 @@ void GLES2Implementation::CompressedTexImage2D( |
| if (height == 0 || width == 0) { |
| return; |
| } |
| + // If there's a pixel unpack buffer bound use it when issuing |
| + // CompressedTexImage2D. |
| + if (bound_pixel_unpack_transfer_buffer_id_) { |
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| + bound_pixel_unpack_transfer_buffer_id_); |
| + if (!buffer) { |
| + SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "invalid buffer"); |
| + return; |
| + } |
| + GLuint offset = ToGLuint(data); |
| + if ((buffer->size() - offset) < static_cast<GLuint>(image_size)) { |
| + SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", |
| + "unpack size to large"); |
| + return; |
| + } |
| + helper_->CompressedTexImage2D( |
| + target, level, internalformat, width, height, border, image_size, |
| + buffer->shm_id(), buffer->shm_offset() + offset); |
| + return; |
| + } |
| SetBucketContents(kResultBucketId, data, image_size); |
| helper_->CompressedTexImage2DBucket( |
| target, level, internalformat, width, height, border, kResultBucketId); |
| @@ -1698,6 +1766,27 @@ void GLES2Implementation::CompressedTexSubImage2D( |
| SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); |
| return; |
| } |
| + // If there's a pixel unpack buffer bound use it when issuing |
| + // CompressedTexSubImage2D. |
| + if (bound_pixel_unpack_transfer_buffer_id_) { |
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
|
greggman
2012/11/19 04:50:14
It seems like this code and the code above and twi
reveman
2012/11/20 16:49:30
Done. Made it GetBoundPixelUnpackTransferBufferIfV
|
| + bound_pixel_unpack_transfer_buffer_id_); |
| + if (!buffer) { |
| + SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", |
| + "invalid buffer"); |
| + return; |
| + } |
| + GLuint offset = ToGLuint(data); |
| + if ((buffer->size() - offset) < static_cast<GLuint>(image_size)) { |
| + SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", |
| + "unpack size to large"); |
| + return; |
| + } |
| + helper_->CompressedTexSubImage2D( |
| + target, level, xoffset, yoffset, width, height, format, image_size, |
| + buffer->shm_id(), buffer->shm_offset() + offset); |
| + return; |
| + } |
| SetBucketContents(kResultBucketId, data, image_size); |
| helper_->CompressedTexSubImage2DBucket( |
| target, level, xoffset, yoffset, width, height, format, kResultBucketId); |
| @@ -1769,6 +1858,25 @@ void GLES2Implementation::TexImage2D( |
| return; |
| } |
| + // If there's a pixel unpack buffer bound use it when issuing TexImage2D. |
| + if (bound_pixel_unpack_transfer_buffer_id_) { |
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| + bound_pixel_unpack_transfer_buffer_id_); |
| + if (!buffer) { |
| + SetGLError(GL_INVALID_VALUE, "glTexImage2D", "invalid buffer"); |
| + return; |
| + } |
| + GLuint offset = ToGLuint(pixels); |
| + if ((buffer->size() - offset) < size) { |
| + SetGLError(GL_INVALID_VALUE, "glTexImage2D", "unpack size to large"); |
| + return; |
| + } |
| + helper_->TexImage2D( |
| + target, level, internalformat, width, height, border, format, type, |
| + buffer->shm_id(), buffer->shm_offset() + offset); |
| + return; |
| + } |
| + |
| // If there's no data just issue TexImage2D |
| if (!pixels) { |
| helper_->TexImage2D( |
| @@ -1856,6 +1964,25 @@ void GLES2Implementation::TexSubImage2D( |
| return; |
| } |
| + // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
| + if (bound_pixel_unpack_transfer_buffer_id_) { |
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| + bound_pixel_unpack_transfer_buffer_id_); |
| + if (!buffer) { |
| + SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "invalid buffer"); |
| + return; |
| + } |
| + GLuint offset = ToGLuint(pixels); |
| + if ((buffer->size() - offset) < temp_size) { |
| + SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "unpack size to large"); |
| + return; |
| + } |
| + helper_->TexSubImage2D( |
| + target, level, xoffset, yoffset, width, height, format, type, |
| + buffer->shm_id(), buffer->shm_offset() + offset, false); |
| + return; |
| + } |
| + |
| // compute the advance bytes per row for the src pixels |
| uint32 src_padded_row_size; |
| if (unpack_row_length_ > 0) { |
| @@ -2379,6 +2506,9 @@ bool GLES2Implementation::BindBufferHelper( |
| changed = true; |
| } |
| break; |
| + case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| + bound_pixel_unpack_transfer_buffer_id_ = buffer; |
| + break; |
| default: |
| changed = true; |
| break; |
| @@ -2500,6 +2630,17 @@ void GLES2Implementation::DeleteBuffersHelper( |
| if (buffers[ii] == bound_element_array_buffer_id_) { |
| bound_element_array_buffer_id_ = 0; |
| } |
| + if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { |
| + bound_pixel_unpack_transfer_buffer_id_ = 0; |
| + } |
| + |
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); |
| + if (buffer) { |
| + // Free buffer memory, pending the passage of a token. |
| + buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
| + // Remove buffer. |
| + buffer_tracker_->RemoveBuffer(buffers[ii]); |
| + } |
| } |
| } |
| @@ -3469,6 +3610,53 @@ void GLES2Implementation::TraceBeginCHROMIUM(const char* name) { |
| helper_->SetBucketSize(kResultBucketId, 0); |
| } |
| +void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { |
| + GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferCHROMIUM(" |
| + << target << ", " << GLES2Util::GetStringEnum(access) << ")"); |
| + if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { |
|
greggman
2012/11/19 04:50:14
Looking at glMapBuffer you're not aloud to map a b
reveman
2012/11/20 16:49:30
Done.
|
| + SetGLError( |
| + GL_INVALID_ENUM, "glMapBufferCHROMIUM", "invalid target"); |
| + return NULL; |
| + } |
| + if (access != GL_WRITE_ONLY) { |
| + SetGLError( |
| + GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode"); |
| + return NULL; |
| + } |
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| + bound_pixel_unpack_transfer_buffer_id_); |
| + if (!buffer) { |
| + SetGLError( |
| + GL_INVALID_VALUE, "glMapBufferCHROMIUM", "invalid buffer"); |
| + return NULL; |
| + } |
| + |
| + GPU_DCHECK(buffer->address()); |
| + GPU_CLIENT_LOG(" returned " << buffer->address()); |
| + return buffer->address(); |
| +} |
| + |
| +GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
| + GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| + GPU_CLIENT_LOG( |
| + "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); |
| + if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { |
| + SetGLError( |
| + GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); |
| + return false; |
| + } |
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| + bound_pixel_unpack_transfer_buffer_id_); |
| + if (!buffer) { |
| + SetGLError( |
| + GL_INVALID_VALUE, "glMapBufferCHROMIUM", "invalid buffer"); |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| // 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. |