| 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..2ec061cc1212e1ee3dc0c66f5bcfad59d32a81bf 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,11 +101,13 @@ 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),
|
| current_query_(NULL),
|
| - error_message_callback_(NULL) {
|
| + error_message_callback_(NULL),
|
| + gpu_memory_buffer_factory_(NULL) {
|
| GPU_DCHECK(helper);
|
| GPU_DCHECK(transfer_buffer);
|
|
|
| @@ -173,6 +178,8 @@ 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(
|
| + gpu_memory_buffer_factory_));
|
|
|
| #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| GetIdHandler(id_namespaces::kBuffers)->MakeIds(
|
| @@ -630,6 +637,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 +1255,17 @@ void GLES2Implementation::ShaderSource(
|
| CheckGLError();
|
| }
|
|
|
| +void 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");
|
| + }
|
| +
|
| + return;
|
| +}
|
| +
|
| void GLES2Implementation::BufferDataHelper(
|
| GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
|
| if (size < 0) {
|
| @@ -2029,6 +2050,10 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) {
|
| "GL_CHROMIUM_map_sub "
|
| "GL_CHROMIUM_shallow_flush "
|
| "GL_EXT_unpack_subimage";
|
| + if (gpu_memory_buffer_factory_ != NULL) {
|
| + str += " ";
|
| + str += "GL_CHROMIUM_gpu_memory_buffer";
|
| + }
|
| break;
|
| default:
|
| break;
|
| @@ -2274,6 +2299,10 @@ void GLES2Implementation::GenQueriesEXTHelper(
|
| GLsizei /* n */, const GLuint* /* queries */) {
|
| }
|
|
|
| +void GLES2Implementation::GenImageBuffersHelper(
|
| + GLsizei /* n */, const GLuint* /* queries */) {
|
| +}
|
| +
|
| // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id
|
| // generates a new resource. On newer versions of OpenGL they don't. The code
|
| // related to binding below will need to change if we switch to the new OpenGL
|
| @@ -2301,6 +2330,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;
|
| @@ -2535,6 +2567,34 @@ void GLES2Implementation::DeleteVertexArraysOESHelper(
|
| }
|
| }
|
|
|
| +void GLES2Implementation::DeleteImageBuffersHelper(
|
| + GLsizei n, const GLuint* imagebuffers) {
|
| + if (!GetIdHandler(id_namespaces::kImageBuffers)->FreeIds(
|
| + this, n, imagebuffers, &GLES2Implementation::DeleteImageBuffersStub)) {
|
| + SetGLError(
|
| + GL_INVALID_VALUE,
|
| + "glDeleteImageBuffers", "id not created by this context.");
|
| + return;
|
| + }
|
| +
|
| + for (GLsizei ii = 0; ii < n; ++ii) {
|
| + if (imagebuffers[ii] == bound_gpu_memory_buffer_id_) {
|
| + bound_gpu_memory_buffer_id_ = 0;
|
| + }
|
| +
|
| + GpuMemoryBuffer* gpu_buffer =
|
| + gpu_memory_buffer_tracker_->GetBuffer(imagebuffers[ii]);
|
| + if (gpu_buffer) {
|
| + gpu_memory_buffer_tracker_->RemoveBuffer(imagebuffers[ii]);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void GLES2Implementation::DeleteImageBuffersStub(
|
| + GLsizei n, const GLuint* imagebuffers) {
|
| + helper_->DeleteImageBuffersImmediate(n, imagebuffers);
|
| +}
|
| +
|
| void GLES2Implementation::DeleteVertexArraysOESStub(
|
| GLsizei n, const GLuint* arrays) {
|
| helper_->DeleteVertexArraysOESImmediate(n, arrays);
|
| @@ -3390,40 +3450,92 @@ void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) {
|
| return NULL;
|
| }
|
| break;
|
| + case GL_IMAGE_BUFFER_CHROMIUM:
|
| + break;
|
| default:
|
| 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 +3543,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, "glUnmapBufferCHROMIUM", "not mapped");
|
| + 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, "glUnmapBufferCHROMIUM",
|
| + "invalid buffer");
|
| + break;
|
| + }
|
| + if (!buffer->mapped()) {
|
| + SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "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 +3701,43 @@ GLuint GLES2Implementation::InsertSyncPointCHROMIUM() {
|
| return helper_->InsertSyncPointCHROMIUM();
|
| }
|
|
|
| +void GLES2Implementation::CreateGpuMemoryBuffer2DCHROMIUMHelper(
|
| + GLuint image_id, GLint width, GLint height) {
|
| + if (width < 0) {
|
| + SetGLError(GL_INVALID_VALUE, "glCreateGpuMemoryBuffer2DCHROMIUM",
|
| + "width < 0");
|
| + return;
|
| + }
|
| +
|
| + if (height < 0) {
|
| + SetGLError(GL_INVALID_VALUE, "glCreateGpuMemoryBuffer2DCHROMIUM",
|
| + "height < 0");
|
| + return;
|
| + }
|
| +
|
| + if (gpu_memory_buffer_tracker_->GetBuffer(image_id) != NULL) {
|
| + SetGLError(GL_INVALID_VALUE, "glCreateGpuMemoryBuffer2DCHROMIUM",
|
| + "existing image_id");
|
| + return;
|
| + }
|
| +
|
| + if (width != 0 && height != 0) {
|
| + // Create new buffer.
|
| + gpu_memory_buffer_tracker_->CreateBuffer(image_id, width, height);
|
| + }
|
| +}
|
| +
|
| +void GLES2Implementation::CreateGpuMemoryBuffer2DCHROMIUM(
|
| + GLuint image_id, GLint width, GLint height) {
|
| + GPU_CLIENT_SINGLE_THREAD_CHECK();
|
| + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateGpuMemoryBuffer2DCHROMIUM("
|
| + << image_id << ", "
|
| + << width << ", "
|
| + << height << ")");
|
| + CreateGpuMemoryBuffer2DCHROMIUMHelper(image_id, 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.
|
|
|