summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'gpu')
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py14
-rw-r--r--gpu/command_buffer/client/buffer_tracker.cc69
-rw-r--r--gpu/command_buffer/client/buffer_tracker.h103
-rw-r--r--gpu/command_buffer/client/buffer_tracker_unittest.cc74
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h10
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc188
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h19
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h4
-rw-r--r--gpu/command_buffer/client/gles2_interface_autogen.h2
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_autogen.h2
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h7
-rw-r--r--gpu/command_buffer/cmd_buffer_functions.txt3
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h2
-rw-r--r--gpu/command_buffer/service/feature_info.cc1
-rw-r--r--gpu/command_buffer/service/gl_utils.h4
-rw-r--r--gpu/gpu.gyp1
-rw-r--r--gpu/gpu_common.gypi2
17 files changed, 500 insertions, 5 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 21a9290..33690bf 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -1702,6 +1702,13 @@ _FUNCTION_INFO = {
'decoder_func': 'DoLinkProgram',
'impl_func': False,
},
+ 'MapBufferCHROMIUM': {
+ 'gen_cmd': False,
+ 'extension': True,
+ 'chromium': True,
+ 'client_test': False,
+ 'chromium': True,
+ },
'MapBufferSubDataCHROMIUM': {
'gen_cmd': False,
'extension': True,
@@ -1924,6 +1931,13 @@ _FUNCTION_INFO = {
'count': 16,
'decoder_func': 'DoUniformMatrix4fv',
},
+ 'UnmapBufferCHROMIUM': {
+ 'gen_cmd': False,
+ 'extension': True,
+ 'chromium': True,
+ 'client_test': False,
+ 'chromium': True,
+ },
'UnmapBufferSubDataCHROMIUM': {
'gen_cmd': False,
'extension': True,
diff --git a/gpu/command_buffer/client/buffer_tracker.cc b/gpu/command_buffer/client/buffer_tracker.cc
new file mode 100644
index 0000000..3e4e087
--- /dev/null
+++ b/gpu/command_buffer/client/buffer_tracker.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "../client/buffer_tracker.h"
+
+#include "../client/atomicops.h"
+#include "../client/cmd_buffer_helper.h"
+#include "../client/mapped_memory.h"
+
+namespace gpu {
+namespace gles2 {
+
+BufferTracker::BufferTracker(MappedMemoryManager* manager)
+ : mapped_memory_(manager) {
+}
+
+BufferTracker::~BufferTracker() {
+ while (!buffers_.empty()) {
+ RemoveBuffer(buffers_.begin()->first);
+ }
+}
+
+BufferTracker::Buffer* BufferTracker::CreateBuffer(
+ GLuint id, GLsizeiptr size) {
+ GPU_DCHECK_NE(0u, id);
+ GPU_DCHECK_LT(0, size);
+ int32 shm_id;
+ uint32 shm_offset;
+ void* address = mapped_memory_->Alloc(size, &shm_id, &shm_offset);
+ if (!address) {
+ return NULL;
+ }
+
+ Buffer* buffer = new Buffer(id, size, shm_id, shm_offset, address);
+ std::pair<BufferMap::iterator, bool> result =
+ buffers_.insert(std::make_pair(id, buffer));
+ GPU_DCHECK(result.second);
+ return buffer;
+}
+
+BufferTracker::Buffer* BufferTracker::GetBuffer(GLuint client_id) {
+ BufferMap::iterator it = buffers_.find(client_id);
+ return it != buffers_.end() ? it->second : NULL;
+}
+
+void BufferTracker::RemoveBuffer(GLuint client_id) {
+ BufferMap::iterator it = buffers_.find(client_id);
+ if (it != buffers_.end()) {
+ Buffer* buffer = it->second;
+ buffers_.erase(it);
+ if (buffer->address_)
+ mapped_memory_->Free(buffer->address_);
+ delete buffer;
+ }
+}
+
+void BufferTracker::FreePendingToken(Buffer* buffer, int32 token) {
+ GPU_DCHECK(buffer->address_);
+ mapped_memory_->FreePendingToken(buffer->address_, token);
+ buffer->size_ = 0;
+ buffer->shm_id_ = 0;
+ buffer->shm_offset_ = 0;
+ buffer->address_ = NULL;
+}
+
+
+} // namespace gles2
+} // namespace gpu
diff --git a/gpu/command_buffer/client/buffer_tracker.h b/gpu/command_buffer/client/buffer_tracker.h
new file mode 100644
index 0000000..54f5bc7
--- /dev/null
+++ b/gpu/command_buffer/client/buffer_tracker.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_CLIENT_BUFFER_TRACKER_H_
+#define GPU_COMMAND_BUFFER_CLIENT_BUFFER_TRACKER_H_
+
+#include <GLES2/gl2.h>
+
+#include <queue>
+#include "../client/hash_tables.h"
+#include "../common/gles2_cmd_format.h"
+#include "gles2_impl_export.h"
+
+namespace gpu {
+
+class CommandBufferHelper;
+class MappedMemoryManager;
+
+namespace gles2 {
+
+// Tracks buffer objects for client side of command buffer.
+class GLES2_IMPL_EXPORT BufferTracker {
+ public:
+ class GLES2_IMPL_EXPORT Buffer {
+ public:
+ Buffer(GLuint id,
+ unsigned int size,
+ int32 shm_id,
+ uint32 shm_offset,
+ void* address)
+ : id_(id),
+ size_(size),
+ shm_id_(shm_id),
+ shm_offset_(shm_offset),
+ address_(address),
+ mapped_(false) {
+ }
+
+ GLenum id() const {
+ return id_;
+ }
+
+ unsigned int size() const {
+ return size_;
+ }
+
+ int32 shm_id() const {
+ return shm_id_;
+ }
+
+ uint32 shm_offset() const {
+ return shm_offset_;
+ }
+
+ void* address() const {
+ return address_;
+ }
+
+ void set_mapped(bool mapped) {
+ mapped_ = mapped;
+ }
+
+ bool mapped() const {
+ return mapped_;
+ }
+
+ private:
+ friend class BufferTracker;
+ friend class BufferTrackerTest;
+
+ GLuint id_;
+ unsigned int size_;
+ int32 shm_id_;
+ uint32 shm_offset_;
+ void* address_;
+ bool mapped_;
+ };
+
+ BufferTracker(MappedMemoryManager* manager);
+ ~BufferTracker();
+
+ Buffer* CreateBuffer(GLuint id, GLsizeiptr size);
+ Buffer* GetBuffer(GLuint id);
+ void RemoveBuffer(GLuint id);
+
+ // Frees the block of memory associated with buffer, pending the passage
+ // of a token.
+ void FreePendingToken(Buffer*, int32 token);
+
+ private:
+ typedef gpu::hash_map<GLuint, Buffer*> BufferMap;
+
+ MappedMemoryManager* mapped_memory_;
+ BufferMap buffers_;
+
+ DISALLOW_COPY_AND_ASSIGN(BufferTracker);
+};
+
+} // namespace gles2
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_CLIENT_BUFFER_TRACKER_H_
diff --git a/gpu/command_buffer/client/buffer_tracker_unittest.cc b/gpu/command_buffer/client/buffer_tracker_unittest.cc
new file mode 100644
index 0000000..b1a459c
--- /dev/null
+++ b/gpu/command_buffer/client/buffer_tracker_unittest.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Tests for the BufferTracker.
+
+#include "gpu/command_buffer/client/buffer_tracker.h"
+
+#include <GLES2/gl2ext.h>
+#include "base/memory/scoped_ptr.h"
+#include "gpu/command_buffer/client/client_test_helper.h"
+#include "gpu/command_buffer/client/gles2_cmd_helper.h"
+#include "gpu/command_buffer/client/mapped_memory.h"
+#include "gpu/command_buffer/common/command_buffer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gpu {
+namespace gles2 {
+
+class BufferTrackerTest : public testing::Test {
+ protected:
+ static const int32 kNumCommandEntries = 400;
+ static const int32 kCommandBufferSizeBytes =
+ kNumCommandEntries * sizeof(CommandBufferEntry);
+
+ virtual void SetUp() {
+ command_buffer_.reset(new MockClientCommandBuffer());
+ helper_.reset(new GLES2CmdHelper(command_buffer_.get()));
+ helper_->Initialize(kCommandBufferSizeBytes);
+ mapped_memory_.reset(new MappedMemoryManager(helper_.get()));
+ buffer_tracker_.reset(new BufferTracker(mapped_memory_.get()));
+ }
+
+ virtual void TearDown() {
+ buffer_tracker_.reset();
+ mapped_memory_.reset();
+ helper_.reset();
+ command_buffer_.reset();
+ }
+
+ scoped_ptr<CommandBuffer> command_buffer_;
+ scoped_ptr<GLES2CmdHelper> helper_;
+ scoped_ptr<MappedMemoryManager> mapped_memory_;
+ scoped_ptr<BufferTracker> buffer_tracker_;
+};
+
+TEST_F(BufferTrackerTest, Basic) {
+ const GLuint kId1 = 123;
+ const GLuint kId2 = 124;
+ const GLsizeiptr size = 64;
+
+ // Check we can create a Buffer.
+ BufferTracker::Buffer* buffer = buffer_tracker_->CreateBuffer(kId1, size);
+ ASSERT_TRUE(buffer != NULL);
+ // Check we can get the same Buffer.
+ EXPECT_EQ(buffer, buffer_tracker_->GetBuffer(kId1));
+ // Check mapped memory address.
+ EXPECT_TRUE(buffer->address() != NULL);
+ // Check shared memory was allocated.
+ EXPECT_EQ(1lu, mapped_memory_->num_chunks());
+ // Check we get nothing for a non-existent buffer.
+ EXPECT_TRUE(buffer_tracker_->GetBuffer(kId2) == NULL);
+ // Check we can delete the buffer.
+ buffer_tracker_->RemoveBuffer(kId1);
+ // Check shared memory was freed.
+ mapped_memory_->FreeUnused();
+ EXPECT_EQ(0lu, mapped_memory_->num_chunks());
+ // Check we get nothing for a non-existent buffer.
+ EXPECT_TRUE(buffer_tracker_->GetBuffer(kId1) == NULL);
+}
+
+} // namespace gles2
+} // namespace gpu
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index bcc2f6a..6e760c9 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -588,6 +588,12 @@ void GLES2RegisterSharedIdsCHROMIUM(
GLboolean GLES2EnableFeatureCHROMIUM(const char* feature) {
return gles2::GetGLContext()->EnableFeatureCHROMIUM(feature);
}
+void* GLES2MapBufferCHROMIUM(GLuint target, GLenum access) {
+ return gles2::GetGLContext()->MapBufferCHROMIUM(target, access);
+}
+GLboolean GLES2UnmapBufferCHROMIUM(GLuint target) {
+ return gles2::GetGLContext()->UnmapBufferCHROMIUM(target);
+}
void* GLES2MapBufferSubDataCHROMIUM(
GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) {
return gles2::GetGLContext()->MapBufferSubDataCHROMIUM(
@@ -962,6 +968,10 @@ NameToFunc g_gles2_function_table[] = {
glRegisterSharedIdsCHROMIUM), },
{ "glEnableFeatureCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(
glEnableFeatureCHROMIUM), },
+ { "glMapBufferCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(
+ glMapBufferCHROMIUM), },
+ { "glUnmapBufferCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(
+ glUnmapBufferCHROMIUM), },
{ "glMapBufferSubDataCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(
glMapBufferSubDataCHROMIUM), },
{ "glUnmapBufferSubDataCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index b0b228d..43b88a0 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.
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 47fb3b0..47c221c 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -13,16 +13,17 @@
#include <string>
#include <vector>
-#include "../common/compiler_specific.h"
-#include "../common/debug_marker_manager.h"
-#include "../common/gles2_cmd_utils.h"
-#include "../common/scoped_ptr.h"
-#include "../client/ref_counted.h"
+#include "../client/buffer_tracker.h"
#include "../client/gles2_cmd_helper.h"
#include "../client/gles2_interface.h"
#include "../client/query_tracker.h"
+#include "../client/ref_counted.h"
#include "../client/ring_buffer.h"
#include "../client/share_group.h"
+#include "../common/compiler_specific.h"
+#include "../common/debug_marker_manager.h"
+#include "../common/gles2_cmd_utils.h"
+#include "../common/scoped_ptr.h"
#include "gles2_impl_export.h"
#if !defined(NDEBUG) && !defined(__native_client__) && !defined(GLES2_CONFORMANCE_TESTS) // NOLINT
@@ -483,6 +484,9 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface {
// for error checking.
bool MustBeContextLost();
+ BufferTracker::Buffer* GetBoundPixelUnpackTransferBufferIfValid(
+ const char* function_name, GLuint offset, GLsizei size);
+
const std::string& GetLogPrefix() const;
GLES2Util util_;
@@ -534,6 +538,9 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface {
// The currently bound element array buffer.
GLuint bound_element_array_buffer_id_;
+ // The currently bound pixel transfer buffer.
+ GLuint bound_pixel_unpack_transfer_buffer_id_;
+
// GL names for the buffers used to emulate client side buffers.
GLuint client_side_array_id_;
GLuint client_side_element_array_id_;
@@ -578,6 +585,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface {
scoped_ptr<QueryTracker> query_tracker_;
QueryTracker::Query* current_query_;
+ scoped_ptr<BufferTracker> buffer_tracker_;
+
ErrorMessageCallback* error_message_callback_;
DISALLOW_COPY_AND_ASSIGN(GLES2Implementation);
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 0034ba3..b6dce8c 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -434,6 +434,10 @@ virtual void RegisterSharedIdsCHROMIUM(
virtual GLboolean EnableFeatureCHROMIUM(const char* feature) OVERRIDE;
+virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) OVERRIDE;
+
+virtual GLboolean UnmapBufferCHROMIUM(GLuint target) OVERRIDE;
+
virtual void* MapBufferSubDataCHROMIUM(
GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) OVERRIDE;
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index 3879fe11..b83bad5 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -248,6 +248,8 @@ virtual void DeleteSharedIdsCHROMIUM(
virtual void RegisterSharedIdsCHROMIUM(
GLuint namespace_id, GLsizei n, const GLuint* ids) = 0;
virtual GLboolean EnableFeatureCHROMIUM(const char* feature) = 0;
+virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) = 0;
+virtual GLboolean UnmapBufferCHROMIUM(GLuint target) = 0;
virtual void* MapBufferSubDataCHROMIUM(
GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) = 0;
virtual void UnmapBufferSubDataCHROMIUM(const void* mem) = 0;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
index 5ea0131..452b4c7 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -277,6 +277,8 @@ virtual void DeleteSharedIdsCHROMIUM(
virtual void RegisterSharedIdsCHROMIUM(
GLuint namespace_id, GLsizei n, const GLuint* ids) OVERRIDE;
virtual GLboolean EnableFeatureCHROMIUM(const char* feature) OVERRIDE;
+virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) OVERRIDE;
+virtual GLboolean UnmapBufferCHROMIUM(GLuint target) OVERRIDE;
virtual void* MapBufferSubDataCHROMIUM(
GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) OVERRIDE;
virtual void UnmapBufferSubDataCHROMIUM(const void* mem) OVERRIDE;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index 735ac0a..1cf7548 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -520,6 +520,13 @@ GLboolean GLES2InterfaceStub::EnableFeatureCHROMIUM(
const char* /* feature */) {
return 0;
}
+void* GLES2InterfaceStub::MapBufferCHROMIUM(
+ GLuint /* target */, GLenum /* access */) {
+ return 0;
+}
+GLboolean GLES2InterfaceStub::UnmapBufferCHROMIUM(GLuint /* target */) {
+ return 0;
+}
void* GLES2InterfaceStub::MapBufferSubDataCHROMIUM(
GLuint /* target */, GLintptr /* offset */, GLsizeiptr /* size */,
GLenum /* access */) {
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index a759cd0..a91f8db 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -173,6 +173,9 @@ GL_APICALL void GL_APIENTRY glGenSharedIdsCHROMIUM (GLuint namespace_id,
GL_APICALL void GL_APIENTRY glDeleteSharedIdsCHROMIUM (GLuint namespace_id, GLsizeiNotNegative n, const GLuint* ids);
GL_APICALL void GL_APIENTRY glRegisterSharedIdsCHROMIUM (GLuint namespace_id, GLsizeiNotNegative n, const GLuint* ids);
GL_APICALL GLboolean GL_APIENTRY glEnableFeatureCHROMIUM (const char* feature);
+GL_APICALL void* GL_APIENTRY glMapBufferCHROMIUM (GLuint target, GLenum access);
+GL_APICALL GLboolean GL_APIENTRY glUnmapBufferCHROMIUM (GLuint target);
+
GL_APICALL void* GL_APIENTRY glMapBufferSubDataCHROMIUM (GLuint target, GLintptrNotNegative offset, GLsizeiptr size, GLenum access);
GL_APICALL void GL_APIENTRY glUnmapBufferSubDataCHROMIUM (const void* mem);
GL_APICALL void* GL_APIENTRY glMapTexSubImage2DCHROMIUM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum access);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
index 901f52a..03913b4 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -550,6 +550,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x80C9, "GL_BLEND_SRC_RGB", },
{ 0x80C8, "GL_BLEND_DST_RGB", },
{ 0x0504, "GL_STACK_UNDERFLOW", },
+ { 0x88EC, "GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM", },
{ 0x8059, "GL_RGB10_A2_EXT", },
{ 0x8058, "GL_RGBA8_OES", },
{ 0x00002000, "GL_DEPTH_BUFFER_BIT5_QCOM", },
@@ -634,6 +635,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x8CAA, "GL_READ_FRAMEBUFFER_BINDING_ANGLE", },
{ 0x40000000, "GL_MULTISAMPLE_BUFFER_BIT6_QCOM", },
{ 0x9116, "GL_SYNC_FENCE_APPLE", },
+ { 0x88EF, "GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM", },
{ 0x00000800, "GL_DEPTH_BUFFER_BIT3_QCOM", },
{ 0x1903, "GL_RED_EXT", },
{ 0x8CE2, "GL_COLOR_ATTACHMENT2_NV", },
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 7283ac2..3c2365e 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -241,6 +241,7 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
AddExtensionString("GL_CHROMIUM_copy_texture");
AddExtensionString("GL_CHROMIUM_discard_framebuffer");
AddExtensionString("GL_CHROMIUM_get_error_query");
+ AddExtensionString("GL_CHROMIUM_pixel_transfer_buffer_object");
AddExtensionString("GL_CHROMIUM_rate_limit_offscreen_context");
AddExtensionString("GL_CHROMIUM_resize");
AddExtensionString("GL_CHROMIUM_resource_safe");
diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h
index bd3ca49..ccd96f3 100644
--- a/gpu/command_buffer/service/gl_utils.h
+++ b/gpu/command_buffer/service/gl_utils.h
@@ -110,6 +110,10 @@
// GL_OES_vertex_array_object
#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5
+// GL_CHROMIUM_pixel_transfer_buffer_object
+#define GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM 0x78EC
+#define GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM 0x78EF
+
#define GL_GLEXT_PROTOTYPES 1
// GL_ARB_get_program_binary
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index 39feafa..ff0717b 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -130,6 +130,7 @@
],
'sources': [
'<@(gles2_c_lib_source_files)',
+ 'command_buffer/client/buffer_tracker_unittest.cc',
'command_buffer/client/client_test_helper.cc',
'command_buffer/client/client_test_helper.h',
'command_buffer/client/cmd_buffer_helper_test.cc',
diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi
index 24c7e4d..98fb3c1 100644
--- a/gpu/gpu_common.gypi
+++ b/gpu/gpu_common.gypi
@@ -19,6 +19,8 @@
# with without support for client side arrays and once with for pepper and
# the OpenGL ES 2.0 compliant for the conformance tests.
'gles2_implementation_source_files': [
+ 'command_buffer/client/buffer_tracker.cc',
+ 'command_buffer/client/buffer_tracker.h',
'command_buffer/client/gles2_impl_export.h',
'command_buffer/client/gles2_implementation_autogen.h',
'command_buffer/client/gles2_implementation.cc',