diff options
author | zmo <zmo@chromium.org> | 2015-03-10 13:50:34 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-10 20:51:11 +0000 |
commit | a06b988d074e869eec0e910429549d6606e214e4 (patch) | |
tree | b31c780fdfae8104159c817e39963dccb07a01da /gpu | |
parent | 89e07c277ad9986bc814fea1b61f835cebda730a (diff) | |
download | chromium_src-a06b988d074e869eec0e910429549d6606e214e4.zip chromium_src-a06b988d074e869eec0e910429549d6606e214e4.tar.gz chromium_src-a06b988d074e869eec0e910429549d6606e214e4.tar.bz2 |
Add glMapBufferRange to GPU command buffer.
BUG=429053
TEST=gpu_unittests
R=piman@chromium.org
Review URL: https://codereview.chromium.org/960013002
Cr-Commit-Position: refs/heads/master@{#319966}
Diffstat (limited to 'gpu')
31 files changed, 910 insertions, 130 deletions
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 6270d00..75aed69 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn @@ -186,6 +186,7 @@ test("gpu_unittests") { "command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc", "command_buffer/service/gles2_cmd_decoder_unittest_base.cc", "command_buffer/service/gles2_cmd_decoder_unittest_base.h", + "command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc", "command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc", "command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc", "command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc", diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index 60404dc..0f3ebf3 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h @@ -256,6 +256,7 @@ #define glUnmapBufferCHROMIUM GLES2_GET_FUN(UnmapBufferCHROMIUM) #define glMapBufferSubDataCHROMIUM GLES2_GET_FUN(MapBufferSubDataCHROMIUM) #define glUnmapBufferSubDataCHROMIUM GLES2_GET_FUN(UnmapBufferSubDataCHROMIUM) +#define glMapBufferRange GLES2_GET_FUN(MapBufferRange) #define glMapTexSubImage2DCHROMIUM GLES2_GET_FUN(MapTexSubImage2DCHROMIUM) #define glUnmapTexSubImage2DCHROMIUM GLES2_GET_FUN(UnmapTexSubImage2DCHROMIUM) #define glResizeCHROMIUM GLES2_GET_FUN(ResizeCHROMIUM) diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index ab51fcd..4207305 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -607,6 +607,20 @@ _NAMED_TYPE_INFO = { 'GL_RENDERBUFFER', ], }, + 'MapBufferAccess': { + 'type': 'GLenum', + 'valid': [ + 'GL_MAP_READ_BIT', + 'GL_MAP_WRITE_BIT', + 'GL_MAP_INVALIDATE_RANGE_BIT', + 'GL_MAP_INVALIDATE_BUFFER_BIT', + 'GL_MAP_FLUSH_EXPLICIT_BIT', + 'GL_MAP_UNSYNCHRONIZED_BIT', + ], + 'invalid': [ + 'GL_SYNC_FLUSH_COMMANDS_BIT', + ], + }, 'Bufferiv': { 'type': 'GLenum', 'valid': [ @@ -2503,6 +2517,16 @@ _FUNCTION_INFO = { 'client_test': False, 'pepper_interface': 'ChromiumMapSub', }, + 'MapBufferRange': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': 'GLenumBufferTarget target, GLintptrNotNegative offset, ' + 'GLsizeiptr size, GLbitfieldMapBufferAccess access, ' + 'uint32_t data_shm_id, uint32_t data_shm_offset, ' + 'uint32_t result_shm_id, uint32_t result_shm_offset', + 'unsafe': True, + 'result': ['uint32_t'], + }, 'PauseTransformFeedback': { 'unsafe': True, }, diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 7e0da4b..84a5708 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -1065,6 +1065,12 @@ void* GLES2MapBufferSubDataCHROMIUM(GLuint target, void GLES2UnmapBufferSubDataCHROMIUM(const void* mem) { gles2::GetGLContext()->UnmapBufferSubDataCHROMIUM(mem); } +void* GLES2MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) { + return gles2::GetGLContext()->MapBufferRange(target, offset, size, access); +} void* GLES2MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, @@ -2293,6 +2299,10 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glUnmapBufferSubDataCHROMIUM), }, { + "glMapBufferRange", + reinterpret_cast<GLES2FunctionPointer>(glMapBufferRange), + }, + { "glMapTexSubImage2DCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glMapTexSubImage2DCHROMIUM), }, diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index ad3eb58..e9abfc7 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -2226,6 +2226,21 @@ void EnableFeatureCHROMIUM(GLuint bucket_id, } } +void MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access, + uint32_t data_shm_id, + uint32_t data_shm_offset, + uint32_t result_shm_id, + uint32_t result_shm_offset) { + gles2::cmds::MapBufferRange* c = GetCmdSpace<gles2::cmds::MapBufferRange>(); + if (c) { + c->Init(target, offset, size, access, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + } +} + void ResizeCHROMIUM(GLuint width, GLuint height, GLfloat scale_factor) { gles2::cmds::ResizeCHROMIUM* c = GetCmdSpace<gles2::cmds::ResizeCHROMIUM>(); if (c) { diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 5938524..74e79ef 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -222,6 +222,10 @@ GLES2Implementation::~GLES2Implementation() { DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); } + // Release remaining BufferRange mem; This is when a MapBufferRange() is + // called but not the UnmapBuffer() pair. + ClearMappedBufferRangeMap(); + // Release any per-context data in share group. share_group_->FreeContext(this); @@ -605,6 +609,11 @@ GLboolean GLES2Implementation::IsEnabled(GLenum cap) { } bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { + // TODO(zmo): For all the BINDING points, there is a possibility where + // resources are shared among multiple contexts, that the cached points + // are invalid. It is not a problem for now, but once we allow resource + // sharing in WebGL, we need to implement a mechanism to allow correct + // client side binding points tracking. crbug.com/465562. switch (pname) { case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = capabilities_.max_combined_texture_image_units; @@ -643,18 +652,12 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { *params = capabilities_.num_shader_binary_formats; return true; case GL_ARRAY_BUFFER_BINDING: - if (share_group_->bind_generates_resource()) { - *params = bound_array_buffer_id_; - return true; - } - return false; + *params = bound_array_buffer_id_; + return true; case GL_ELEMENT_ARRAY_BUFFER_BINDING: - if (share_group_->bind_generates_resource()) { - *params = - vertex_array_object_manager_->bound_element_array_buffer(); - return true; - } - return false; + *params = + vertex_array_object_manager_->bound_element_array_buffer(); + return true; case GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM: *params = bound_pixel_pack_transfer_buffer_id_; return true; @@ -665,43 +668,27 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { *params = active_texture_unit_ + GL_TEXTURE0; return true; case GL_TEXTURE_BINDING_2D: - if (share_group_->bind_generates_resource()) { - *params = texture_units_[active_texture_unit_].bound_texture_2d; - return true; - } - return false; + *params = texture_units_[active_texture_unit_].bound_texture_2d; + return true; case GL_TEXTURE_BINDING_CUBE_MAP: - if (share_group_->bind_generates_resource()) { - *params = texture_units_[active_texture_unit_].bound_texture_cube_map; - return true; - } - return false; + *params = texture_units_[active_texture_unit_].bound_texture_cube_map; + return true; case GL_TEXTURE_BINDING_EXTERNAL_OES: - if (share_group_->bind_generates_resource()) { - *params = - texture_units_[active_texture_unit_].bound_texture_external_oes; - return true; - } - return false; + *params = + texture_units_[active_texture_unit_].bound_texture_external_oes; + return true; case GL_FRAMEBUFFER_BINDING: - if (share_group_->bind_generates_resource()) { - *params = bound_framebuffer_; - return true; - } - return false; + *params = bound_framebuffer_; + return true; case GL_READ_FRAMEBUFFER_BINDING: - if (IsChromiumFramebufferMultisampleAvailable() && - share_group_->bind_generates_resource()) { + if (IsChromiumFramebufferMultisampleAvailable()) { *params = bound_read_framebuffer_; return true; } return false; case GL_RENDERBUFFER_BINDING: - if (share_group_->bind_generates_resource()) { - *params = bound_renderbuffer_; - return true; - } - return false; + *params = bound_renderbuffer_; + return true; case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = capabilities_.max_uniform_buffer_bindings; return true; @@ -711,6 +698,7 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = capabilities_.uniform_buffer_offset_alignment; return true; + // TODO(zmo): Support ES3 pnames. default: return false; } @@ -1384,12 +1372,10 @@ void GLES2Implementation::BufferDataHelper( return; } - if (size == 0) { - return; - } + RemoveMappedBufferRangeByTarget(target); // If there is no data just send BufferData - if (!data) { + if (size == 0 || !data) { helper_->BufferData(target, size, 0, 0, usage); return; } @@ -3291,6 +3277,8 @@ void GLES2Implementation::DeleteBuffersHelper( if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { bound_pixel_unpack_transfer_buffer_id_ = 0; } + + RemoveMappedBufferRangeById(buffers[ii]); } } @@ -3672,6 +3660,94 @@ void GLES2Implementation::UnmapBufferSubDataCHROMIUM(const void* mem) { CheckGLError(); } +GLuint GLES2Implementation::GetBoundBufferHelper(GLenum target) { + GLenum binding = GLES2Util::MapBufferTargetToBindingEnum(target); + GLint id = 0; + bool cached = GetHelper(binding, &id); + DCHECK(cached); + return static_cast<GLuint>(id); +} + +void GLES2Implementation::RemoveMappedBufferRangeByTarget(GLenum target) { + GLuint buffer = GetBoundBufferHelper(target); + RemoveMappedBufferRangeById(buffer); +} + +void GLES2Implementation::RemoveMappedBufferRangeById(GLuint buffer) { + if (buffer > 0) { + auto iter = mapped_buffer_range_map_.find(buffer); + if (iter != mapped_buffer_range_map_.end() && iter->second.shm_memory) { + mapped_memory_->FreePendingToken( + iter->second.shm_memory, helper_->InsertToken()); + mapped_buffer_range_map_.erase(iter); + } + } +} + +void GLES2Implementation::ClearMappedBufferRangeMap() { + for (auto& buffer_range : mapped_buffer_range_map_) { + if (buffer_range.second.shm_memory) { + mapped_memory_->FreePendingToken( + buffer_range.second.shm_memory, helper_->InsertToken()); + } + } + mapped_buffer_range_map_.clear(); +} + +void* GLES2Implementation::MapBufferRange( + GLenum target, GLintptr offset, GLsizeiptr size, GLbitfield access) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferRange(" + << GLES2Util::GetStringEnum(target) << ", " << offset << ", " + << size << ", " << access << ")"); + if (!ValidateSize("glMapBufferRange", size) || + !ValidateOffset("glMapBufferRange", offset)) { + return nullptr; + } + + int32 shm_id; + unsigned int shm_offset; + void* mem = mapped_memory_->Alloc(size, &shm_id, &shm_offset); + if (!mem) { + SetGLError(GL_OUT_OF_MEMORY, "glMapBufferRange", "out of memory"); + return nullptr; + } + + typedef cmds::MapBufferRange::Result Result; + Result* result = GetResultAs<Result*>(); + *result = 0; + helper_->MapBufferRange(target, offset, size, access, shm_id, shm_offset, + GetResultShmId(), GetResultShmOffset()); + // TODO(zmo): For write only mode with MAP_INVALID_*_BIT, we should + // consider an early return without WaitForCmd(). crbug.com/465804. + WaitForCmd(); + if (*result) { + const GLbitfield kInvalidateBits = + GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT; + if ((access & kInvalidateBits) != 0) { + // We do not read back from the buffer, therefore, we set the client + // side memory to zero to avoid uninitialized data. + memset(mem, 0, size); + } + GLuint buffer = GetBoundBufferHelper(target); + DCHECK_NE(0u, buffer); + // glMapBufferRange fails on an already mapped buffer. + DCHECK(mapped_buffer_range_map_.find(buffer) == + mapped_buffer_range_map_.end()); + auto iter = mapped_buffer_range_map_.insert(std::make_pair( + buffer, + MappedBuffer(access, shm_id, mem, shm_offset, target, offset, size))); + DCHECK(iter.second); + } else { + mapped_memory_->Free(mem); + mem = nullptr; + } + + GPU_CLIENT_LOG(" returned " << mem); + CheckGLError(); + return mem; +} + void* GLES2Implementation::MapTexSubImage2DCHROMIUM( GLenum target, GLint level, diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index 1ffdf91..a9baf0b 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -560,6 +560,7 @@ class GLES2_IMPL_EXPORT GLES2Implementation // Helpers for query functions. bool GetHelper(GLenum pname, GLint* params); + GLuint GetBoundBufferHelper(GLenum target); bool GetBooleanvHelper(GLenum pname, GLboolean* params); bool GetBufferParameterivHelper(GLenum target, GLenum pname, GLint* params); bool GetFloatvHelper(GLenum pname, GLfloat* params); @@ -659,6 +660,10 @@ class GLES2_IMPL_EXPORT GLES2Implementation void FailGLError(GLenum /* error */) { } #endif + void RemoveMappedBufferRangeByTarget(GLenum target); + void RemoveMappedBufferRangeById(GLuint buffer); + void ClearMappedBufferRangeMap(); + GLES2Util util_; GLES2CmdHelper* helper_; TransferBufferInterface* transfer_buffer_; @@ -767,6 +772,10 @@ class GLES2_IMPL_EXPORT GLES2Implementation typedef std::map<const void*, MappedBuffer> MappedBufferMap; MappedBufferMap mapped_buffers_; + // TODO(zmo): Consolidate |mapped_buffers_| and |mapped_buffer_range_map_|. + typedef base::hash_map<GLuint, MappedBuffer> MappedBufferRangeMap; + MappedBufferRangeMap mapped_buffer_range_map_; + typedef std::map<const void*, MappedTexture> MappedTextureMap; MappedTextureMap mapped_textures_; diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 8e032e4..5111a6a 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -800,6 +800,11 @@ void* MapBufferSubDataCHROMIUM(GLuint target, void UnmapBufferSubDataCHROMIUM(const void* mem) override; +void* MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) override; + void* MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 3af9413..16908ca 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -2858,37 +2858,6 @@ TEST_F(GLES2ImplementationTest, TexSubImage3D4Writes) { reinterpret_cast<uint8*>(pixels.get()) + offset_to_last, mem2_2.ptr)); } -// Binds can not be cached with bind_generates_resource = false because -// our id might not be valid. More specifically if you bind on contextA then -// delete on contextB the resource is still bound on contextA but GetInterger -// won't return an id. -TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) { - struct PNameValue { - GLenum pname; - GLint expected; - }; - const PNameValue pairs[] = {{GL_TEXTURE_BINDING_2D, 1, }, - {GL_TEXTURE_BINDING_CUBE_MAP, 2, }, - {GL_TEXTURE_BINDING_EXTERNAL_OES, 3, }, - {GL_FRAMEBUFFER_BINDING, 4, }, - {GL_RENDERBUFFER_BINDING, 5, }, - {GL_ARRAY_BUFFER_BINDING, 6, }, - {GL_ELEMENT_ARRAY_BUFFER_BINDING, 7, }, }; - size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]); - for (size_t ii = 0; ii < num_pairs; ++ii) { - const PNameValue& pv = pairs[ii]; - GLint v = -1; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result)); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, - SizedResultHelper<GLuint>(pv.expected))) - .RetiresOnSaturation(); - gl_->GetIntegerv(pv.pname, &v); - EXPECT_EQ(pv.expected, v); - } -} - // glGen* Ids must not be reused until glDelete* commands have been // flushed by glFlush. TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) { @@ -3631,6 +3600,89 @@ TEST_F(GLES2ImplementationTest, WaitSync) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, MapBufferRangeWrite) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(1))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT); + EXPECT_TRUE(mem != nullptr); +} + +TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithInvalidateBit) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(1))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + GLsizeiptr kSize = 64; + void* mem = gl_->MapBufferRange( + GL_ARRAY_BUFFER, 10, kSize, + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT); + EXPECT_TRUE(mem != nullptr); + std::vector<int8_t> zero(kSize); + memset(&zero[0], 0, kSize); + EXPECT_EQ(0, memcmp(mem, &zero[0], kSize)); +} + +TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithGLError) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + // Return a result of 0 to indicate an GL error. + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(0))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT); + EXPECT_TRUE(mem == nullptr); +} + +TEST_F(GLES2ImplementationTest, MapBufferRangeRead) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(1))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT); + EXPECT_TRUE(mem != nullptr); +} + +TEST_F(GLES2ImplementationTest, MapBufferRangeReadWithGLError) { + ExpectedMemoryInfo result = + GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result)); + + // Return a result of 0 to indicate an GL error. + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result.ptr, uint32_t(0))) + .RetiresOnSaturation(); + + const GLuint kBufferId = 123; + gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); + + void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT); + EXPECT_TRUE(mem == nullptr); +} + TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) { ContextInitOptions init_options; init_options.lose_context_when_out_of_memory = true; diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 2d8480a..4785ff0 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -2718,6 +2718,7 @@ TEST_F(GLES2ImplementationTest, IsVertexArrayOES) { EXPECT_TRUE(result); } // TODO(zmo): Implement unit test for EnableFeatureCHROMIUM +// TODO(zmo): Implement unit test for MapBufferRange TEST_F(GLES2ImplementationTest, ResizeCHROMIUM) { struct Cmds { diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index f93ec07..a181c43 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h @@ -583,6 +583,10 @@ virtual void* MapBufferSubDataCHROMIUM(GLuint target, GLsizeiptr size, GLenum access) = 0; virtual void UnmapBufferSubDataCHROMIUM(const void* mem) = 0; +virtual void* MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) = 0; virtual void* MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 0381b323..48697d5 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -568,6 +568,10 @@ void* MapBufferSubDataCHROMIUM(GLuint target, GLsizeiptr size, GLenum access) override; void UnmapBufferSubDataCHROMIUM(const void* mem) override; +void* MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) override; void* MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, 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 0f2e5fd..dfbb319 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -987,6 +987,12 @@ void* GLES2InterfaceStub::MapBufferSubDataCHROMIUM(GLuint /* target */, } void GLES2InterfaceStub::UnmapBufferSubDataCHROMIUM(const void* /* mem */) { } +void* GLES2InterfaceStub::MapBufferRange(GLenum /* target */, + GLintptr /* offset */, + GLsizeiptr /* size */, + GLbitfield /* access */) { + return 0; +} void* GLES2InterfaceStub::MapTexSubImage2DCHROMIUM(GLenum /* target */, GLint /* level */, GLint /* xoffset */, diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 8a9be79..32ccdab 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -568,6 +568,10 @@ void* MapBufferSubDataCHROMIUM(GLuint target, GLsizeiptr size, GLenum access) override; void UnmapBufferSubDataCHROMIUM(const void* mem) override; +void* MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) override; void* MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index d1479b1..327becc 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -1683,6 +1683,14 @@ void GLES2TraceImplementation::UnmapBufferSubDataCHROMIUM(const void* mem) { gl_->UnmapBufferSubDataCHROMIUM(mem); } +void* GLES2TraceImplementation::MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr size, + GLbitfield access) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::MapBufferRange"); + return gl_->MapBufferRange(target, offset, size, access); +} + void* GLES2TraceImplementation::MapTexSubImage2DCHROMIUM(GLenum target, GLint level, GLint xoffset, diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index 140db2c..153aca4 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt @@ -246,6 +246,7 @@ GL_APICALL void* GL_APIENTRY glMapBufferCHROMIUM (GLuint target, GLenum a 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 glMapBufferRange (GLenumBufferTarget target, GLintptrNotNegative offset, GLsizeiptr size, GLbitfieldMapBufferAccess access); GL_APICALL void* GL_APIENTRY glMapTexSubImage2DCHROMIUM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum access); GL_APICALL void GL_APIENTRY glUnmapTexSubImage2DCHROMIUM (const void* mem); GL_APICALL void GL_APIENTRY glResizeCHROMIUM (GLuint width, GLuint height, GLfloat scale_factor); diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index d3cb00a..251bfff 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -10939,6 +10939,86 @@ static_assert(offsetof(EnableFeatureCHROMIUM, result_shm_id) == 8, static_assert(offsetof(EnableFeatureCHROMIUM, result_shm_offset) == 12, "offset of EnableFeatureCHROMIUM result_shm_offset should be 12"); +struct MapBufferRange { + typedef MapBufferRange ValueType; + static const CommandId kCmdId = kMapBufferRange; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef uint32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, + GLintptr _offset, + GLsizeiptr _size, + GLbitfield _access, + uint32_t _data_shm_id, + uint32_t _data_shm_offset, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + SetHeader(); + target = _target; + offset = _offset; + size = _size; + access = _access; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, + GLenum _target, + GLintptr _offset, + GLsizeiptr _size, + GLbitfield _access, + uint32_t _data_shm_id, + uint32_t _data_shm_offset, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_target, _offset, _size, _access, + _data_shm_id, _data_shm_offset, + _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t offset; + int32_t size; + uint32_t access; + uint32_t data_shm_id; + uint32_t data_shm_offset; + uint32_t result_shm_id; + uint32_t result_shm_offset; +}; + +static_assert(sizeof(MapBufferRange) == 36, + "size of MapBufferRange should be 36"); +static_assert(offsetof(MapBufferRange, header) == 0, + "offset of MapBufferRange header should be 0"); +static_assert(offsetof(MapBufferRange, target) == 4, + "offset of MapBufferRange target should be 4"); +static_assert(offsetof(MapBufferRange, offset) == 8, + "offset of MapBufferRange offset should be 8"); +static_assert(offsetof(MapBufferRange, size) == 12, + "offset of MapBufferRange size should be 12"); +static_assert(offsetof(MapBufferRange, access) == 16, + "offset of MapBufferRange access should be 16"); +static_assert(offsetof(MapBufferRange, data_shm_id) == 20, + "offset of MapBufferRange data_shm_id should be 20"); +static_assert(offsetof(MapBufferRange, data_shm_offset) == 24, + "offset of MapBufferRange data_shm_offset should be 24"); +static_assert(offsetof(MapBufferRange, result_shm_id) == 28, + "offset of MapBufferRange result_shm_id should be 28"); +static_assert(offsetof(MapBufferRange, result_shm_offset) == 32, + "offset of MapBufferRange result_shm_offset should be 32"); + struct ResizeCHROMIUM { typedef ResizeCHROMIUM ValueType; static const CommandId kCmdId = kResizeCHROMIUM; diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 3162276..55485bf 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -3778,6 +3778,27 @@ TEST_F(GLES2FormatTest, EnableFeatureCHROMIUM) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, MapBufferRange) { + cmds::MapBufferRange& cmd = *GetBufferAs<cmds::MapBufferRange>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLintptr>(12), + static_cast<GLsizeiptr>(13), static_cast<GLbitfield>(14), + static_cast<uint32_t>(15), static_cast<uint32_t>(16), + static_cast<uint32_t>(17), static_cast<uint32_t>(18)); + EXPECT_EQ(static_cast<uint32_t>(cmds::MapBufferRange::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLintptr>(12), cmd.offset); + EXPECT_EQ(static_cast<GLsizeiptr>(13), cmd.size); + EXPECT_EQ(static_cast<GLbitfield>(14), cmd.access); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32_t>(16), cmd.data_shm_offset); + EXPECT_EQ(static_cast<uint32_t>(17), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32_t>(18), cmd.result_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, ResizeCHROMIUM) { cmds::ResizeCHROMIUM& cmd = *GetBufferAs<cmds::ResizeCHROMIUM>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 1c739e8..997268c2 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -243,53 +243,54 @@ OP(SwapBuffers) /* 484 */ \ OP(GetMaxValueInBufferCHROMIUM) /* 485 */ \ OP(EnableFeatureCHROMIUM) /* 486 */ \ - OP(ResizeCHROMIUM) /* 487 */ \ - OP(GetRequestableExtensionsCHROMIUM) /* 488 */ \ - OP(RequestExtensionCHROMIUM) /* 489 */ \ - OP(GetProgramInfoCHROMIUM) /* 490 */ \ - OP(GetUniformBlocksCHROMIUM) /* 491 */ \ - OP(GetTransformFeedbackVaryingsCHROMIUM) /* 492 */ \ - OP(GetUniformsES3CHROMIUM) /* 493 */ \ - OP(GetTranslatedShaderSourceANGLE) /* 494 */ \ - OP(PostSubBufferCHROMIUM) /* 495 */ \ - OP(TexImageIOSurface2DCHROMIUM) /* 496 */ \ - OP(CopyTextureCHROMIUM) /* 497 */ \ - OP(CopySubTextureCHROMIUM) /* 498 */ \ - OP(DrawArraysInstancedANGLE) /* 499 */ \ - OP(DrawElementsInstancedANGLE) /* 500 */ \ - OP(VertexAttribDivisorANGLE) /* 501 */ \ - OP(GenMailboxCHROMIUM) /* 502 */ \ - OP(ProduceTextureCHROMIUMImmediate) /* 503 */ \ - OP(ProduceTextureDirectCHROMIUMImmediate) /* 504 */ \ - OP(ConsumeTextureCHROMIUMImmediate) /* 505 */ \ - OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 506 */ \ - OP(BindUniformLocationCHROMIUMBucket) /* 507 */ \ - OP(GenValuebuffersCHROMIUMImmediate) /* 508 */ \ - OP(DeleteValuebuffersCHROMIUMImmediate) /* 509 */ \ - OP(IsValuebufferCHROMIUM) /* 510 */ \ - OP(BindValuebufferCHROMIUM) /* 511 */ \ - OP(SubscribeValueCHROMIUM) /* 512 */ \ - OP(PopulateSubscribedValuesCHROMIUM) /* 513 */ \ - OP(UniformValuebufferCHROMIUM) /* 514 */ \ - OP(BindTexImage2DCHROMIUM) /* 515 */ \ - OP(ReleaseTexImage2DCHROMIUM) /* 516 */ \ - OP(TraceBeginCHROMIUM) /* 517 */ \ - OP(TraceEndCHROMIUM) /* 518 */ \ - OP(AsyncTexSubImage2DCHROMIUM) /* 519 */ \ - OP(AsyncTexImage2DCHROMIUM) /* 520 */ \ - OP(WaitAsyncTexImage2DCHROMIUM) /* 521 */ \ - OP(WaitAllAsyncTexImage2DCHROMIUM) /* 522 */ \ - OP(DiscardFramebufferEXTImmediate) /* 523 */ \ - OP(LoseContextCHROMIUM) /* 524 */ \ - OP(InsertSyncPointCHROMIUM) /* 525 */ \ - OP(WaitSyncPointCHROMIUM) /* 526 */ \ - OP(DrawBuffersEXTImmediate) /* 527 */ \ - OP(DiscardBackbufferCHROMIUM) /* 528 */ \ - OP(ScheduleOverlayPlaneCHROMIUM) /* 529 */ \ - OP(SwapInterval) /* 530 */ \ - OP(MatrixLoadfCHROMIUMImmediate) /* 531 */ \ - OP(MatrixLoadIdentityCHROMIUM) /* 532 */ \ - OP(BlendBarrierKHR) /* 533 */ + OP(MapBufferRange) /* 487 */ \ + OP(ResizeCHROMIUM) /* 488 */ \ + OP(GetRequestableExtensionsCHROMIUM) /* 489 */ \ + OP(RequestExtensionCHROMIUM) /* 490 */ \ + OP(GetProgramInfoCHROMIUM) /* 491 */ \ + OP(GetUniformBlocksCHROMIUM) /* 492 */ \ + OP(GetTransformFeedbackVaryingsCHROMIUM) /* 493 */ \ + OP(GetUniformsES3CHROMIUM) /* 494 */ \ + OP(GetTranslatedShaderSourceANGLE) /* 495 */ \ + OP(PostSubBufferCHROMIUM) /* 496 */ \ + OP(TexImageIOSurface2DCHROMIUM) /* 497 */ \ + OP(CopyTextureCHROMIUM) /* 498 */ \ + OP(CopySubTextureCHROMIUM) /* 499 */ \ + OP(DrawArraysInstancedANGLE) /* 500 */ \ + OP(DrawElementsInstancedANGLE) /* 501 */ \ + OP(VertexAttribDivisorANGLE) /* 502 */ \ + OP(GenMailboxCHROMIUM) /* 503 */ \ + OP(ProduceTextureCHROMIUMImmediate) /* 504 */ \ + OP(ProduceTextureDirectCHROMIUMImmediate) /* 505 */ \ + OP(ConsumeTextureCHROMIUMImmediate) /* 506 */ \ + OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 507 */ \ + OP(BindUniformLocationCHROMIUMBucket) /* 508 */ \ + OP(GenValuebuffersCHROMIUMImmediate) /* 509 */ \ + OP(DeleteValuebuffersCHROMIUMImmediate) /* 510 */ \ + OP(IsValuebufferCHROMIUM) /* 511 */ \ + OP(BindValuebufferCHROMIUM) /* 512 */ \ + OP(SubscribeValueCHROMIUM) /* 513 */ \ + OP(PopulateSubscribedValuesCHROMIUM) /* 514 */ \ + OP(UniformValuebufferCHROMIUM) /* 515 */ \ + OP(BindTexImage2DCHROMIUM) /* 516 */ \ + OP(ReleaseTexImage2DCHROMIUM) /* 517 */ \ + OP(TraceBeginCHROMIUM) /* 518 */ \ + OP(TraceEndCHROMIUM) /* 519 */ \ + OP(AsyncTexSubImage2DCHROMIUM) /* 520 */ \ + OP(AsyncTexImage2DCHROMIUM) /* 521 */ \ + OP(WaitAsyncTexImage2DCHROMIUM) /* 522 */ \ + OP(WaitAllAsyncTexImage2DCHROMIUM) /* 523 */ \ + OP(DiscardFramebufferEXTImmediate) /* 524 */ \ + OP(LoseContextCHROMIUM) /* 525 */ \ + OP(InsertSyncPointCHROMIUM) /* 526 */ \ + OP(WaitSyncPointCHROMIUM) /* 527 */ \ + OP(DrawBuffersEXTImmediate) /* 528 */ \ + OP(DiscardBackbufferCHROMIUM) /* 529 */ \ + OP(ScheduleOverlayPlaneCHROMIUM) /* 530 */ \ + OP(SwapInterval) /* 531 */ \ + OP(MatrixLoadfCHROMIUMImmediate) /* 532 */ \ + OP(MatrixLoadIdentityCHROMIUM) /* 533 */ \ + OP(BlendBarrierKHR) /* 534 */ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/gpu/command_buffer/common/gles2_cmd_utils.cc b/gpu/command_buffer/common/gles2_cmd_utils.cc index 0950b41..14d6a21 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.cc +++ b/gpu/command_buffer/common/gles2_cmd_utils.cc @@ -870,6 +870,31 @@ uint64_t GLES2Util::MapTwoUint32ToUint64(uint32_t v32_0, uint32_t v32_1) { return (v64 << 32) | v32_0; } +// static +uint32_t GLES2Util::MapBufferTargetToBindingEnum(uint32_t target) { + switch (target) { + case GL_ARRAY_BUFFER: + return GL_ARRAY_BUFFER_BINDING; + case GL_COPY_READ_BUFFER: + return GL_COPY_READ_BUFFER_BINDING; + case GL_COPY_WRITE_BUFFER: + return GL_COPY_WRITE_BUFFER_BINDING; + case GL_ELEMENT_ARRAY_BUFFER: + return GL_ELEMENT_ARRAY_BUFFER_BINDING; + case GL_PIXEL_PACK_BUFFER: + return GL_PIXEL_PACK_BUFFER_BINDING; + case GL_PIXEL_UNPACK_BUFFER: + return GL_PIXEL_UNPACK_BUFFER_BINDING; + case GL_TRANSFORM_FEEDBACK_BUFFER: + return GL_TRANSFORM_FEEDBACK_BUFFER_BINDING; + case GL_UNIFORM_BUFFER: + return GL_UNIFORM_BUFFER_BINDING; + default: + return 0; + } +} + + namespace { // WebGraphicsContext3DCommandBufferImpl configuration attributes. Those in diff --git a/gpu/command_buffer/common/gles2_cmd_utils.h b/gpu/command_buffer/common/gles2_cmd_utils.h index 9dd8f28..1661247 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.h +++ b/gpu/command_buffer/common/gles2_cmd_utils.h @@ -191,6 +191,8 @@ class GLES2_UTILS_EXPORT GLES2Util { uint64_t v64, uint32_t* v32_0, uint32_t* v32_1); static uint64_t MapTwoUint32ToUint64(uint32_t v32_0, uint32_t v32_1); + static uint32_t MapBufferTargetToBindingEnum(uint32_t target); + #include "../common/gles2_cmd_utils_autogen.h" private: diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h index 76419ce..cd5002d 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h @@ -41,6 +41,7 @@ static std::string GetStringImageInternalFormat(uint32_t value); static std::string GetStringImageUsage(uint32_t value); static std::string GetStringIndexType(uint32_t value); static std::string GetStringIndexedBufferTarget(uint32_t value); +static std::string GetStringMapBufferAccess(uint32_t value); static std::string GetStringMatrixMode(uint32_t value); static std::string GetStringPixelStore(uint32_t value); static std::string GetStringPixelType(uint32_t value); 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 403925e..52511ed 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -4845,6 +4845,19 @@ std::string GLES2Util::GetStringIndexedBufferTarget(uint32_t value) { arraysize(string_table), value); } +std::string GLES2Util::GetStringMapBufferAccess(uint32_t value) { + static const EnumToString string_table[] = { + {GL_MAP_READ_BIT, "GL_MAP_READ_BIT"}, + {GL_MAP_WRITE_BIT, "GL_MAP_WRITE_BIT"}, + {GL_MAP_INVALIDATE_RANGE_BIT, "GL_MAP_INVALIDATE_RANGE_BIT"}, + {GL_MAP_INVALIDATE_BUFFER_BIT, "GL_MAP_INVALIDATE_BUFFER_BIT"}, + {GL_MAP_FLUSH_EXPLICIT_BIT, "GL_MAP_FLUSH_EXPLICIT_BIT"}, + {GL_MAP_UNSYNCHRONIZED_BIT, "GL_MAP_UNSYNCHRONIZED_BIT"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + std::string GLES2Util::GetStringMatrixMode(uint32_t value) { static const EnumToString string_table[] = { {GL_PATH_PROJECTION_CHROMIUM, "GL_PATH_PROJECTION_CHROMIUM"}, diff --git a/gpu/command_buffer/service/buffer_manager.cc b/gpu/command_buffer/service/buffer_manager.cc index 1f64fd5..d151a65 100644 --- a/gpu/command_buffer/service/buffer_manager.cc +++ b/gpu/command_buffer/service/buffer_manager.cc @@ -82,7 +82,8 @@ Buffer::Buffer(BufferManager* manager, GLuint service_id) is_client_side_array_(false), service_id_(service_id), target_(0), - usage_(GL_STATIC_DRAW) { + usage_(GL_STATIC_DRAW), + buffer_range_pointer_(nullptr) { manager_->StartTracking(this); } @@ -119,6 +120,7 @@ void Buffer::SetInfo( memset(shadow_.get(), 0, size); } } + buffer_range_pointer_ = nullptr; } bool Buffer::CheckRange( @@ -397,12 +399,23 @@ bool BufferManager::SetTarget(Buffer* buffer, GLenum target) { // Since one BufferManager can be shared by multiple decoders, ContextState is // passed in each time and not just passed in during initialization. Buffer* BufferManager::GetBufferInfoForTarget( - ContextState* state, GLenum target) { - DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); - if (target == GL_ARRAY_BUFFER) { - return state->bound_array_buffer.get(); - } else { - return state->vertex_attrib_manager->element_array_buffer(); + ContextState* state, GLenum target) const { + switch (target) { + case GL_ARRAY_BUFFER: + return state->bound_array_buffer.get(); + case GL_ELEMENT_ARRAY_BUFFER: + return state->vertex_attrib_manager->element_array_buffer(); + case GL_COPY_READ_BUFFER: + case GL_COPY_WRITE_BUFFER: + case GL_PIXEL_PACK_BUFFER: + case GL_PIXEL_UNPACK_BUFFER: + case GL_TRANSFORM_FEEDBACK_BUFFER: + case GL_UNIFORM_BUFFER: + NOTIMPLEMENTED(); + return nullptr; + default: + NOTREACHED(); + return nullptr; } } diff --git a/gpu/command_buffer/service/buffer_manager.h b/gpu/command_buffer/service/buffer_manager.h index 22a6e42..fb6261d 100644 --- a/gpu/command_buffer/service/buffer_manager.h +++ b/gpu/command_buffer/service/buffer_manager.h @@ -67,6 +67,14 @@ class GPU_EXPORT Buffer : public base::RefCounted<Buffer> { return is_client_side_array_; } + void set_buffer_range_pointer(void* mem) { + buffer_range_pointer_ = mem; + } + + void* buffer_range_pointer() const { + return buffer_range_pointer_; + } + private: friend class BufferManager; friend class BufferManagerTestBase; @@ -163,6 +171,9 @@ class GPU_EXPORT Buffer : public base::RefCounted<Buffer> { // Usage of buffer. GLenum usage_; + // Returned value from last glMapBufferRange call. + void* buffer_range_pointer_; + // A map of ranges to the highest value in that range of a certain type. typedef std::map<Range, GLuint, Range::Less> RangeToMaxValueMap; RangeToMaxValueMap range_set_; @@ -232,15 +243,16 @@ class GPU_EXPORT BufferManager { // set to a non-zero size. bool UseNonZeroSizeForClientSideArrayBuffer(); + Buffer* GetBufferInfoForTarget(ContextState* state, GLenum target) const; + private: friend class Buffer; friend class TestHelper; // Needs access to DoBufferData. friend class BufferManagerTestBase; // Needs access to DoBufferSubData. + void StartTracking(Buffer* buffer); void StopTracking(Buffer* buffer); - Buffer* GetBufferInfoForTarget(ContextState* state, GLenum target); - // Does a glBufferSubData and updates the approriate accounting. // Assumes the values have already been validated. void DoBufferSubData( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 28c1e0f..3cf4dda 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -3113,6 +3113,7 @@ void GLES2DecoderImpl::DeleteBuffersHelper( for (GLsizei ii = 0; ii < n; ++ii) { Buffer* buffer = GetBuffer(client_ids[ii]); if (buffer && !buffer->IsDeleted()) { + buffer->set_buffer_range_pointer(nullptr); state_.vertex_attrib_manager->Unbind(buffer); if (state_.bound_array_buffer.get() == buffer) { state_.bound_array_buffer = NULL; @@ -12288,6 +12289,70 @@ error::Error GLES2DecoderImpl::HandleWaitSync( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleMapBufferRange( + uint32_t immediate_data_size, const void* cmd_data) { + if (!unsafe_es3_apis_enabled()) { + return error::kUnknownCommand; + } + const gles2::cmds::MapBufferRange& c = + *static_cast<const gles2::cmds::MapBufferRange*>(cmd_data); + GLenum target = static_cast<GLenum>(c.target); + GLbitfield access = static_cast<GLbitfield>(c.access); + GLintptr offset = static_cast<GLintptr>(c.offset); + GLsizeiptr size = static_cast<GLsizeiptr>(c.size); + + typedef cmds::MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result)); + if (!result) { + return error::kOutOfBounds; + } + if (*result != 0) { + *result = 0; + return error::kInvalidArguments; + } + int8_t* mem = + GetSharedMemoryAs<int8_t*>(c.data_shm_id, c.data_shm_offset, size); + if (!mem) { + return error::kOutOfBounds; + } + + GLbitfield mask = GL_MAP_INVALIDATE_BUFFER_BIT; + if ((access & mask) == mask) { + // TODO(zmo): To be on the safe side, always map + // GL_MAP_INVALIDATE_BUFFER_BIT to GL_MAP_INVALIDATE_RANGE_BIT. + access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT); + access = (access | GL_MAP_INVALIDATE_RANGE_BIT); + } + // TODO(zmo): Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of + // undefined behaviors. + mask = GL_MAP_READ_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + if ((access & mask) == mask) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "MapBufferRange", + "incompatible access bits"); + return error::kNoError; + } + access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT); + if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT && + (access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { + access = (access | GL_MAP_READ_BIT); + } + void* ptr = glMapBufferRange(target, offset, size, access); + if (ptr == nullptr) { + return error::kNoError; + } + Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); + DCHECK(buffer); + if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT) { + buffer->set_buffer_range_pointer(ptr); + } + if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { + memcpy(mem, ptr, size); + } + *result = 1; + return error::kNoError; +} + void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( TextureRef* texture_ref) { Texture* texture = texture_ref->texture(); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h index 29a55ba..fe5975e 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h @@ -218,6 +218,8 @@ TEST_P(GLES2DecoderTest3, PopGroupMarkerEXTValidArgs) { // TODO(gman): GetMaxValueInBufferCHROMIUM // TODO(gman): EnableFeatureCHROMIUM +// TODO(gman): MapBufferRange + // TODO(gman): ResizeCHROMIUM // TODO(gman): GetRequestableExtensionsCHROMIUM diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc new file mode 100644 index 0000000..1c934dd --- /dev/null +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc @@ -0,0 +1,311 @@ +// Copyright 2015 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 "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" + +using ::gfx::MockGLInterface; +using ::testing::_; +using ::testing::Return; +using ::testing::SetArgPointee; + +namespace gpu { +namespace gles2 { + +using namespace cmds; + +namespace { + +} // namespace anonymous + +TEST_P(GLES2DecoderTest, MapBufferRangeReadSucceeds) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_READ_BIT; + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + EXPECT_EQ(0, memcmp(&data[0], mem, kSize)); + EXPECT_EQ(1u, *result); + decoder_->set_unsafe_es3_apis_enabled(false); + *result = 0; + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); + EXPECT_EQ(0u, *result); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeWriteSucceeds) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_WRITE_BIT; + const GLbitfield kMappedAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kMappedAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + EXPECT_EQ(0, memcmp(&data[0], mem, kSize)); + EXPECT_EQ(1u, *result); + decoder_->set_unsafe_es3_apis_enabled(false); + *result = 0; + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); + EXPECT_EQ(0u, *result); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeNotInitFails) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_READ_BIT; + std::vector<int8_t> data(kSize); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 1; // Any value other than 0. + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeWriteInvalidateRangeSucceeds) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + // With MAP_INVALIDATE_RANGE_BIT, no need to append MAP_READ_BIT. + const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT; + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + memset(mem, 72, kSize); // Init to a random value other than 0. + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeWriteInvalidateBufferSucceeds) { + // Test INVALIDATE_BUFFER_BIT is mapped to INVALIDATE_RANGE_BIT. + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; + // With MAP_INVALIDATE_BUFFER_BIT, no need to append MAP_READ_BIT. + const GLbitfield kFilteredAccess = + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT; + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kFilteredAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + memset(mem, 72, kSize); // Init to a random value other than 0. + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeWriteUnsynchronizedBit) { + // Test UNSYNCHRONIZED_BIT is filtered out. + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + const GLbitfield kFilteredAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; + + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId); + + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kFilteredAccess)) + .WillOnce(Return(&data[0])) + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + memset(mem, 72, kSize); // Init to a random value other than 0. + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, memcmp(&data[0], mem, kSize)); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeWithError) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_READ_BIT; + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + EXPECT_CALL(*gl_, + MapBufferRange(kTarget, kOffset, kSize, kAccess)) + .WillOnce(Return(nullptr)) // Return nullptr to indicate a GL error. + .RetiresOnSaturation(); + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); + memset(mem, 72, kSize); // Init to a random value other than 0. + + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset, + result_shm_id, result_shm_offset); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + memset(&data[0], 72, kSize); + // Mem is untouched. + EXPECT_EQ(0, memcmp(&data[0], mem, kSize)); + EXPECT_EQ(0u, *result); +} + +TEST_P(GLES2DecoderTest, MapBufferRangeBadSharedMemoryFails) { + const GLenum kTarget = GL_ARRAY_BUFFER; + const GLintptr kOffset = 10; + const GLsizeiptr kSize = 64; + const GLbitfield kAccess = GL_MAP_READ_BIT; + std::vector<int8_t> data(kSize); + for (GLsizeiptr ii = 0; ii < kSize; ++ii) { + data[ii] = static_cast<int8_t>(ii % 255); + } + + typedef MapBufferRange::Result Result; + Result* result = GetSharedMemoryAs<Result*>(); + *result = 0; + uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_offset = kSharedMemoryOffset; + uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); + + decoder_->set_unsafe_es3_apis_enabled(true); + MapBufferRange cmd; + cmd.Init(kTarget, kOffset, kSize, kAccess, + kInvalidSharedMemoryId, data_shm_offset, + result_shm_id, result_shm_offset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kTarget, kOffset, kSize, kAccess, + data_shm_id, data_shm_offset, + kInvalidSharedMemoryId, result_shm_offset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kTarget, kOffset, kSize, kAccess, + data_shm_id, kInvalidSharedMemoryOffset, + result_shm_id, result_shm_offset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kTarget, kOffset, kSize, kAccess, + data_shm_id, data_shm_offset, + result_shm_id, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +} // namespace gles2 +} // namespace gpu diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index 953c0f9..2a8684a 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h @@ -41,6 +41,7 @@ ValueValidator<GLenum> image_internal_format; ValueValidator<GLenum> image_usage; ValueValidator<GLenum> index_type; ValueValidator<GLenum> indexed_buffer_target; +ValueValidator<GLenum> map_buffer_access; ValueValidator<GLenum> matrix_mode; ValueValidator<GLenum> pixel_store; ValueValidator<GLint> pixel_store_alignment; diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 11d8492..2f83240 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -289,6 +289,15 @@ static const GLenum valid_indexed_buffer_target_table[] = { GL_UNIFORM_BUFFER, }; +static const GLenum valid_map_buffer_access_table[] = { + GL_MAP_READ_BIT, + GL_MAP_WRITE_BIT, + GL_MAP_INVALIDATE_RANGE_BIT, + GL_MAP_INVALIDATE_BUFFER_BIT, + GL_MAP_FLUSH_EXPLICIT_BIT, + GL_MAP_UNSYNCHRONIZED_BIT, +}; + static const GLenum valid_matrix_mode_table[] = { GL_PATH_PROJECTION_CHROMIUM, GL_PATH_MODELVIEW_CHROMIUM, @@ -670,6 +679,8 @@ Validators::Validators() index_type(valid_index_type_table, arraysize(valid_index_type_table)), indexed_buffer_target(valid_indexed_buffer_target_table, arraysize(valid_indexed_buffer_target_table)), + map_buffer_access(valid_map_buffer_access_table, + arraysize(valid_map_buffer_access_table)), matrix_mode(valid_matrix_mode_table, arraysize(valid_matrix_mode_table)), pixel_store(valid_pixel_store_table, arraysize(valid_pixel_store_table)), pixel_store_alignment(valid_pixel_store_alignment_table, diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 6021f56..29fb8b4 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -220,6 +220,7 @@ 'command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc', 'command_buffer/service/gles2_cmd_decoder_unittest_base.cc', 'command_buffer/service/gles2_cmd_decoder_unittest_base.h', + 'command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc', 'command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc', 'command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc', 'command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc', |