diff options
Diffstat (limited to 'gpu')
-rwxr-xr-x | gpu/command_buffer/build_gles2_cmd_buffer.py | 14 | ||||
-rw-r--r-- | gpu/command_buffer/client/buffer_tracker.cc | 69 | ||||
-rw-r--r-- | gpu/command_buffer/client/buffer_tracker.h | 103 | ||||
-rw-r--r-- | gpu/command_buffer/client/buffer_tracker_unittest.cc | 74 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_c_lib_autogen.h | 10 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation.cc | 188 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation.h | 19 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation_autogen.h | 4 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_interface_autogen.h | 2 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_interface_stub_autogen.h | 2 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h | 7 | ||||
-rw-r--r-- | gpu/command_buffer/cmd_buffer_functions.txt | 3 | ||||
-rw-r--r-- | gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h | 2 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info.cc | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/gl_utils.h | 4 | ||||
-rw-r--r-- | gpu/gpu.gyp | 1 | ||||
-rw-r--r-- | gpu/gpu_common.gypi | 2 |
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', |