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 8960cff9767e1fd7c46ccaecce8f2eca089577bc..f493d37af3debf9ce0ea619a03ef7feda36b275a 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" |
@@ -439,6 +440,7 @@ GLES2Implementation::GLES2Implementation( |
bound_renderbuffer_(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), |
@@ -515,6 +517,7 @@ bool GLES2Implementation::Initialize( |
new TextureUnit[gl_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( |
@@ -540,6 +543,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. |
@@ -960,6 +965,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()) { |
+ *params = bound_pixel_unpack_transfer_buffer_id_; |
+ return true; |
+ } |
+ return false; |
case GL_ACTIVE_TEXTURE: |
*params = active_texture_unit_ + GL_TEXTURE0; |
return true; |
@@ -1265,6 +1276,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) |
+ helper_->BindBuffer(target, buffer); |
+} |
+ |
void GLES2Implementation::BindUniformLocationCHROMIUM( |
GLuint program, GLint location, const char* name) { |
GPU_CLIENT_SINGLE_THREAD_CHECK(); |
@@ -1612,6 +1636,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); |
@@ -1718,6 +1766,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); |
@@ -1743,6 +1811,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( |
+ 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); |
@@ -1814,6 +1903,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( |
@@ -1901,6 +2009,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) { |
@@ -2417,6 +2544,9 @@ void GLES2Implementation::BindBufferHelper( |
case GL_ELEMENT_ARRAY_BUFFER: |
bound_element_array_buffer_id_ = buffer; |
break; |
+ case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
+ bound_pixel_unpack_transfer_buffer_id_ = buffer; |
+ break; |
default: |
break; |
} |
@@ -2511,6 +2641,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]); |
+ } |
} |
} |
@@ -3470,6 +3611,53 @@ void GLES2Implementation::PopGroupMarkerEXT() { |
debug_marker_manager_.PopGroup(); |
} |
+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) { |
+ 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. |