| 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 b0b228d5c3e84c880a5e1d1a7694dcafe8f233c5..43b88a09f0fd78da586f001cf6166e380d9f7667 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,9 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) {
|
| return true;
|
| }
|
| return false;
|
| + case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM:
|
| + *params = bound_pixel_unpack_transfer_buffer_id_;
|
| + return true;
|
| case GL_ACTIVE_TEXTURE:
|
| *params = active_texture_unit_ + GL_TEXTURE0;
|
| return true;
|
| @@ -1612,6 +1620,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);
|
| @@ -1662,6 +1694,26 @@ void GLES2Implementation::BufferSubDataHelper(
|
| return;
|
| }
|
|
|
| + if (target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) {
|
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(
|
| + bound_pixel_unpack_transfer_buffer_id_);
|
| + if (!buffer) {
|
| + SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
|
| + return;
|
| + }
|
| +
|
| + int32 end = 0;
|
| + int32 buffer_size = buffer->size();
|
| + if (!SafeAddInt32(offset, size, &end) || end > buffer_size) {
|
| + SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range");
|
| + return;
|
| + }
|
| +
|
| + if (data)
|
| + memcpy(static_cast<uint8*>(buffer->address()) + offset, data, size);
|
| + return;
|
| + }
|
| +
|
| ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
|
| BufferSubDataHelperImpl(target, offset, size, data, &buffer);
|
| }
|
| @@ -1700,6 +1752,27 @@ void GLES2Implementation::BufferSubData(
|
| BufferSubDataHelper(target, offset, size, data);
|
| }
|
|
|
| +BufferTracker::Buffer*
|
| +GLES2Implementation::GetBoundPixelUnpackTransferBufferIfValid(
|
| + const char* function_name, GLuint offset, GLsizei size)
|
| +{
|
| + BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(
|
| + bound_pixel_unpack_transfer_buffer_id_);
|
| + if (!buffer) {
|
| + SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer");
|
| + return NULL;
|
| + }
|
| + if (buffer->mapped()) {
|
| + SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped");
|
| + return NULL;
|
| + }
|
| + if ((buffer->size() - offset) < static_cast<GLuint>(size)) {
|
| + SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large");
|
| + return NULL;
|
| + }
|
| + return buffer;
|
| +}
|
| +
|
| void GLES2Implementation::CompressedTexImage2D(
|
| GLenum target, GLint level, GLenum internalformat, GLsizei width,
|
| GLsizei height, GLint border, GLsizei image_size, const void* data) {
|
| @@ -1718,6 +1791,18 @@ 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_) {
|
| + GLuint offset = ToGLuint(data);
|
| + BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
|
| + "glCompressedTexImage2D", offset, image_size);
|
| + if (buffer)
|
| + 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 +1828,18 @@ 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_) {
|
| + GLuint offset = ToGLuint(data);
|
| + BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
|
| + "glCompressedTexSubImage2D", offset, image_size);
|
| + if (buffer)
|
| + 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 +1911,18 @@ void GLES2Implementation::TexImage2D(
|
| return;
|
| }
|
|
|
| + // If there's a pixel unpack buffer bound use it when issuing TexImage2D.
|
| + if (bound_pixel_unpack_transfer_buffer_id_) {
|
| + GLuint offset = ToGLuint(pixels);
|
| + BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
|
| + "glTexImage2D", offset, size);
|
| + if (buffer)
|
| + 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 +2010,18 @@ void GLES2Implementation::TexSubImage2D(
|
| return;
|
| }
|
|
|
| + // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D.
|
| + if (bound_pixel_unpack_transfer_buffer_id_) {
|
| + GLuint offset = ToGLuint(pixels);
|
| + BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
|
| + "glTexSubImage2D", offset, temp_size);
|
| + if (buffer)
|
| + 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 +2538,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 +2635,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]);
|
| + }
|
| }
|
| }
|
|
|
| @@ -3480,6 +3615,59 @@ 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) {
|
| + 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_OPERATION, "glMapBufferCHROMIUM", "invalid buffer");
|
| + return NULL;
|
| + }
|
| + if (buffer->mapped()) {
|
| + SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped");
|
| + return NULL;
|
| + }
|
| + buffer->set_mapped(true);
|
| +
|
| + 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_OPERATION, "glMapBufferCHROMIUM", "invalid buffer");
|
| + return false;
|
| + }
|
| + if (!buffer->mapped()) {
|
| + SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped");
|
| + return false;
|
| + }
|
| + buffer->set_mapped(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.
|
|
|