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 aa5792a04498f6c172502a32bb72864802d1dd15..824e91f77d859b8c2a965d42faaf96c966dc455f 100644 |
| --- a/gpu/command_buffer/client/gles2_implementation.cc |
| +++ b/gpu/command_buffer/client/gles2_implementation.cc |
| @@ -16,6 +16,9 @@ |
| #include <GLES2/gl2ext.h> |
| #include <GLES2/gl2extchromium.h> |
| #include "../client/buffer_tracker.h" |
| +#include "../client/gpu_memory_buffer.h" |
| +#include "../client/gpu_memory_buffer_factory.h" |
| +#include "../client/gpu_memory_buffer_tracker.h" |
| #include "../client/mapped_memory.h" |
| #include "../client/program_info_manager.h" |
| #include "../client/query_tracker.h" |
| @@ -98,6 +101,7 @@ GLES2Implementation::GLES2Implementation( |
| bound_array_buffer_id_(0), |
| bound_pixel_pack_transfer_buffer_id_(0), |
| bound_pixel_unpack_transfer_buffer_id_(0), |
| + bound_gpu_memory_buffer_id_(0), |
| error_bits_(0), |
| debug_(false), |
| use_count_(0), |
| @@ -173,6 +177,7 @@ bool GLES2Implementation::Initialize( |
| query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
| buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); |
| + gpu_memory_buffer_tracker_.reset(new GpuMemoryBufferTracker()); |
| #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
| @@ -630,6 +635,9 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { |
| return true; |
| } |
| return false; |
| + case GL_IMAGE_BUFFER_BINDING_CHROMIUM: |
| + *params = bound_gpu_memory_buffer_id_; |
| + return true; |
| default: |
| return false; |
| } |
| @@ -1245,6 +1253,17 @@ void GLES2Implementation::ShaderSource( |
| CheckGLError(); |
| } |
| +bool GLES2Implementation::GetBoundGpuMemoryBuffer( |
| + const char* function_name, GLuint* buffer_id) { |
| + *buffer_id = bound_gpu_memory_buffer_id_; |
| + |
| + if (*buffer_id == 0) { |
| + SetGLError(GL_INVALID_OPERATION, function_name, "no buffer bound"); |
|
greggman
2013/04/29 19:58:33
This function returns only ever returns 'true'. Sh
kaanb
2013/04/30 03:40:10
Done.
|
| + } |
| + |
| + return true; |
| +} |
| + |
| void GLES2Implementation::BufferDataHelper( |
| GLenum target, GLsizeiptr size, const void* data, GLenum usage) { |
| if (size < 0) { |
| @@ -2029,6 +2048,10 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) { |
| "GL_CHROMIUM_map_sub " |
| "GL_CHROMIUM_shallow_flush " |
| "GL_EXT_unpack_subimage"; |
| + if (!GetProcessDefaultGpuMemoryBufferFactory().is_null()) { |
| + str += " "; |
|
greggman
2013/04/29 19:58:33
Sadly this probably has to be the same as above, o
kaanb
2013/04/30 03:40:10
Here str is guaranteed to be non-empty though. We
|
| + str += "GL_CHROMIUM_gpu_memory_buffer"; |
| + } |
| break; |
| default: |
| break; |
| @@ -2301,6 +2324,9 @@ bool GLES2Implementation::BindBufferHelper( |
| case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| bound_pixel_unpack_transfer_buffer_id_ = buffer; |
| break; |
| + case GL_IMAGE_BUFFER_CHROMIUM: |
| + bound_gpu_memory_buffer_id_ = buffer; |
| + break; |
| default: |
| changed = true; |
| break; |
| @@ -2445,6 +2471,14 @@ void GLES2Implementation::DeleteBuffersHelper( |
| if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { |
| bound_pixel_unpack_transfer_buffer_id_ = 0; |
| } |
| + if (buffers[ii] == bound_gpu_memory_buffer_id_) { |
| + bound_gpu_memory_buffer_id_ = 0; |
| + } |
| + GpuMemoryBuffer* gpu_buffer = |
| + gpu_memory_buffer_tracker_->GetBuffer(buffers[ii]); |
| + if (gpu_buffer) { |
| + gpu_memory_buffer_tracker_->RemoveBuffer(buffers[ii]); |
| + } |
| } |
| } |
| @@ -3390,40 +3424,93 @@ void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { |
| return NULL; |
| } |
| break; |
| + case GL_IMAGE_BUFFER_CHROMIUM: |
| + break; |
| default: |
| + // TODO(kaanb): Do we need matching CheckGLError() calls for these? |
|
greggman
2013/04/29 19:58:33
no I don't think you do. CheckGLError is for debug
kaanb
2013/04/30 03:40:10
Done.
|
| SetGLError( |
| GL_INVALID_ENUM, "glMapBufferCHROMIUM", "invalid target"); |
| return NULL; |
| } |
| + |
| GLuint buffer_id; |
| - GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id); |
| - if (!buffer_id) { |
| - return NULL; |
| - } |
| - BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| - if (!buffer) { |
| - SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); |
| - return NULL; |
| - } |
| - if (buffer->mapped()) { |
| - SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); |
| - return NULL; |
| - } |
| - // Here we wait for previous transfer operations to be finished. |
| - // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work |
| - // with this method of synchronization. Until this is fixed, |
| - // MapBufferCHROMIUM will not block even if the transfer is not ready |
| - // for these calls. |
| - if (buffer->transfer_ready_token()) { |
| - helper_->WaitForToken(buffer->transfer_ready_token()); |
| - buffer->set_transfer_ready_token(0); |
| - } |
| - buffer->set_mapped(true); |
| + switch(target) { |
| + case GL_IMAGE_BUFFER_CHROMIUM: { |
| + GetBoundGpuMemoryBuffer("glMapBufferCHROMIUM", &buffer_id); |
| + if (buffer_id == 0) { |
| + return NULL; |
| + } |
| + GpuMemoryBuffer* gpu_buffer = |
| + gpu_memory_buffer_tracker_->GetBuffer(buffer_id); |
| + if (!gpu_buffer) { |
| + SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", |
| + "invalid GPU memory buffer"); |
| + return NULL; |
| + } |
| + GpuMemoryBuffer::AccessMode mode = GpuMemoryBuffer::READ_ONLY; |
| + switch(access) { |
| + case GL_WRITE_ONLY: |
| + mode = GpuMemoryBuffer::WRITE_ONLY; |
| + break; |
| + case GL_READ_ONLY: |
| + mode = GpuMemoryBuffer::READ_ONLY; |
| + break; |
| + // TODO(kaanb): should we add GL_READ_WRITE to gl2ext.h? |
| + default: |
| + SetGLError( |
| + GL_INVALID_ENUM, "glMapBufferCHROMIUM", |
| + "invalid GPU access mode"); |
| + return NULL; |
| + } |
| - GPU_DCHECK(buffer->address()); |
| - GPU_CLIENT_LOG(" returned " << buffer->address()); |
| - CheckGLError(); |
| - return buffer->address(); |
| + if (gpu_buffer->IsMapped()) { |
| + SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", |
| + "already mapped"); |
| + return NULL; |
| + } |
| + |
| + void* mapped_buffer = NULL; |
| + gpu_buffer->Map(mode, &mapped_buffer); |
| + CheckGLError(); |
| + return mapped_buffer; |
| + } |
| + case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| + case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: { |
| + GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id); |
| + if (!buffer_id) { |
| + return NULL; |
| + } |
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| + if (!buffer) { |
| + SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", |
| + "invalid buffer"); |
| + return NULL; |
| + } |
| + if (buffer->mapped()) { |
| + SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", |
| + "already mapped"); |
| + return NULL; |
| + } |
| + // Here we wait for previous transfer operations to be finished. |
| + // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work |
| + // with this method of synchronization. Until this is fixed, |
| + // MapBufferCHROMIUM will not block even if the transfer is not ready |
| + // for these calls. |
| + if (buffer->transfer_ready_token()) { |
| + helper_->WaitForToken(buffer->transfer_ready_token()); |
| + buffer->set_transfer_ready_token(0); |
| + } |
| + buffer->set_mapped(true); |
| + |
| + GPU_DCHECK(buffer->address()); |
| + GPU_CLIENT_LOG(" returned " << buffer->address()); |
| + CheckGLError(); |
| + return buffer->address(); |
| + } |
| + default: |
| + return NULL; |
| + } |
| + return NULL; |
| } |
| GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
| @@ -3431,24 +3518,50 @@ GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
| GPU_CLIENT_LOG( |
| "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); |
| GLuint buffer_id; |
| - if (!GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id)) { |
| - SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); |
| - } |
| - if (!buffer_id) { |
| - return false; |
| - } |
| - BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| - if (!buffer) { |
| - SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); |
| - return false; |
| - } |
| - if (!buffer->mapped()) { |
| - SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped"); |
| - return false; |
| + switch(target) { |
| + case GL_IMAGE_BUFFER_CHROMIUM: { |
| + GetBoundGpuMemoryBuffer("glUnmapBufferCHROMIUM", &buffer_id); |
| + if (buffer_id == 0) { |
| + break; |
| + } |
| + GpuMemoryBuffer* gpu_buffer = |
| + gpu_memory_buffer_tracker_->GetBuffer(buffer_id); |
| + |
| + if (!gpu_buffer->IsMapped()) { |
| + SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped"); |
|
greggman
2013/04/29 19:58:33
Here and below s/glMap/glUnmap/
kaanb
2013/04/30 03:40:10
Done.
|
| + break; |
| + } |
| + gpu_buffer->Unmap(); |
| + return true; |
| + } |
| + case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| + case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: { |
| + if (!GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", |
| + &buffer_id)) { |
| + SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); |
| + break; |
| + } |
| + if (!buffer_id) { |
| + break; |
| + } |
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| + if (!buffer) { |
| + SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", |
| + "invalid buffer"); |
| + break; |
| + } |
| + if (!buffer->mapped()) { |
| + SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped"); |
| + break; |
| + } |
| + buffer->set_mapped(false); |
| + return true; |
| + } |
| + default: |
| + SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); |
| } |
| - buffer->set_mapped(false); |
| CheckGLError(); |
| - return true; |
| + return false; |
| } |
| void GLES2Implementation::AsyncTexImage2DCHROMIUM( |
| @@ -3563,6 +3676,69 @@ GLuint GLES2Implementation::InsertSyncPointCHROMIUM() { |
| return helper_->InsertSyncPointCHROMIUM(); |
| } |
| +void* GLES2Implementation::GetNativeHandleForBoundGpuMemoryBuffer() { |
| + if (bound_gpu_memory_buffer_id_ == 0) { |
| + return NULL; |
| + } |
| + |
| + GpuMemoryBuffer* buffer = |
| + gpu_memory_buffer_tracker_->GetBuffer(bound_gpu_memory_buffer_id_); |
| + |
| + return (buffer != NULL) ? buffer->GetNativeBuffer() : NULL; |
| +} |
| + |
| +void GLES2Implementation::ImageBufferDataCHROMIUMHelper( |
| + GLenum target, GLsizei width, GLsizei height) { |
| + if (width < 0) { |
| + SetGLError(GL_INVALID_VALUE, "glImageBufferDataCHROMIUM", "width < 0"); |
| + return; |
| + } |
| + |
| + if (height < 0) { |
| + SetGLError(GL_INVALID_VALUE, "glImageBufferDataCHROMIUM", "height < 0"); |
| + return; |
| + } |
| + |
| + if (target != GL_IMAGE_BUFFER_CHROMIUM) { |
| + SetGLErrorInvalidEnum("glImageBufferDataCHROMIUM", target, "target"); |
| + return; |
| + } |
| + |
| + GLuint buffer_id; |
| + bool found_buffer = GetBoundGpuMemoryBuffer( |
| + "glImageBufferDataCHROMIUM", &buffer_id); |
| + |
| + if (!found_buffer || buffer_id == 0) { |
| + return; |
| + } |
| + |
| + GpuMemoryBuffer* buffer = |
| + gpu_memory_buffer_tracker_->GetBuffer(buffer_id); |
| + if (buffer) { |
| + // Remove old buffer, deletes the buffer pointer. |
| + gpu_memory_buffer_tracker_->RemoveBuffer(buffer_id); |
| + } |
| + |
| + if (width != 0 && height != 0) { |
| + // Create new buffer. |
| + buffer = gpu_memory_buffer_tracker_->CreateBuffer(buffer_id, width, height); |
| + GPU_DCHECK(buffer); |
| + } |
| + |
| + return; |
| +} |
| + |
| +void GLES2Implementation::ImageBufferDataCHROMIUM( |
| + GLenum target, GLsizei width, GLsizei height) { |
| + GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glImageBufferDataCHROMIUM(" |
| + << GLES2Util::GetStringBufferTarget(target) << ", " |
| + << width << ", " |
| + << height << ")"); |
| + ImageBufferDataCHROMIUMHelper(target, width, height); |
| + 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. |