diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-17 13:57:45 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-19 13:44:40 +0000 |
commit | 6ec7b8da05d21a3878bd21c691b41e675d74bb1c (patch) | |
tree | b87f250bc19413750b9bb9cdbf2da20ef5014820 /chromium/gpu/command_buffer | |
parent | ec02ee4181c49b61fce1c8fb99292dbb8139cc90 (diff) | |
download | qtwebengine-chromium-6ec7b8da05d21a3878bd21c691b41e675d74bb1c.tar.gz |
BASELINE: Update Chromium to 60.0.3112.70
Change-Id: I9911c2280a014d4632f254857876a395d4baed2d
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/gpu/command_buffer')
141 files changed, 7470 insertions, 4344 deletions
diff --git a/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py b/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py index 479b2d6be18..fc0f7fd4bfb 100755 --- a/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/chromium/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -2917,6 +2917,7 @@ _FUNCTION_INFO = { 'gl_test_func': 'glGenFramebuffersEXT', 'resource_type': 'Framebuffer', 'resource_types': 'Framebuffers', + 'not_shared': 'True', }, 'GenRenderbuffers': { 'type': 'GENn', 'gl_test_func': 'glGenRenderbuffersEXT', @@ -2942,6 +2943,7 @@ _FUNCTION_INFO = { 'resource_type': 'TransformFeedback', 'resource_types': 'TransformFeedbacks', 'es3': True, + 'not_shared': 'True', }, 'GetActiveAttrib': { 'type': 'Custom', @@ -4245,6 +4247,7 @@ _FUNCTION_INFO = { 'resource_types': 'VertexArrays', 'unit_test': False, 'pepper_interface': 'VertexArrayObject', + 'not_shared': 'True', }, 'BindVertexArrayOES': { 'type': 'Bind', @@ -4278,6 +4281,11 @@ _FUNCTION_INFO = { 'unit_test': False, 'extension': "CHROMIUM_image", }, + 'BindTexImage2DWithInternalformatCHROMIUM': { + 'decoder_func': 'DoBindTexImage2DWithInternalformatCHROMIUM', + 'unit_test': False, + 'extension': "CHROMIUM_image", + }, 'ReleaseTexImage2DCHROMIUM': { 'decoder_func': 'DoReleaseTexImage2DCHROMIUM', 'unit_test': False, @@ -4399,7 +4407,7 @@ _FUNCTION_INFO = { 'type': 'Custom', 'impl_func': False, 'client_test': False, - 'cmd_args': 'GLuint contents_texture_id, GLuint background_color, ' + 'cmd_args': 'GLsizei num_textures, GLuint background_color, ' 'GLuint edge_aa_mask, GLuint filter, GLuint shm_id, ' 'GLuint shm_offset', 'extension': 'CHROMIUM_schedule_ca_layer', @@ -4552,6 +4560,28 @@ _FUNCTION_INFO = { 'decoder_func': 'DoSetEnableDCLayersCHROMIUM', 'extension': 'CHROMIUM_dc_layers', }, + 'InitializeDiscardableTextureCHROMIUM': { + 'type': 'Custom', + 'cmd_args': 'GLuint texture_id, uint32_t shm_id, ' + 'uint32_t shm_offset', + 'impl_func': False, + 'client_test': False, + 'extension': True, + }, + 'UnlockDiscardableTextureCHROMIUM': { + 'type': 'Custom', + 'cmd_args': 'GLuint texture_id', + 'impl_func': False, + 'client_test': False, + 'extension': True, + }, + 'LockDiscardableTextureCHROMIUM': { + 'type': 'Custom', + 'cmd_args': 'GLuint texture_id', + 'impl_func': False, + 'client_test': False, + 'extension': True, + }, } @@ -4633,6 +4663,27 @@ def ToCamelCase(input_string): """converts ABC_underscore_case to ABCUnderscoreCase.""" return ''.join(w[0].upper() + w[1:] for w in input_string.split('_')) +def EnumsConflict(a, b): + """Returns true if the enums have different names (ignoring suffixes) and one + of them is a Chromium enum.""" + if a == b: + return False + + if b.endswith('_CHROMIUM'): + a, b = b, a + + if not a.endswith('_CHROMIUM'): + return False + + def removesuffix(string, suffix): + if not string.endswith(suffix): + return string + return string[:-len(suffix)] + b = removesuffix(b, "_NV") + b = removesuffix(b, "_EXT") + b = removesuffix(b, "_OES") + return removesuffix(a, "_CHROMIUM") != b + def GetGLGetTypeConversion(result_type, value_type, value): """Makes a gl compatible type conversion string for accessing state variables. @@ -5819,7 +5870,7 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { TEST_P(%(test_name)s, %(name)sValidArgsNewId) { EXPECT_CALL(*gl_, %(gl_func_name)s(kNewServiceId)); EXPECT_CALL(*gl_, %(gl_gen_func_name)s(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; cmd.Init(kNewClientId); @@ -5849,7 +5900,7 @@ TEST_P(%(test_name)s, %(name)sValidArgsNewId) { EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args_with_new_id)s)); EXPECT_CALL(*gl_, %(gl_gen_func_name)s(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); SpecializedSetup<cmds::%(name)s, 0>(true); cmds::%(name)s cmd; cmd.Init(%(args_with_new_id)s); @@ -6011,28 +6062,34 @@ class GENnHandler(TypeHandler): arg.WriteClientSideValidationCode(f, func) not_shared = func.GetInfo('not_shared') if not_shared: - alloc_code = ( - -""" IdAllocator* id_allocator = GetIdAllocator(id_namespaces::k%s); - for (GLsizei ii = 0; ii < n; ++ii) - %s[ii] = id_allocator->AllocateID();""" % - (func.GetInfo('resource_types'), func.GetOriginalArgs()[1].name)) + alloc_code = ("""\ + IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::k%s); + for (GLsizei ii = 0; ii < n; ++ii) + %s[ii] = id_allocator->AllocateID();""" % + (func.GetInfo('resource_types'), func.GetOriginalArgs()[1].name)) else: - alloc_code = (""" GetIdHandler(id_namespaces::k%(resource_types)s)-> + alloc_code = ("""\ + GetIdHandler(SharedIdNamespaces::k%(resource_types)s)-> MakeIds(this, 0, %(args)s);""" % args) args['alloc_code'] = alloc_code - code = """ GPU_CLIENT_SINGLE_THREAD_CHECK(); -%(alloc_code)s - %(name)sHelper(%(args)s); - helper_->%(name)sImmediate(%(args)s); - if (share_group_->bind_generates_resource()) - helper_->CommandBufferHelper::Flush(); -%(log_code)s - CheckGLError(); -} + code = """\ + GPU_CLIENT_SINGLE_THREAD_CHECK(); + %(alloc_code)s + %(name)sHelper(%(args)s); + helper_->%(name)sImmediate(%(args)s); + """ + if not not_shared: + code += """\ + if (share_group_->bind_generates_resource()) + helper_->CommandBufferHelper::Flush(); + """ + code += """\ + %(log_code)s + CheckGLError(); + } -""" + """ f.write(code % args) def WriteGLES2ImplementationUnitTest(self, func, f): @@ -6068,7 +6125,7 @@ TEST_F(GLES2ImplementationTest, %(name)s) { valid_test = """ TEST_P(%(test_name)s, %(name)sValidArgs) { EXPECT_CALL(*gl_, %(gl_func_name)s(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>(); GLuint temp = kNewClientId; SpecializedSetup<cmds::%(name)s, 0>(true); @@ -6322,10 +6379,10 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { f.write(" GLuint client_id;\n") if func.return_type == "GLsync": f.write( - " GetIdHandler(id_namespaces::kSyncs)->\n") + " GetIdHandler(SharedIdNamespaces::kSyncs)->\n") else: f.write( - " GetIdHandler(id_namespaces::kProgramsAndShaders)->\n") + " GetIdHandler(SharedIdNamespaces::kProgramsAndShaders)->\n") f.write(" MakeIds(this, 0, 1, &client_id);\n") f.write(" helper_->%s(%s);\n" % (func.name, func.MakeCmdArgString(""))) @@ -8349,7 +8406,7 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { SpecializedSetup<cmds::%(name)s, 0>(true); %(expect_len_code)s EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)) - .WillOnce(DoAll(SetArgumentPointee<2>(strlen(kInfo)), + .WillOnce(DoAll(SetArgPointee<2>(strlen(kInfo)), SetArrayArgument<3>(kInfo, kInfo + strlen(kInfo) + 1))); cmds::%(name)s cmd; cmd.Init(%(args)s); @@ -8378,7 +8435,7 @@ TEST_P(%(test_name)s, %(name)sValidArgs) { if get_len_func and get_len_func[0:2] == 'gl': sub['expect_len_code'] = ( " EXPECT_CALL(*gl_, %s(%s, %s, _))\n" - " .WillOnce(SetArgumentPointee<2>(strlen(kInfo) + 1));") % ( + " .WillOnce(SetArgPointee<2>(strlen(kInfo) + 1));") % ( get_len_func[2:], id_name, get_len_enum) self.WriteValidUnitTest(func, f, valid_test, sub, *extras) @@ -10906,8 +10963,7 @@ extern const NameToFunc g_gles2_function_table[] = { if not value in dict: dict[value] = name # check our own _CHROMIUM macro conflicts with khronos GL headers. - elif dict[value] != name and (name.endswith('_CHROMIUM') or - dict[value].endswith('_CHROMIUM')): + elif EnumsConflict(dict[value], name): self.Error("code collision: %s and %s have the same code %s" % (dict[value], name, value)) diff --git a/chromium/gpu/command_buffer/client/BUILD.gn b/chromium/gpu/command_buffer/client/BUILD.gn index 33964be2d91..30c6f60f5d7 100644 --- a/chromium/gpu/command_buffer/client/BUILD.gn +++ b/chromium/gpu/command_buffer/client/BUILD.gn @@ -35,6 +35,8 @@ source_set("client_sources") { visibility = [ "//gpu/*" ] sources = [ + "client_discardable_manager.cc", + "client_discardable_manager.h", "cmd_buffer_helper.cc", "cmd_buffer_helper.h", "fenced_allocator.cc", diff --git a/chromium/gpu/command_buffer/client/DEPS b/chromium/gpu/command_buffer/client/DEPS new file mode 100644 index 00000000000..867a547a663 --- /dev/null +++ b/chromium/gpu/command_buffer/client/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+ui/latency", +] diff --git a/chromium/gpu/command_buffer/client/client_discardable_manager.cc b/chromium/gpu/command_buffer/client/client_discardable_manager.cc new file mode 100644 index 00000000000..d657751f66f --- /dev/null +++ b/chromium/gpu/command_buffer/client/client_discardable_manager.cc @@ -0,0 +1,232 @@ +// Copyright (c) 2017 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/client/client_discardable_manager.h" + +#include "base/containers/flat_set.h" +#include "base/memory/ptr_util.h" +#include "base/sys_info.h" + +namespace gpu { +namespace { + +// Stores a set of offsets, initially 0 to |element_count_|. Allows callers to +// take and return offsets from the set. Internally stores the offsets as a set +// of ranges. This means that in the worst case (every other offset taken), the +// set will use |element_count_| uints, but should typically use fewer. +class FreeOffsetSet { + public: + // Creates a new set, containing 0 to |element_count|. + explicit FreeOffsetSet(uint32_t element_count); + + // Returns true if the set contains at least one element. + bool HasFreeOffset() const; + + // Returns true if any element from the set has been taken. + bool HasUsedOffset() const; + + // Takes a free offset from the set. Should only be called if HasFreeOffset(). + uint32_t TakeFreeOffset(); + + // Returns an offset to the set. + void ReturnFreeOffset(uint32_t offset); + + private: + struct FreeRange { + uint32_t start; + uint32_t end; + }; + struct CompareFreeRanges { + bool operator()(const FreeRange& a, const FreeRange& b) const { + return a.start < b.start; + } + }; + + const uint32_t element_count_; + base::flat_set<FreeRange, CompareFreeRanges> free_ranges_; + + DISALLOW_COPY_AND_ASSIGN(FreeOffsetSet); +}; + +FreeOffsetSet::FreeOffsetSet(uint32_t element_count) + : element_count_(element_count) { + free_ranges_.insert({0, element_count_}); +} + +bool FreeOffsetSet::HasFreeOffset() const { + return !free_ranges_.empty(); +} + +bool FreeOffsetSet::HasUsedOffset() const { + if (free_ranges_.size() != 1 || free_ranges_.begin()->start != 0 || + free_ranges_.begin()->end != element_count_) + return true; + + return false; +} + +uint32_t FreeOffsetSet::TakeFreeOffset() { + DCHECK(HasFreeOffset()); + + auto it = free_ranges_.begin(); + uint32_t offset_to_return = it->start; + + FreeRange new_range{it->start + 1, it->end}; + free_ranges_.erase(it); + if (new_range.start != new_range.end) + free_ranges_.insert(new_range); + + return offset_to_return; +} + +void FreeOffsetSet::ReturnFreeOffset(uint32_t offset) { + FreeRange new_range{offset, offset + 1}; + + // Find the FreeRange directly before/after our new range. + auto next_range = free_ranges_.lower_bound(new_range); + auto prev_range = free_ranges_.end(); + if (next_range != free_ranges_.begin()) { + prev_range = std::prev(next_range); + } + + // Collapse ranges if possible. + if (prev_range != free_ranges_.end() && prev_range->end == new_range.start) { + new_range.start = prev_range->start; + // Erase invalidates the next_range iterator, so re-acquire it. + next_range = free_ranges_.erase(prev_range); + } + + if (next_range != free_ranges_.end() && next_range->start == new_range.end) { + new_range.end = next_range->end; + free_ranges_.erase(next_range); + } + + free_ranges_.insert(new_range); +} + +// Returns the size of the allocation which ClientDiscardableManager will +// sub-allocate from. This should be at least as big as the minimum shared +// memory allocation size. +size_t AllocationSize() { +#if defined(OS_NACL) + // base::SysInfo isn't available under NaCl. + size_t allocation_size = getpagesize(); +#else + size_t allocation_size = base::SysInfo::VMAllocationGranularity(); +#endif + + // If the allocation is small (less than 2K), round it up to at least 2K. + allocation_size = std::max(static_cast<size_t>(2048), allocation_size); + return allocation_size; +} + +} // namespace + +struct ClientDiscardableManager::Allocation { + Allocation(uint32_t element_count) : free_offsets(element_count) {} + + scoped_refptr<Buffer> buffer; + int32_t shm_id = 0; + FreeOffsetSet free_offsets; +}; + +ClientDiscardableManager::ClientDiscardableManager() + : allocation_size_(AllocationSize()) {} +ClientDiscardableManager::~ClientDiscardableManager() = default; + +ClientDiscardableHandle ClientDiscardableManager::InitializeTexture( + CommandBuffer* command_buffer, + uint32_t texture_id) { + DCHECK(texture_handles_.find(texture_id) == texture_handles_.end()); + + scoped_refptr<Buffer> buffer; + uint32_t offset = 0; + int32_t shm_id = 0; + FindAllocation(command_buffer, &buffer, &shm_id, &offset); + uint32_t byte_offset = offset * element_size_; + ClientDiscardableHandle handle(std::move(buffer), byte_offset, shm_id); + texture_handles_.emplace(texture_id, handle); + return handle; +} + +bool ClientDiscardableManager::LockTexture(uint32_t texture_id) { + auto found = texture_handles_.find(texture_id); + DCHECK(found != texture_handles_.end()); + return found->second.Lock(); +} + +void ClientDiscardableManager::FreeTexture(uint32_t texture_id) { + auto found = texture_handles_.find(texture_id); + if (found == texture_handles_.end()) + return; + pending_handles_.push(found->second); + texture_handles_.erase(found); +} + +bool ClientDiscardableManager::TextureIsValid(uint32_t texture_id) const { + return texture_handles_.find(texture_id) != texture_handles_.end(); +} + +void ClientDiscardableManager::FindAllocation(CommandBuffer* command_buffer, + scoped_refptr<Buffer>* buffer, + int32_t* shm_id, + uint32_t* offset) { + CheckPending(command_buffer); + + for (auto& allocation : allocations_) { + if (!allocation->free_offsets.HasFreeOffset()) + continue; + + *offset = allocation->free_offsets.TakeFreeOffset(); + *shm_id = allocation->shm_id; + *buffer = allocation->buffer; + return; + } + + // We couldn't find an existing free entry. Allocate more space. + auto allocation = base::MakeUnique<Allocation>(elements_per_allocation_); + allocation->buffer = command_buffer->CreateTransferBuffer( + allocation_size_, &allocation->shm_id); + + *offset = allocation->free_offsets.TakeFreeOffset(); + *shm_id = allocation->shm_id; + *buffer = allocation->buffer; + allocations_.push_back(std::move(allocation)); +} + +void ClientDiscardableManager::ReturnAllocation( + CommandBuffer* command_buffer, + const ClientDiscardableHandle& handle) { + for (auto it = allocations_.begin(); it != allocations_.end(); ++it) { + Allocation* allocation = it->get(); + if (allocation->shm_id != handle.shm_id()) + continue; + + allocation->free_offsets.ReturnFreeOffset(handle.byte_offset() / + element_size_); + + if (!allocation->free_offsets.HasUsedOffset()) { + command_buffer->DestroyTransferBuffer(allocation->shm_id); + allocations_.erase(it); + return; + } + } +} + +void ClientDiscardableManager::CheckPending(CommandBuffer* command_buffer) { + while (pending_handles_.size() > 0 && + pending_handles_.front().CanBeReUsed()) { + ReturnAllocation(command_buffer, pending_handles_.front()); + pending_handles_.pop(); + } +} + +ClientDiscardableHandle ClientDiscardableManager::GetHandleForTesting( + uint32_t texture_id) { + auto found = texture_handles_.find(texture_id); + DCHECK(found != texture_handles_.end()); + return found->second; +} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/client/client_discardable_manager.h b/chromium/gpu/command_buffer/client/client_discardable_manager.h new file mode 100644 index 00000000000..780b80dcf17 --- /dev/null +++ b/chromium/gpu/command_buffer/client/client_discardable_manager.h @@ -0,0 +1,72 @@ +// Copyright (c) 2017 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_CLIENT_DISCARDABLE_MANAGER_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CLIENT_DISCARDABLE_MANAGER_H_ + +#include <map> +#include <queue> +#include <set> + +#include "gpu/command_buffer/common/command_buffer.h" +#include "gpu/command_buffer/common/discardable_handle.h" +#include "gpu/gpu_export.h" + +namespace gpu { + +// ClientDiscardableManager is a helper class used by the client GLES2 +// implementation. Currently, this class only supports textures, but it could +// be extended to other types in the future. +// +// When the GLES2 impl is done with a texture (the texture is being deleted), +// it should call FreeTexture to allow helper memory to be reclaimed. +class GPU_EXPORT ClientDiscardableManager { + public: + ClientDiscardableManager(); + ~ClientDiscardableManager(); + ClientDiscardableHandle InitializeTexture(CommandBuffer* command_buffer, + uint32_t texture_id); + bool LockTexture(uint32_t texture_id); + void FreeTexture(uint32_t texture_id); + bool TextureIsValid(uint32_t texture_id) const; + + // Test only functions. + void CheckPendingForTesting(CommandBuffer* command_buffer) { + CheckPending(command_buffer); + } + void SetElementCountForTesting(uint32_t count) { + elements_per_allocation_ = count; + allocation_size_ = count * element_size_; + } + ClientDiscardableHandle GetHandleForTesting(uint32_t texture_id); + + private: + void FindAllocation(CommandBuffer* command_buffer, + scoped_refptr<Buffer>* buffer, + int32_t* shm_id, + uint32_t* offset); + void ReturnAllocation(CommandBuffer* command_buffer, + const ClientDiscardableHandle& handle); + void CheckPending(CommandBuffer* command_buffer); + + private: + size_t allocation_size_; + size_t element_size_ = sizeof(base::subtle::Atomic32); + uint32_t elements_per_allocation_ = + static_cast<uint32_t>(allocation_size_ / element_size_); + + struct Allocation; + std::vector<std::unique_ptr<Allocation>> allocations_; + std::map<uint32_t, ClientDiscardableHandle> texture_handles_; + + // Handles that are pending service deletion, and can be re-used once + // ClientDiscardableHandle::CanBeReUsed returns true. + std::queue<ClientDiscardableHandle> pending_handles_; + + DISALLOW_COPY_AND_ASSIGN(ClientDiscardableManager); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_CLIENT_CLIENT_DISCARDABLE_MANAGER_H_ diff --git a/chromium/gpu/command_buffer/client/client_discardable_manager_unittest.cc b/chromium/gpu/command_buffer/client/client_discardable_manager_unittest.cc new file mode 100644 index 00000000000..fd6df57c87e --- /dev/null +++ b/chromium/gpu/command_buffer/client/client_discardable_manager_unittest.cc @@ -0,0 +1,159 @@ +// Copyright (c) 2017 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/client/client_discardable_manager.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { +namespace { +class FakeCommandBuffer : public CommandBuffer { + public: + FakeCommandBuffer() = default; + ~FakeCommandBuffer() override { EXPECT_TRUE(active_ids_.empty()); } + // Overridden from CommandBuffer: + State GetLastState() override { + NOTREACHED(); + return State(); + }; + void Flush(int32_t put_offset) override { NOTREACHED(); } + void OrderingBarrier(int32_t put_offset) override { NOTREACHED(); } + State WaitForTokenInRange(int32_t start, int32_t end) override { + NOTREACHED(); + + return State(); + } + State WaitForGetOffsetInRange(uint32_t set_get_buffer_count, + int32_t start, + int32_t end) override { + NOTREACHED(); + return State(); + } + void SetGetBuffer(int32_t transfer_buffer_id) override { NOTREACHED(); } + scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size, + int32_t* id) override { + EXPECT_GE(size, 2048u); + *id = next_id_++; + active_ids_.insert(*id); + std::unique_ptr<base::SharedMemory> shared_mem(new base::SharedMemory); + shared_mem->CreateAndMapAnonymous(size); + return MakeBufferFromSharedMemory(std::move(shared_mem), size); + } + void DestroyTransferBuffer(int32_t id) override { + auto found = active_ids_.find(id); + EXPECT_TRUE(found != active_ids_.end()); + active_ids_.erase(found); + } + + private: + int32_t next_id_ = 1; + std::set<int32_t> active_ids_; +}; + +void UnlockClientHandleForTesting( + const ClientDiscardableHandle& client_handle) { + ServiceDiscardableHandle service_handle(client_handle.BufferForTesting(), + client_handle.byte_offset(), + client_handle.shm_id()); + service_handle.Unlock(); +} + +bool DeleteClientHandleForTesting( + const ClientDiscardableHandle& client_handle) { + ServiceDiscardableHandle service_handle(client_handle.BufferForTesting(), + client_handle.byte_offset(), + client_handle.shm_id()); + return service_handle.Delete(); +} + +void UnlockAndDeleteClientHandleForTesting( + const ClientDiscardableHandle& client_handle) { + UnlockClientHandleForTesting(client_handle); + EXPECT_TRUE(DeleteClientHandleForTesting(client_handle)); +} + +} // namespace + +TEST(ClientDiscardableManagerTest, BasicUsage) { + FakeCommandBuffer command_buffer; + ClientDiscardableManager manager; + { + ClientDiscardableHandle handle = + manager.InitializeTexture(&command_buffer, 1); + EXPECT_TRUE(handle.IsLockedForTesting()); + EXPECT_EQ(handle.shm_id(), 1); + EXPECT_FALSE(DeleteClientHandleForTesting(handle)); + UnlockClientHandleForTesting(handle); + manager.LockTexture(1); + EXPECT_FALSE(DeleteClientHandleForTesting(handle)); + UnlockAndDeleteClientHandleForTesting(handle); + } + manager.FreeTexture(1); + manager.CheckPendingForTesting(&command_buffer); +} + +TEST(ClientDiscardableManagerTest, Reuse) { + FakeCommandBuffer command_buffer; + ClientDiscardableManager manager; + manager.SetElementCountForTesting(1024); + for (int i = 1; i <= 1024; ++i) { + ClientDiscardableHandle handle = + manager.InitializeTexture(&command_buffer, i); + EXPECT_TRUE(handle.IsLockedForTesting()); + EXPECT_EQ(handle.shm_id(), 1); + UnlockAndDeleteClientHandleForTesting(handle); + } + // Delete every other entry. + for (int i = 1; i <= 1024; i += 2) { + manager.FreeTexture(i); + } + // Allocate 512 more entries, ensure we re-use the original buffer. + for (int i = 1; i <= 512; ++i) { + ClientDiscardableHandle handle = + manager.InitializeTexture(&command_buffer, 1024 + i); + EXPECT_TRUE(handle.IsLockedForTesting()); + EXPECT_EQ(handle.shm_id(), 1); + UnlockAndDeleteClientHandleForTesting(handle); + } + // Delete the other half of the original allocations. + for (int i = 2; i <= 1024; i += 2) { + manager.FreeTexture(i); + } + // And delete the second set of allocations. + for (int i = 1; i <= 512; ++i) { + manager.FreeTexture(1024 + i); + } + manager.CheckPendingForTesting(&command_buffer); +} + +TEST(ClientDiscardableManagerTest, MultipleAllocations) { + FakeCommandBuffer command_buffer; + ClientDiscardableManager manager; + manager.SetElementCountForTesting(1024); + for (int i = 1; i <= 1024; ++i) { + ClientDiscardableHandle handle = + manager.InitializeTexture(&command_buffer, i); + EXPECT_TRUE(handle.IsLockedForTesting()); + EXPECT_EQ(handle.shm_id(), 1); + UnlockAndDeleteClientHandleForTesting(handle); + } + // Allocate and free one entry multiple times, this should cause the + // allocation and release of a new shm_id each time. + for (int i = 1; i < 10; ++i) { + { + ClientDiscardableHandle handle = + manager.InitializeTexture(&command_buffer, 1024 + i); + EXPECT_TRUE(handle.IsLockedForTesting()); + EXPECT_EQ(handle.shm_id(), i + 1); + UnlockAndDeleteClientHandleForTesting(handle); + } + manager.FreeTexture(1024 + i); + } + // Delete every other entry. + for (int i = 1; i <= 1024; ++i) { + manager.FreeTexture(i); + } + manager.CheckPendingForTesting(&command_buffer); +} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/client/client_test_helper.cc b/chromium/gpu/command_buffer/client/client_test_helper.cc index 12c889c6424..e1cbda5955f 100644 --- a/chromium/gpu/command_buffer/client/client_test_helper.cc +++ b/chromium/gpu/command_buffer/client/client_test_helper.cc @@ -20,45 +20,21 @@ using ::testing::Invoke; namespace gpu { -MockCommandBufferBase::MockCommandBufferBase() : put_offset_(0) {} +FakeCommandBufferServiceBase::FakeCommandBufferServiceBase() {} -MockCommandBufferBase::~MockCommandBufferBase() {} +FakeCommandBufferServiceBase::~FakeCommandBufferServiceBase() {} -CommandBuffer::State MockCommandBufferBase::GetLastState() { +CommandBuffer::State FakeCommandBufferServiceBase::GetState() { return state_; } -void MockCommandBufferBase::SetGetOffset(int32_t get_offset) { - state_.get_offset = get_offset; -} - -void MockCommandBufferBase::SetReleaseCount(uint64_t release_count) { +void FakeCommandBufferServiceBase::SetReleaseCount(uint64_t release_count) { state_.release_count = release_count; } -CommandBuffer::State MockCommandBufferBase::WaitForTokenInRange(int32_t start, - int32_t end) { - return state_; -} - -CommandBuffer::State MockCommandBufferBase::WaitForGetOffsetInRange( - int32_t start, - int32_t end) { - state_.get_offset = put_offset_; - OnFlush(); - return state_; -} - -void MockCommandBufferBase::SetGetBuffer(int transfer_buffer_id) { - ring_buffer_buffer_ = GetTransferBuffer(transfer_buffer_id); - ring_buffer_ = - static_cast<CommandBufferEntry*>(ring_buffer_buffer_->memory()); - state_.token = 10000; // All token checks in the tests should pass. -} - // Get's the Id of the next transfer buffer that will be returned // by CreateTransferBuffer. This is useful for testing expected ids. -int32_t MockCommandBufferBase::GetNextFreeTransferBufferId() { +int32_t FakeCommandBufferServiceBase::GetNextFreeTransferBufferId() { for (size_t ii = 0; ii < arraysize(transfer_buffer_buffers_); ++ii) { if (!transfer_buffer_buffers_[ii].get()) { return kTransferBufferBaseId + ii; @@ -67,9 +43,15 @@ int32_t MockCommandBufferBase::GetNextFreeTransferBufferId() { return -1; } -scoped_refptr<gpu::Buffer> MockCommandBufferBase::CreateTransferBuffer( - size_t size, - int32_t* id) { +void FakeCommandBufferServiceBase::SetGetBufferHelper(int transfer_buffer_id) { + ++state_.set_get_buffer_count; + state_.get_offset = 0; + state_.token = 10000; // All token checks in the tests should pass. +} + +scoped_refptr<gpu::Buffer> +FakeCommandBufferServiceBase::CreateTransferBufferHelper(size_t size, + int32_t* id) { *id = GetNextFreeTransferBufferId(); if (*id >= 0) { int32_t ndx = *id - kTransferBufferBaseId; @@ -81,47 +63,42 @@ scoped_refptr<gpu::Buffer> MockCommandBufferBase::CreateTransferBuffer( return GetTransferBuffer(*id); } -void MockCommandBufferBase::DestroyTransferBufferHelper(int32_t id) { +void FakeCommandBufferServiceBase::DestroyTransferBufferHelper(int32_t id) { DCHECK_GE(id, kTransferBufferBaseId); DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); id -= kTransferBufferBaseId; transfer_buffer_buffers_[id] = NULL; } -scoped_refptr<Buffer> MockCommandBufferBase::GetTransferBuffer(int32_t id) { - DCHECK_GE(id, kTransferBufferBaseId); - DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); +scoped_refptr<Buffer> FakeCommandBufferServiceBase::GetTransferBuffer( + int32_t id) { + if ((id < kTransferBufferBaseId) || + (id >= kTransferBufferBaseId + kMaxTransferBuffers)) + return nullptr; return transfer_buffer_buffers_[id - kTransferBufferBaseId]; } -void MockCommandBufferBase::FlushHelper(int32_t put_offset) { - put_offset_ = put_offset; +void FakeCommandBufferServiceBase::FlushHelper(int32_t put_offset) { + state_.get_offset = put_offset; } -void MockCommandBufferBase::SetToken(int32_t token) { - NOTREACHED(); +void FakeCommandBufferServiceBase::SetToken(int32_t token) { state_.token = token; } -void MockCommandBufferBase::SetParseError(error::Error error) { - NOTREACHED(); +void FakeCommandBufferServiceBase::SetParseError(error::Error error) { state_.error = error; } -void MockCommandBufferBase::SetContextLostReason( +void FakeCommandBufferServiceBase::SetContextLostReason( error::ContextLostReason reason) { - NOTREACHED(); state_.context_lost_reason = reason; } -int32_t MockCommandBufferBase::GetPutOffset() { - return put_offset_; -} - // GCC requires these declarations, but MSVC requires they not be present #ifndef _MSC_VER -const int32_t MockCommandBufferBase::kTransferBufferBaseId; -const int32_t MockCommandBufferBase::kMaxTransferBuffers; +const int32_t FakeCommandBufferServiceBase::kTransferBufferBaseId; +const int32_t FakeCommandBufferServiceBase::kMaxTransferBuffers; #endif MockClientCommandBuffer::MockClientCommandBuffer() { @@ -130,18 +107,51 @@ MockClientCommandBuffer::MockClientCommandBuffer() { MockClientCommandBuffer::~MockClientCommandBuffer() {} +CommandBuffer::State MockClientCommandBuffer::GetLastState() { + return GetState(); +} + +CommandBuffer::State MockClientCommandBuffer::WaitForTokenInRange(int32_t start, + int32_t end) { + return GetState(); +} + +CommandBuffer::State MockClientCommandBuffer::WaitForGetOffsetInRange( + uint32_t set_get_buffer_count, + int32_t start, + int32_t end) { + State state = GetState(); + EXPECT_EQ(set_get_buffer_count, state.set_get_buffer_count); + if (state.get_offset != put_offset_) { + FlushHelper(put_offset_); + OnFlush(); + state = GetState(); + } + return state; +} + +void MockClientCommandBuffer::SetGetBuffer(int transfer_buffer_id) { + SetGetBufferHelper(transfer_buffer_id); +} + +scoped_refptr<gpu::Buffer> MockClientCommandBuffer::CreateTransferBuffer( + size_t size, + int32_t* id) { + return CreateTransferBufferHelper(size, id); +} + void MockClientCommandBuffer::Flush(int32_t put_offset) { - FlushHelper(put_offset); + put_offset_ = put_offset; } void MockClientCommandBuffer::OrderingBarrier(int32_t put_offset) { - FlushHelper(put_offset); + put_offset_ = put_offset; } void MockClientCommandBuffer::DelegateToFake() { ON_CALL(*this, DestroyTransferBuffer(_)) - .WillByDefault( - Invoke(this, &MockCommandBufferBase::DestroyTransferBufferHelper)); + .WillByDefault(Invoke( + this, &FakeCommandBufferServiceBase::DestroyTransferBufferHelper)); } MockClientCommandBufferMockFlush::MockClientCommandBufferMockFlush() { @@ -153,7 +163,11 @@ MockClientCommandBufferMockFlush::~MockClientCommandBufferMockFlush() {} void MockClientCommandBufferMockFlush::DelegateToFake() { MockClientCommandBuffer::DelegateToFake(); ON_CALL(*this, Flush(_)) - .WillByDefault(Invoke(this, &MockCommandBufferBase::FlushHelper)); + .WillByDefault(Invoke(this, &MockClientCommandBufferMockFlush::DoFlush)); +} + +void MockClientCommandBufferMockFlush::DoFlush(int32_t put_offset) { + MockClientCommandBuffer::Flush(put_offset); } MockClientGpuControl::MockClientGpuControl() {} diff --git a/chromium/gpu/command_buffer/client/client_test_helper.h b/chromium/gpu/command_buffer/client/client_test_helper.h index f806fbbb606..8881436a1d5 100644 --- a/chromium/gpu/command_buffer/client/client_test_helper.h +++ b/chromium/gpu/command_buffer/client/client_test_helper.h @@ -21,53 +21,55 @@ #include "gpu/command_buffer/service/command_buffer_service.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/latency/latency_info.h" namespace gpu { -class MockCommandBufferBase : public CommandBufferServiceBase { +class FakeCommandBufferServiceBase : public CommandBufferServiceBase { public: static const int32_t kTransferBufferBaseId = 0x123; static const int32_t kMaxTransferBuffers = 32; - MockCommandBufferBase(); - ~MockCommandBufferBase() override; + FakeCommandBufferServiceBase(); + ~FakeCommandBufferServiceBase() override; - State GetLastState() override; - State WaitForTokenInRange(int32_t start, int32_t end) override; - State WaitForGetOffsetInRange(int32_t start, int32_t end) override; - void SetGetBuffer(int transfer_buffer_id) override; - void SetGetOffset(int32_t get_offset) override; + CommandBuffer::State GetState() override; void SetReleaseCount(uint64_t release_count) override; - scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size, - int32_t* id) override; scoped_refptr<gpu::Buffer> GetTransferBuffer(int32_t id) override; void SetToken(int32_t token) override; void SetParseError(error::Error error) override; void SetContextLostReason(error::ContextLostReason reason) override; - int32_t GetPutOffset() override; // Get's the Id of the next transfer buffer that will be returned // by CreateTransferBuffer. This is useful for testing expected ids. int32_t GetNextFreeTransferBufferId(); void FlushHelper(int32_t put_offset); + void SetGetBufferHelper(int transfer_buffer_id); + scoped_refptr<gpu::Buffer> CreateTransferBufferHelper(size_t size, + int32_t* id); void DestroyTransferBufferHelper(int32_t id); - virtual void OnFlush() = 0; - private: scoped_refptr<Buffer> transfer_buffer_buffers_[kMaxTransferBuffers]; - CommandBufferEntry* ring_buffer_; - scoped_refptr<Buffer> ring_buffer_buffer_; - State state_; - int32_t put_offset_; + CommandBuffer::State state_; }; -class MockClientCommandBuffer : public MockCommandBufferBase { +class MockClientCommandBuffer : public CommandBuffer, + public FakeCommandBufferServiceBase { public: MockClientCommandBuffer(); ~MockClientCommandBuffer() override; + State GetLastState() override; + State WaitForTokenInRange(int32_t start, int32_t end) override; + State WaitForGetOffsetInRange(uint32_t set_get_buffer_count, + int32_t start, + int32_t end) override; + void SetGetBuffer(int transfer_buffer_id) override; + scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size, + int32_t* id) override; + // This is so we can use all the gmock functions when Flush is called. MOCK_METHOD0(OnFlush, void()); MOCK_METHOD1(DestroyTransferBuffer, void(int32_t id)); @@ -76,6 +78,11 @@ class MockClientCommandBuffer : public MockCommandBufferBase { void OrderingBarrier(int32_t put_offset) override; void DelegateToFake(); + + int32_t GetServicePutOffset() { return put_offset_; } + + private: + int32_t put_offset_ = 0; }; class MockClientCommandBufferMockFlush : public MockClientCommandBuffer { @@ -87,6 +94,7 @@ class MockClientCommandBufferMockFlush : public MockClientCommandBuffer { MOCK_METHOD1(OrderingBarrier, void(int32_t put_offset)); void DelegateToFake(); + void DoFlush(int32_t put_offset); }; class MockClientGpuControl : public GpuControl { @@ -109,7 +117,8 @@ class MockClientGpuControl : public GpuControl { MOCK_METHOD0(EnsureWorkVisible, void()); MOCK_CONST_METHOD0(GetNamespaceID, CommandBufferNamespace()); MOCK_CONST_METHOD0(GetCommandBufferID, CommandBufferId()); - MOCK_CONST_METHOD0(GetExtraCommandBufferData, int32_t()); + MOCK_CONST_METHOD0(GetStreamId, int32_t()); + MOCK_METHOD1(FlushOrderingBarrierOnStream, void(int32_t)); MOCK_METHOD0(GenerateFenceSyncRelease, uint64_t()); MOCK_METHOD1(IsFenceSyncRelease, bool(uint64_t release)); MOCK_METHOD1(IsFenceSyncFlushed, bool(uint64_t release)); @@ -119,6 +128,7 @@ class MockClientGpuControl : public GpuControl { const base::Closure& callback)); MOCK_METHOD1(WaitSyncTokenHint, void(const SyncToken&)); MOCK_METHOD1(CanWaitUnverifiedSyncToken, bool(const SyncToken&)); + MOCK_METHOD1(AddLatencyInfo, void(const std::vector<ui::LatencyInfo>&)); private: DISALLOW_COPY_AND_ASSIGN(MockClientGpuControl); diff --git a/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc b/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc index 7021fa399f4..42cb4165a84 100644 --- a/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc +++ b/chromium/gpu/command_buffer/client/cmd_buffer_helper.cc @@ -35,6 +35,8 @@ CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) last_put_sent_(0), cached_last_token_read_(0), cached_get_offset_(0), + set_get_buffer_count_(0), + service_on_old_buffer_(false), #if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK) commands_issued_(0), #endif @@ -117,12 +119,15 @@ bool CommandBufferHelper::AllocateRingBuffer() { ring_buffer_ = buffer; ring_buffer_id_ = id; command_buffer_->SetGetBuffer(id); + ++set_get_buffer_count_; entries_ = static_cast<CommandBufferEntry*>(ring_buffer_->memory()); total_entry_count_ = ring_buffer_size_ / sizeof(CommandBufferEntry); // Call to SetGetBuffer(id) above resets get and put offsets to 0. // No need to query it through IPC. put_ = 0; + last_put_sent_ = 0; cached_get_offset_ = 0; + service_on_old_buffer_ = true; CalcImmediateEntries(0); return true; } @@ -153,7 +158,12 @@ CommandBufferHelper::~CommandBufferHelper() { } void CommandBufferHelper::UpdateCachedState(const CommandBuffer::State& state) { - cached_get_offset_ = state.get_offset; + // If the service hasn't seen the current get buffer yet (i.e. hasn't + // processed the latest SetGetBuffer), it's as if it hadn't processed anything + // in it, i.e. get == 0. + service_on_old_buffer_ = + (state.set_get_buffer_count != set_get_buffer_count_); + cached_get_offset_ = service_on_old_buffer_ ? 0 : state.get_offset; cached_last_token_read_ = state.token; context_lost_ = error::IsError(state.error); } @@ -164,8 +174,8 @@ bool CommandBufferHelper::WaitForGetOffsetInRange(int32_t start, int32_t end) { if (!usable()) { return false; } - CommandBuffer::State last_state = - command_buffer_->WaitForGetOffsetInRange(start, end); + CommandBuffer::State last_state = command_buffer_->WaitForGetOffsetInRange( + set_get_buffer_count_, start, end); UpdateCachedState(last_state); return !context_lost_; } @@ -214,12 +224,13 @@ bool CommandBufferHelper::Finish() { return false; } // If there is no work just exit. - if (put_ == cached_get_offset_) { + if (put_ == cached_get_offset_ && !service_on_old_buffer_) { return true; } DCHECK(HaveRingBuffer() || error::IsError(command_buffer_->GetLastState().error)); - Flush(); + if (last_put_sent_ != put_) + Flush(); if (!WaitForGetOffsetInRange(put_, put_)) return false; DCHECK_EQ(cached_get_offset_, put_); diff --git a/chromium/gpu/command_buffer/client/cmd_buffer_helper.h b/chromium/gpu/command_buffer/client/cmd_buffer_helper.h index 3ea507f8975..bdf7bbad1d2 100644 --- a/chromium/gpu/command_buffer/client/cmd_buffer_helper.h +++ b/chromium/gpu/command_buffer/client/cmd_buffer_helper.h @@ -301,6 +301,8 @@ class GPU_EXPORT CommandBufferHelper int32_t last_put_sent_; int32_t cached_last_token_read_; int32_t cached_get_offset_; + uint32_t set_get_buffer_count_; + bool service_on_old_buffer_; #if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK) int commands_issued_; diff --git a/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc index 3489ea8b8de..3cada6afbde 100644 --- a/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc +++ b/chromium/gpu/command_buffer/client/cmd_buffer_helper_test.cc @@ -14,10 +14,10 @@ #include "base/bind_helpers.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" -#include "gpu/command_buffer/service/command_buffer_service.h" -#include "gpu/command_buffer/service/command_executor.h" +#include "gpu/command_buffer/service/command_buffer_direct.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -37,26 +37,27 @@ const int32_t kCommandBufferSizeBytes = kTotalNumCommandEntries * sizeof(CommandBufferEntry); const int32_t kUnusedCommandId = 5; // we use 0 and 2 currently. -// Override CommandBufferService::Flush() to lock flushing and simulate +// Override CommandBufferDirect::Flush() to lock flushing and simulate // the buffer becoming full in asynchronous mode. -class CommandBufferServiceLocked : public CommandBufferService { +class CommandBufferDirectLocked : public CommandBufferDirect { public: - explicit CommandBufferServiceLocked( - TransferBufferManagerInterface* transfer_buffer_manager) - : CommandBufferService(transfer_buffer_manager), + explicit CommandBufferDirectLocked( + TransferBufferManager* transfer_buffer_manager, + AsyncAPIInterface* handler) + : CommandBufferDirect(transfer_buffer_manager, handler), flush_locked_(false), last_flush_(-1), previous_put_offset_(0), flush_count_(0) {} - ~CommandBufferServiceLocked() override {} + ~CommandBufferDirectLocked() override {} - // Overridden from CommandBufferService + // Overridden from CommandBufferDirect void Flush(int32_t put_offset) override { flush_count_++; if (!flush_locked_) { last_flush_ = -1; previous_put_offset_ = put_offset; - CommandBufferService::Flush(put_offset); + CommandBufferDirect::Flush(put_offset); } else { last_flush_ = put_offset; } @@ -68,28 +69,32 @@ class CommandBufferServiceLocked : public CommandBufferService { int FlushCount() { return flush_count_; } - State WaitForGetOffsetInRange(int32_t start, int32_t end) override { + State WaitForGetOffsetInRange(uint32_t set_get_buffer_count, + int32_t start, + int32_t end) override { // Flush only if it's required to unblock this Wait. - if (last_flush_ != -1 && - !CommandBuffer::InRange(start, end, previous_put_offset_)) { + if (last_flush_ != -1 && !InRange(start, end, previous_put_offset_)) { previous_put_offset_ = last_flush_; - CommandBufferService::Flush(last_flush_); + CommandBufferDirect::Flush(last_flush_); last_flush_ = -1; } - return CommandBufferService::WaitForGetOffsetInRange(start, end); + return CommandBufferDirect::WaitForGetOffsetInRange(set_get_buffer_count, + start, end); } + int GetServicePutOffset() { return previous_put_offset_; } + private: bool flush_locked_; int last_flush_; int previous_put_offset_; int flush_count_; - DISALLOW_COPY_AND_ASSIGN(CommandBufferServiceLocked); + DISALLOW_COPY_AND_ASSIGN(CommandBufferDirectLocked); }; // Test fixture for CommandBufferHelper test - Creates a CommandBufferHelper, -// using a CommandBufferEngine with a mock AsyncAPIInterface for its interface -// (calling it directly, not through the RPC mechanism). +// using a CommandBufferServiceLocked with a mock AsyncAPIInterface for its +// interface (calling it directly, not through the RPC mechanism). class CommandBufferHelperTest : public testing::Test { protected: virtual void SetUp() { @@ -100,22 +105,11 @@ class CommandBufferHelperTest : public testing::Test { EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, _, _)) .WillRepeatedly(Return(error::kNoError)); - { - TransferBufferManager* manager = new TransferBufferManager(nullptr); - transfer_buffer_manager_ = manager; - EXPECT_TRUE(manager->Initialize()); - } - command_buffer_.reset( - new CommandBufferServiceLocked(transfer_buffer_manager_.get())); - - executor_.reset( - new CommandExecutor(command_buffer_.get(), api_mock_.get(), NULL)); - command_buffer_->SetPutOffsetChangeCallback(base::Bind( - &CommandExecutor::PutChanged, base::Unretained(executor_.get()))); - command_buffer_->SetGetBufferChangeCallback(base::Bind( - &CommandExecutor::SetGetBuffer, base::Unretained(executor_.get()))); + transfer_buffer_manager_ = base::MakeUnique<TransferBufferManager>(nullptr); + command_buffer_.reset(new CommandBufferDirectLocked( + transfer_buffer_manager_.get(), api_mock_.get())); - api_mock_->set_engine(executor_.get()); + api_mock_->set_command_buffer_service(command_buffer_->service()); helper_.reset(new CommandBufferHelper(command_buffer_.get())); helper_->Initialize(kCommandBufferSizeBytes); @@ -129,8 +123,6 @@ class CommandBufferHelperTest : public testing::Test { test_command_args_.clear(); } - const CommandParser* GetParser() const { return executor_->parser(); } - int32_t ImmediateEntryCount() const { return helper_->immediate_entry_count_; } @@ -193,9 +185,9 @@ class CommandBufferHelperTest : public testing::Test { } helper_->Finish(); - EXPECT_EQ(GetParser()->put(), + EXPECT_EQ(GetPutOffset(), (start_commands * cmd_size) % kTotalNumCommandEntries); - EXPECT_EQ(GetParser()->get(), + EXPECT_EQ(GetGetOffset(), (start_commands * cmd_size) % kTotalNumCommandEntries); // Lock flushing to force the buffer to get full. @@ -222,8 +214,8 @@ class CommandBufferHelperTest : public testing::Test { // Checks that the buffer from put to put+size is free in the parser. void CheckFreeSpace(CommandBufferOffset put, unsigned int size) { - CommandBufferOffset parser_put = GetParser()->put(); - CommandBufferOffset parser_get = GetParser()->get(); + CommandBufferOffset parser_put = GetPutOffset(); + CommandBufferOffset parser_get = GetGetOffset(); CommandBufferOffset limit = put + size; if (parser_get > parser_put) { // "busy" buffer wraps, so "free" buffer is between put (inclusive) and @@ -243,9 +235,11 @@ class CommandBufferHelperTest : public testing::Test { } } - int32_t GetGetOffset() { return command_buffer_->GetLastState().get_offset; } + int32_t GetGetOffset() { + return command_buffer_->service()->GetState().get_offset; + } - int32_t GetPutOffset() { return command_buffer_->GetPutOffset(); } + int32_t GetPutOffset() { return command_buffer_->GetServicePutOffset(); } int32_t GetHelperGetOffset() { return helper_->cached_get_offset_; } @@ -260,9 +254,8 @@ class CommandBufferHelperTest : public testing::Test { CommandBufferOffset get_helper_put() { return helper_->put_; } std::unique_ptr<AsyncAPIMock> api_mock_; - scoped_refptr<TransferBufferManagerInterface> transfer_buffer_manager_; - std::unique_ptr<CommandBufferServiceLocked> command_buffer_; - std::unique_ptr<CommandExecutor> executor_; + std::unique_ptr<TransferBufferManager> transfer_buffer_manager_; + std::unique_ptr<CommandBufferDirectLocked> command_buffer_; std::unique_ptr<CommandBufferHelper> helper_; std::vector<std::unique_ptr<CommandBufferEntry[]>> test_command_args_; unsigned int test_command_next_id_; @@ -437,7 +430,6 @@ TEST_F(CommandBufferHelperTest, TestCalcImmediateEntriesOverFlushLimit) { TEST_F(CommandBufferHelperTest, TestCommandProcessing) { // Check initial state of the engine - it should have been configured by the // helper. - EXPECT_TRUE(GetParser() != NULL); EXPECT_EQ(error::kNoError, GetError()); EXPECT_EQ(0, GetGetOffset()); @@ -457,7 +449,7 @@ TEST_F(CommandBufferHelperTest, TestCommandProcessing) { // Wait until it's done. helper_->Finish(); // Check that the engine has no more work to do. - EXPECT_TRUE(GetParser()->IsEmpty()); + EXPECT_EQ(GetGetOffset(), GetPutOffset()); // Check that the commands did happen. Mock::VerifyAndClearExpectations(api_mock_.get()); @@ -671,7 +663,7 @@ TEST_F(CommandBufferHelperTest, Noop) { TEST_F(CommandBufferHelperTest, IsContextLost) { EXPECT_FALSE(helper_->IsContextLost()); - command_buffer_->SetParseError(error::kGenericError); + command_buffer_->service()->SetParseError(error::kGenericError); EXPECT_TRUE(helper_->IsContextLost()); } diff --git a/chromium/gpu/command_buffer/client/context_support.h b/chromium/gpu/command_buffer/client/context_support.h index 53b33c8fee6..dc64d6e09eb 100644 --- a/chromium/gpu/command_buffer/client/context_support.h +++ b/chromium/gpu/command_buffer/client/context_support.h @@ -16,12 +16,22 @@ class Rect; class RectF; } +namespace ui { +class LatencyInfo; +} + namespace gpu { struct SyncToken; class ContextSupport { public: + // Returns the stream id for this context. + virtual int32_t GetStreamId() const = 0; + + // Flush any outstanding ordering barriers on given stream. + virtual void FlushOrderingBarrierOnStream(int32_t stream_id) = 0; + // Runs |callback| when the given sync token is signalled. The sync token may // belong to any context. virtual void SignalSyncToken(const SyncToken& sync_token, @@ -63,6 +73,11 @@ class ContextSupport { virtual void SetErrorMessageCallback( const base::Callback<void(const char*, int32_t)>& callback) = 0; + // Add |latency_info| to be reported and augumented with GPU latency + // components next time there is a GPU buffer swap. + virtual void AddLatencyInfo( + const std::vector<ui::LatencyInfo>& latency_info) = 0; + protected: ContextSupport() {} virtual ~ContextSupport() {} diff --git a/chromium/gpu/command_buffer/client/fenced_allocator_test.cc b/chromium/gpu/command_buffer/client/fenced_allocator_test.cc index 6590c179800..c19a0667271 100644 --- a/chromium/gpu/command_buffer/client/fenced_allocator_test.cc +++ b/chromium/gpu/command_buffer/client/fenced_allocator_test.cc @@ -11,12 +11,12 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/memory/aligned_memory.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" #include "gpu/command_buffer/client/fenced_allocator.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" -#include "gpu/command_buffer/service/command_buffer_service.h" -#include "gpu/command_buffer/service/command_executor.h" +#include "gpu/command_buffer/service/command_buffer_direct.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -48,22 +48,11 @@ class BaseFencedAllocatorTest : public testing::Test { .WillRepeatedly(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), Return(error::kNoError))); - { - TransferBufferManager* manager = new TransferBufferManager(nullptr); - transfer_buffer_manager_ = manager; - EXPECT_TRUE(manager->Initialize()); - } - command_buffer_.reset( - new CommandBufferService(transfer_buffer_manager_.get())); + transfer_buffer_manager_ = base::MakeUnique<TransferBufferManager>(nullptr); + command_buffer_.reset(new CommandBufferDirect( + transfer_buffer_manager_.get(), api_mock_.get())); - executor_.reset( - new CommandExecutor(command_buffer_.get(), api_mock_.get(), NULL)); - command_buffer_->SetPutOffsetChangeCallback(base::Bind( - &CommandExecutor::PutChanged, base::Unretained(executor_.get()))); - command_buffer_->SetGetBufferChangeCallback(base::Bind( - &CommandExecutor::SetGetBuffer, base::Unretained(executor_.get()))); - - api_mock_->set_engine(executor_.get()); + api_mock_->set_command_buffer_service(command_buffer_->service()); helper_.reset(new CommandBufferHelper(command_buffer_.get())); helper_->Initialize(kBufferSize); @@ -72,9 +61,8 @@ class BaseFencedAllocatorTest : public testing::Test { int32_t GetToken() { return command_buffer_->GetLastState().token; } std::unique_ptr<AsyncAPIMock> api_mock_; - scoped_refptr<TransferBufferManagerInterface> transfer_buffer_manager_; - std::unique_ptr<CommandBufferService> command_buffer_; - std::unique_ptr<CommandExecutor> executor_; + std::unique_ptr<TransferBufferManager> transfer_buffer_manager_; + std::unique_ptr<CommandBufferDirect> command_buffer_; std::unique_ptr<CommandBufferHelper> helper_; base::MessageLoop message_loop_; }; diff --git a/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h b/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h index b789a6be6d4..22759a38e94 100644 --- a/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -1415,6 +1415,13 @@ void GL_APIENTRY GLES2BindUniformLocationCHROMIUM(GLuint program, void GL_APIENTRY GLES2BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { gles2::GetGLContext()->BindTexImage2DCHROMIUM(target, imageId); } +void GL_APIENTRY +GLES2BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) { + gles2::GetGLContext()->BindTexImage2DWithInternalformatCHROMIUM( + target, internalformat, imageId); +} void GL_APIENTRY GLES2ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { gles2::GetGLContext()->ReleaseTexImage2DCHROMIUM(target, imageId); } @@ -1516,15 +1523,17 @@ GLES2ScheduleDCLayerSharedStateCHROMIUM(GLfloat opacity, gles2::GetGLContext()->ScheduleDCLayerSharedStateCHROMIUM( opacity, is_clipped, clip_rect, z_order, transform); } -void GL_APIENTRY GLES2ScheduleDCLayerCHROMIUM(GLuint contents_texture_id, - const GLfloat* contents_rect, - GLuint background_color, - GLuint edge_aa_mask, - const GLfloat* bounds_rect, - GLuint filter) { +void GL_APIENTRY +GLES2ScheduleDCLayerCHROMIUM(GLsizei num_textures, + const GLuint* contents_texture_ids, + const GLfloat* contents_rect, + GLuint background_color, + GLuint edge_aa_mask, + const GLfloat* bounds_rect, + GLuint filter) { gles2::GetGLContext()->ScheduleDCLayerCHROMIUM( - contents_texture_id, contents_rect, background_color, edge_aa_mask, - bounds_rect, filter); + num_textures, contents_texture_ids, contents_rect, background_color, + edge_aa_mask, bounds_rect, filter); } void GL_APIENTRY GLES2MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) { gles2::GetGLContext()->MatrixLoadfCHROMIUM(matrixMode, m); @@ -1748,6 +1757,15 @@ void GL_APIENTRY GLES2SetDrawRectangleCHROMIUM(GLint x, void GL_APIENTRY GLES2SetEnableDCLayersCHROMIUM(GLboolean enabled) { gles2::GetGLContext()->SetEnableDCLayersCHROMIUM(enabled); } +void GL_APIENTRY GLES2InitializeDiscardableTextureCHROMIUM(GLuint texture_id) { + gles2::GetGLContext()->InitializeDiscardableTextureCHROMIUM(texture_id); +} +void GL_APIENTRY GLES2UnlockDiscardableTextureCHROMIUM(GLuint texture_id) { + gles2::GetGLContext()->UnlockDiscardableTextureCHROMIUM(texture_id); +} +bool GL_APIENTRY GLES2LockDiscardableTextureCHROMIUM(GLuint texture_id) { + return gles2::GetGLContext()->LockDiscardableTextureCHROMIUM(texture_id); +} namespace gles2 { @@ -2819,6 +2837,11 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glBindTexImage2DCHROMIUM), }, { + "glBindTexImage2DWithInternalformatCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>( + glBindTexImage2DWithInternalformatCHROMIUM), + }, + { "glReleaseTexImage2DCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glReleaseTexImage2DCHROMIUM), }, @@ -3068,6 +3091,21 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glSetEnableDCLayersCHROMIUM), }, { + "glInitializeDiscardableTextureCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>( + glInitializeDiscardableTextureCHROMIUM), + }, + { + "glUnlockDiscardableTextureCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>( + glUnlockDiscardableTextureCHROMIUM), + }, + { + "glLockDiscardableTextureCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>( + glLockDiscardableTextureCHROMIUM), + }, + { NULL, NULL, }, }; diff --git a/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 834b474f6e2..77d259db84c 100644 --- a/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -2651,6 +2651,16 @@ void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { } } +void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) { + gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM* c = + GetCmdSpace<gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM>(); + if (c) { + c->Init(target, internalformat, imageId); + } +} + void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { gles2::cmds::ReleaseTexImage2DCHROMIUM* c = GetCmdSpace<gles2::cmds::ReleaseTexImage2DCHROMIUM>(); @@ -2826,7 +2836,7 @@ void ScheduleDCLayerSharedStateCHROMIUM(GLfloat opacity, } } -void ScheduleDCLayerCHROMIUM(GLuint contents_texture_id, +void ScheduleDCLayerCHROMIUM(GLsizei num_textures, GLuint background_color, GLuint edge_aa_mask, GLuint filter, @@ -2835,7 +2845,7 @@ void ScheduleDCLayerCHROMIUM(GLuint contents_texture_id, gles2::cmds::ScheduleDCLayerCHROMIUM* c = GetCmdSpace<gles2::cmds::ScheduleDCLayerCHROMIUM>(); if (c) { - c->Init(contents_texture_id, background_color, edge_aa_mask, filter, shm_id, + c->Init(num_textures, background_color, edge_aa_mask, filter, shm_id, shm_offset); } } @@ -3238,4 +3248,30 @@ void SetEnableDCLayersCHROMIUM(GLboolean enabled) { } } +void InitializeDiscardableTextureCHROMIUM(GLuint texture_id, + uint32_t shm_id, + uint32_t shm_offset) { + gles2::cmds::InitializeDiscardableTextureCHROMIUM* c = + GetCmdSpace<gles2::cmds::InitializeDiscardableTextureCHROMIUM>(); + if (c) { + c->Init(texture_id, shm_id, shm_offset); + } +} + +void UnlockDiscardableTextureCHROMIUM(GLuint texture_id) { + gles2::cmds::UnlockDiscardableTextureCHROMIUM* c = + GetCmdSpace<gles2::cmds::UnlockDiscardableTextureCHROMIUM>(); + if (c) { + c->Init(texture_id); + } +} + +void LockDiscardableTextureCHROMIUM(GLuint texture_id) { + gles2::cmds::LockDiscardableTextureCHROMIUM* c = + GetCmdSpace<gles2::cmds::LockDiscardableTextureCHROMIUM>(); + if (c) { + c->Init(texture_id); + } +} + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_implementation.cc b/chromium/gpu/command_buffer/client/gles2_implementation.cc index fde1339e7f5..38975cc581b 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation.cc +++ b/chromium/gpu/command_buffer/client/gles2_implementation.cc @@ -245,10 +245,13 @@ bool GLES2Implementation::Initialize( query_tracker_.reset(new QueryTracker(mapped_memory_.get())); buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); - query_id_allocator_.reset(new IdAllocator()); + for (int i = 0; i < static_cast<int>(IdNamespaces::kNumIdNamespaces); ++i) + id_allocators_[i].reset(new IdAllocator()); + if (support_client_side_arrays_) { - GetIdHandler(id_namespaces::kBuffers)->MakeIds( - this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); + GetIdHandler(SharedIdNamespaces::kBuffers) + ->MakeIds(this, kClientSideArrayId, arraysize(reserved_ids_), + &reserved_ids_[0]); } vertex_array_object_manager_.reset(new VertexArrayObjectManager( @@ -303,7 +306,8 @@ GLES2CmdHelper* GLES2Implementation::helper() const { return helper_; } -IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { +IdHandlerInterface* GLES2Implementation::GetIdHandler( + SharedIdNamespaces namespace_id) const { return share_group_->GetIdHandler(namespace_id); } @@ -312,11 +316,9 @@ RangeIdHandlerInterface* GLES2Implementation::GetRangeIdHandler( return share_group_->GetRangeIdHandler(namespace_id); } -IdAllocator* GLES2Implementation::GetIdAllocator(int namespace_id) const { - if (namespace_id == id_namespaces::kQueries) - return query_id_allocator_.get(); - NOTREACHED(); - return NULL; +IdAllocator* GLES2Implementation::GetIdAllocator( + IdNamespaces namespace_id) const { + return id_allocators_[static_cast<int>(namespace_id)].get(); } void GLES2Implementation::OnGpuControlLostContext() { @@ -374,6 +376,14 @@ void GLES2Implementation::RunIfContextNotLost(const base::Closure& callback) { callback.Run(); } +int32_t GLES2Implementation::GetStreamId() const { + return gpu_control_->GetStreamId(); +} + +void GLES2Implementation::FlushOrderingBarrierOnStream(int32_t stream_id) { + gpu_control_->FlushOrderingBarrierOnStream(stream_id); +} + void GLES2Implementation::SignalSyncToken(const gpu::SyncToken& sync_token, const base::Closure& callback) { SyncToken verified_sync_token; @@ -1597,8 +1607,9 @@ void GLES2Implementation::GetVertexAttribPointerv( } bool GLES2Implementation::DeleteProgramHelper(GLuint program) { - if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds( - this, 1, &program, &GLES2Implementation::DeleteProgramStub)) { + if (!GetIdHandler(SharedIdNamespaces::kProgramsAndShaders) + ->FreeIds(this, 1, &program, + &GLES2Implementation::DeleteProgramStub)) { SetGLError( GL_INVALID_VALUE, "glDeleteProgram", "id not created by this context."); @@ -1618,8 +1629,9 @@ void GLES2Implementation::DeleteProgramStub( } bool GLES2Implementation::DeleteShaderHelper(GLuint shader) { - if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds( - this, 1, &shader, &GLES2Implementation::DeleteShaderStub)) { + if (!GetIdHandler(SharedIdNamespaces::kProgramsAndShaders) + ->FreeIds(this, 1, &shader, + &GLES2Implementation::DeleteShaderStub)) { SetGLError( GL_INVALID_VALUE, "glDeleteShader", "id not created by this context."); @@ -1637,8 +1649,9 @@ void GLES2Implementation::DeleteShaderStub( void GLES2Implementation::DeleteSyncHelper(GLsync sync) { GLuint sync_uint = ToGLuint(sync); - if (!GetIdHandler(id_namespaces::kSyncs)->FreeIds( - this, 1, &sync_uint, &GLES2Implementation::DeleteSyncStub)) { + if (!GetIdHandler(SharedIdNamespaces::kSyncs) + ->FreeIds(this, 1, &sync_uint, + &GLES2Implementation::DeleteSyncStub)) { SetGLError( GL_INVALID_VALUE, "glDeleteSync", "id not created by this context."); @@ -4291,8 +4304,9 @@ void GLES2Implementation::BindBufferHelper( } // TODO(gman): See note #2 above. if (changed) { - GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( - this, target, buffer_id, &GLES2Implementation::BindBufferStub); + GetIdHandler(SharedIdNamespaces::kBuffers) + ->MarkAsUsedForBind(this, target, buffer_id, + &GLES2Implementation::BindBufferStub); } } @@ -4334,8 +4348,9 @@ void GLES2Implementation::BindBufferBaseHelper( SetGLError(GL_INVALID_ENUM, "glBindBufferBase", "invalid target"); return; } - GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( - this, target, index, buffer_id, &GLES2Implementation::BindBufferBaseStub); + GetIdHandler(SharedIdNamespaces::kBuffers) + ->MarkAsUsedForBind(this, target, index, buffer_id, + &GLES2Implementation::BindBufferBaseStub); } void GLES2Implementation::BindBufferBaseStub( @@ -4350,9 +4365,9 @@ void GLES2Implementation::BindBufferRangeHelper( GLintptr offset, GLsizeiptr size) { // TODO(zmo): See note #1 above. // TODO(zmo): See note #2 above. - GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( - this, target, index, buffer_id, offset, size, - &GLES2Implementation::BindBufferRangeStub); + GetIdHandler(SharedIdNamespaces::kBuffers) + ->MarkAsUsedForBind(this, target, index, buffer_id, offset, size, + &GLES2Implementation::BindBufferRangeStub); } void GLES2Implementation::BindBufferRangeStub( @@ -4398,18 +4413,12 @@ void GLES2Implementation::BindFramebufferHelper( } if (changed) { - GetIdHandler(id_namespaces::kFramebuffers)->MarkAsUsedForBind( - this, target, framebuffer, &GLES2Implementation::BindFramebufferStub); + if (framebuffer != 0) + GetIdAllocator(IdNamespaces::kFramebuffers)->MarkAsUsed(framebuffer); + helper_->BindFramebuffer(target, framebuffer); } } -void GLES2Implementation::BindFramebufferStub(GLenum target, - GLuint framebuffer) { - helper_->BindFramebuffer(target, framebuffer); - if (share_group_->bind_generates_resource()) - helper_->CommandBufferHelper::OrderingBarrier(); -} - void GLES2Implementation::BindRenderbufferHelper( GLenum target, GLuint renderbuffer) { // TODO(gman): See note #1 above. @@ -4427,9 +4436,9 @@ void GLES2Implementation::BindRenderbufferHelper( } // TODO(zmo): See note #2 above. if (changed) { - GetIdHandler(id_namespaces::kRenderbuffers)->MarkAsUsedForBind( - this, target, renderbuffer, - &GLES2Implementation::BindRenderbufferStub); + GetIdHandler(SharedIdNamespaces::kRenderbuffers) + ->MarkAsUsedForBind(this, target, renderbuffer, + &GLES2Implementation::BindRenderbufferStub); } } @@ -4476,8 +4485,9 @@ void GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) { } // TODO(gman): See note #2 above. if (changed) { - GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind( - this, target, texture, &GLES2Implementation::BindTextureStub); + GetIdHandler(SharedIdNamespaces::kTextures) + ->MarkAsUsedForBind(this, target, texture, + &GLES2Implementation::BindTextureStub); } } @@ -4522,8 +4532,9 @@ bool GLES2Implementation::IsBufferReservedId(GLuint id) { void GLES2Implementation::DeleteBuffersHelper( GLsizei n, const GLuint* buffers) { - if (!GetIdHandler(id_namespaces::kBuffers)->FreeIds( - this, n, buffers, &GLES2Implementation::DeleteBuffersStub)) { + if (!GetIdHandler(SharedIdNamespaces::kBuffers) + ->FreeIds(this, n, buffers, + &GLES2Implementation::DeleteBuffersStub)) { SetGLError( GL_INVALID_VALUE, "glDeleteBuffers", "id not created by this context."); @@ -4573,14 +4584,10 @@ void GLES2Implementation::DeleteBuffersStub( void GLES2Implementation::DeleteFramebuffersHelper( GLsizei n, const GLuint* framebuffers) { - if (!GetIdHandler(id_namespaces::kFramebuffers)->FreeIds( - this, n, framebuffers, &GLES2Implementation::DeleteFramebuffersStub)) { - SetGLError( - GL_INVALID_VALUE, - "glDeleteFramebuffers", "id not created by this context."); - return; - } + helper_->DeleteFramebuffersImmediate(n, framebuffers); + IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kFramebuffers); for (GLsizei ii = 0; ii < n; ++ii) { + id_allocator->FreeID(framebuffers[ii]); if (framebuffers[ii] == bound_framebuffer_) { bound_framebuffer_ = 0; } @@ -4590,15 +4597,11 @@ void GLES2Implementation::DeleteFramebuffersHelper( } } -void GLES2Implementation::DeleteFramebuffersStub( - GLsizei n, const GLuint* framebuffers) { - helper_->DeleteFramebuffersImmediate(n, framebuffers); -} - void GLES2Implementation::DeleteRenderbuffersHelper( GLsizei n, const GLuint* renderbuffers) { - if (!GetIdHandler(id_namespaces::kRenderbuffers)->FreeIds( - this, n, renderbuffers, &GLES2Implementation::DeleteRenderbuffersStub)) { + if (!GetIdHandler(SharedIdNamespaces::kRenderbuffers) + ->FreeIds(this, n, renderbuffers, + &GLES2Implementation::DeleteRenderbuffersStub)) { SetGLError( GL_INVALID_VALUE, "glDeleteRenderbuffers", "id not created by this context."); @@ -4618,14 +4621,17 @@ void GLES2Implementation::DeleteRenderbuffersStub( void GLES2Implementation::DeleteTexturesHelper( GLsizei n, const GLuint* textures) { - if (!GetIdHandler(id_namespaces::kTextures)->FreeIds( - this, n, textures, &GLES2Implementation::DeleteTexturesStub)) { + if (!GetIdHandler(SharedIdNamespaces::kTextures) + ->FreeIds(this, n, textures, + &GLES2Implementation::DeleteTexturesStub)) { SetGLError( GL_INVALID_VALUE, "glDeleteTextures", "id not created by this context."); return; } for (GLsizei ii = 0; ii < n; ++ii) { + share_group_->discardable_manager()->FreeTexture(textures[ii]); + for (GLint tt = 0; tt < capabilities_.max_combined_texture_image_units; ++tt) { TextureUnit& unit = texture_units_[tt]; @@ -4650,18 +4656,10 @@ void GLES2Implementation::DeleteTexturesStub(GLsizei n, void GLES2Implementation::DeleteVertexArraysOESHelper( GLsizei n, const GLuint* arrays) { vertex_array_object_manager_->DeleteVertexArrays(n, arrays); - if (!GetIdHandler(id_namespaces::kVertexArrays)->FreeIds( - this, n, arrays, &GLES2Implementation::DeleteVertexArraysOESStub)) { - SetGLError( - GL_INVALID_VALUE, - "glDeleteVertexArraysOES", "id not created by this context."); - return; - } -} - -void GLES2Implementation::DeleteVertexArraysOESStub( - GLsizei n, const GLuint* arrays) { helper_->DeleteVertexArraysOESImmediate(n, arrays); + IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kVertexArrays); + for (GLsizei ii = 0; ii < n; ++ii) + id_allocator->FreeID(arrays[ii]); } void GLES2Implementation::DeleteSamplersStub( @@ -4671,8 +4669,9 @@ void GLES2Implementation::DeleteSamplersStub( void GLES2Implementation::DeleteSamplersHelper( GLsizei n, const GLuint* samplers) { - if (!GetIdHandler(id_namespaces::kSamplers)->FreeIds( - this, n, samplers, &GLES2Implementation::DeleteSamplersStub)) { + if (!GetIdHandler(SharedIdNamespaces::kSamplers) + ->FreeIds(this, n, samplers, + &GLES2Implementation::DeleteSamplersStub)) { SetGLError( GL_INVALID_VALUE, "glDeleteSamplers", "id not created by this context."); @@ -4680,21 +4679,12 @@ void GLES2Implementation::DeleteSamplersHelper( } } -void GLES2Implementation::DeleteTransformFeedbacksStub( - GLsizei n, const GLuint* transformfeedbacks) { - helper_->DeleteTransformFeedbacksImmediate(n, transformfeedbacks); -} - void GLES2Implementation::DeleteTransformFeedbacksHelper( GLsizei n, const GLuint* transformfeedbacks) { - if (!GetIdHandler(id_namespaces::kTransformFeedbacks)->FreeIds( - this, n, transformfeedbacks, - &GLES2Implementation::DeleteTransformFeedbacksStub)) { - SetGLError( - GL_INVALID_VALUE, - "glDeleteTransformFeedbacks", "id not created by this context."); - return; - } + helper_->DeleteTransformFeedbacksImmediate(n, transformfeedbacks); + IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kTransformFeedbacks); + for (GLsizei ii = 0; ii < n; ++ii) + id_allocator->FreeID(transformfeedbacks[ii]); } void GLES2Implementation::DisableVertexAttribArray(GLuint index) { @@ -4998,13 +4988,17 @@ void GLES2Implementation::ScheduleDCLayerSharedStateCHROMIUM( buffer.shm_id(), buffer.offset()); } -void GLES2Implementation::ScheduleDCLayerCHROMIUM(GLuint contents_texture_id, - const GLfloat* contents_rect, - GLuint background_color, - GLuint edge_aa_mask, - const GLfloat* bounds_rect, - GLuint filter) { - size_t shm_size = 8 * sizeof(GLfloat); +void GLES2Implementation::ScheduleDCLayerCHROMIUM( + GLsizei num_textures, + const GLuint* contents_texture_ids, + const GLfloat* contents_rect, + GLuint background_color, + GLuint edge_aa_mask, + const GLfloat* bounds_rect, + GLuint filter) { + const size_t kRectsSize = 8 * sizeof(GLfloat); + size_t textures_size = num_textures * sizeof(GLuint); + size_t shm_size = kRectsSize + textures_size; ScopedTransferBufferPtr buffer(shm_size, helper_, transfer_buffer_); if (!buffer.valid() || buffer.size() < shm_size) { SetGLError(GL_OUT_OF_MEMORY, "GLES2::ScheduleDCLayerCHROMIUM", @@ -5014,9 +5008,10 @@ void GLES2Implementation::ScheduleDCLayerCHROMIUM(GLuint contents_texture_id, GLfloat* mem = static_cast<GLfloat*>(buffer.address()); memcpy(mem + 0, contents_rect, 4 * sizeof(GLfloat)); memcpy(mem + 4, bounds_rect, 4 * sizeof(GLfloat)); - helper_->ScheduleDCLayerCHROMIUM(contents_texture_id, background_color, - edge_aa_mask, filter, buffer.shm_id(), - buffer.offset()); + memcpy(static_cast<char*>(buffer.address()) + kRectsSize, + contents_texture_ids, textures_size); + helper_->ScheduleDCLayerCHROMIUM(num_textures, background_color, edge_aa_mask, + filter, buffer.shm_id(), buffer.offset()); } void GLES2Implementation::CommitOverlayPlanesCHROMIUM() { @@ -5566,9 +5561,10 @@ void GLES2Implementation::PostSubBufferCHROMIUM( void GLES2Implementation::DeleteQueriesEXTHelper( GLsizei n, const GLuint* queries) { + IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kQueries); for (GLsizei ii = 0; ii < n; ++ii) { query_tracker_->RemoveQuery(queries[ii]); - query_id_allocator_->FreeID(queries[ii]); + id_allocator->FreeID(queries[ii]); } helper_->DeleteQueriesEXTImmediate(n, queries); @@ -5651,7 +5647,7 @@ void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) { return; } - if (!query_id_allocator_->InUse(id)) { + if (!GetIdAllocator(IdNamespaces::kQueries)->InUse(id)) { SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "invalid id"); return; } @@ -5708,7 +5704,7 @@ void GLES2Implementation::QueryCounterEXT(GLuint id, GLenum target) { return; } - if (!query_id_allocator_->InUse(id)) { + if (!GetIdAllocator(IdNamespaces::kQueries)->InUse(id)) { SetGLError(GL_INVALID_OPERATION, "glQueryCounterEXT", "invalid id"); return; } @@ -5932,7 +5928,7 @@ GLuint GLES2Implementation::CreateAndConsumeTextureCHROMIUM( "mailbox that was not generated by " "GenMailboxCHROMIUM."; GLuint client_id; - GetIdHandler(id_namespaces::kTextures)->MakeIds(this, 0, 1, &client_id); + GetIdHandler(SharedIdNamespaces::kTextures)->MakeIds(this, 0, 1, &client_id); helper_->CreateAndConsumeTextureINTERNALImmediate(target, client_id, data); if (share_group_->bind_generates_resource()) @@ -6083,6 +6079,11 @@ void GLES2Implementation::SetErrorMessageCallback( error_message_callback_ = callback; } +void GLES2Implementation::AddLatencyInfo( + const std::vector<ui::LatencyInfo>& latency_info) { + gpu_control_->AddLatencyInfo(latency_info); +} + void GLES2Implementation::SetLostContextCallback( const base::Closure& callback) { lost_context_callback_ = callback; @@ -6111,7 +6112,7 @@ void GLES2Implementation::GenSyncTokenCHROMIUM(GLuint64 fence_sync, // Copy the data over after setting the data to ensure alignment. SyncToken sync_token_data(gpu_control_->GetNamespaceID(), - gpu_control_->GetExtraCommandBufferData(), + gpu_control_->GetStreamId(), gpu_control_->GetCommandBufferID(), fence_sync); sync_token_data.SetVerifyFlush(); memcpy(sync_token, &sync_token_data, sizeof(sync_token_data)); @@ -6135,7 +6136,7 @@ void GLES2Implementation::GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, // Copy the data over after setting the data to ensure alignment. SyncToken sync_token_data(gpu_control_->GetNamespaceID(), - gpu_control_->GetExtraCommandBufferData(), + gpu_control_->GetStreamId(), gpu_control_->GetCommandBufferID(), fence_sync); memcpy(sync_token, &sync_token_data, sizeof(sync_token_data)); } @@ -7039,6 +7040,47 @@ void GLES2Implementation::ProgramPathFragmentInputGenCHROMIUM( CheckGLError(); } +void GLES2Implementation::InitializeDiscardableTextureCHROMIUM( + GLuint texture_id) { + ClientDiscardableManager* manager = share_group()->discardable_manager(); + if (manager->TextureIsValid(texture_id)) { + SetGLError(GL_INVALID_VALUE, "glInitializeDiscardableTextureCHROMIUM", + "Texture ID already initialized"); + return; + } + ClientDiscardableHandle handle = + manager->InitializeTexture(helper_->command_buffer(), texture_id); + helper_->InitializeDiscardableTextureCHROMIUM(texture_id, handle.shm_id(), + handle.byte_offset()); +} + +void GLES2Implementation::UnlockDiscardableTextureCHROMIUM(GLuint texture_id) { + ClientDiscardableManager* manager = share_group()->discardable_manager(); + if (!manager->TextureIsValid(texture_id)) { + SetGLError(GL_INVALID_VALUE, "glUnlockDiscardableTextureCHROMIUM", + "Texture ID not initialized"); + return; + } + helper_->UnlockDiscardableTextureCHROMIUM(texture_id); +} + +bool GLES2Implementation::LockDiscardableTextureCHROMIUM(GLuint texture_id) { + ClientDiscardableManager* manager = share_group()->discardable_manager(); + if (!manager->TextureIsValid(texture_id)) { + SetGLError(GL_INVALID_VALUE, "glLockDiscardableTextureCHROMIUM", + "Texture ID not initialized"); + return false; + } + if (!manager->LockTexture(texture_id)) { + // Failure to lock means that this texture has been deleted on the service + // side. Delete it here as well. + DeleteTexturesHelper(1, &texture_id); + return false; + } + helper_->LockDiscardableTextureCHROMIUM(texture_id); + return true; +} + void GLES2Implementation::UpdateCachedExtensionsIfNeeded() { if (cached_extension_string_) { return; diff --git a/chromium/gpu/command_buffer/client/gles2_implementation.h b/chromium/gpu/command_buffer/client/gles2_implementation.h index 25bbd9eb668..d86b16012a0 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation.h @@ -34,7 +34,8 @@ #include "gpu/command_buffer/common/debug_marker_manager.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#if !defined(NDEBUG) && !defined(__native_client__) && !defined(GLES2_CONFORMANCE_TESTS) // NOLINT +#if DCHECK_IS_ON() && !defined(__native_client__) && \ + !defined(GLES2_CONFORMANCE_TESTS) #if defined(GLES2_INLINE_OPTIMIZATION) // TODO(gman): Replace with macros that work with inline optmization. #define GPU_CLIENT_SINGLE_THREAD_CHECK() @@ -182,12 +183,22 @@ class GLES2_IMPL_EXPORT GLES2Implementation // Gets client side generated errors. GLenum GetClientSideGLError(); + // GLES2Interface implementation + void FreeSharedMemory(void*) override; + // Include the auto-generated part of this class. 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. #include "gpu/command_buffer/client/gles2_implementation_autogen.h" // ContextSupport implementation. + int32_t GetStreamId() const override; + void FlushOrderingBarrierOnStream(int32_t stream_id) override; + void SignalSyncToken(const gpu::SyncToken& sync_token, + const base::Closure& callback) override; + bool IsSyncTokenSignaled(const gpu::SyncToken& sync_token) override; + void SignalQuery(uint32_t query, const base::Closure& callback) override; + void SetAggressivelyFreeResources(bool aggressively_free_resources) override; void Swap() override; void SwapWithBounds(const std::vector<gfx::Rect>& rects) override; void PartialSwapBuffers(const gfx::Rect& sub_buffer) override; @@ -200,6 +211,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation uint64_t ShareGroupTracingGUID() const override; void SetErrorMessageCallback( const base::Callback<void(const char*, int32_t)>& callback) override; + void AddLatencyInfo( + const std::vector<ui::LatencyInfo>& latency_info) override; // TODO(danakj): Move to ContextSupport once ContextProvider doesn't need to // intercept it. @@ -246,15 +259,6 @@ class GLES2_IMPL_EXPORT GLES2Implementation void FreeUnusedSharedMemory(); void FreeEverything(); - void FreeSharedMemory(void*) override; - - // ContextSupport implementation. - void SignalSyncToken(const gpu::SyncToken& sync_token, - const base::Closure& callback) override; - bool IsSyncTokenSignaled(const gpu::SyncToken& sync_token) override; - void SignalQuery(uint32_t query, const base::Closure& callback) override; - void SetAggressivelyFreeResources(bool aggressively_free_resources) override; - // Helper to set verified bit on sync token if allowed by gpu control. bool GetVerifiedSyncTokenForIPC(const gpu::SyncToken& sync_token, gpu::SyncToken* verified_sync_token); @@ -282,6 +286,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation friend class VertexArrayObjectManager; friend class QueryTracker; + using IdNamespaces = id_namespaces::IdNamespaces; + // Used to track whether an extension is available enum ExtensionStatus { kAvailableExtensionStatus, @@ -486,7 +492,6 @@ class GLES2_IMPL_EXPORT GLES2Implementation void BindBufferBaseStub(GLenum target, GLuint index, GLuint buffer); void BindBufferRangeStub(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); - void BindFramebufferStub(GLenum target, GLuint framebuffer); void BindRenderbufferStub(GLenum target, GLuint renderbuffer); void BindTextureStub(GLenum target, GLuint texture); @@ -513,16 +518,12 @@ class GLES2_IMPL_EXPORT GLES2Implementation void DeleteSyncHelper(GLsync sync); void DeleteBuffersStub(GLsizei n, const GLuint* buffers); - void DeleteFramebuffersStub(GLsizei n, const GLuint* framebuffers); void DeleteRenderbuffersStub(GLsizei n, const GLuint* renderbuffers); void DeleteTexturesStub(GLsizei n, const GLuint* textures); void DeletePathsCHROMIUMStub(GLuint first_client_id, GLsizei range); void DeleteProgramStub(GLsizei n, const GLuint* programs); void DeleteShaderStub(GLsizei n, const GLuint* shaders); - void DeleteVertexArraysOESStub(GLsizei n, const GLuint* arrays); void DeleteSamplersStub(GLsizei n, const GLuint* samplers); - void DeleteTransformFeedbacksStub( - GLsizei n, const GLuint* transformfeedbacks); void DeleteSyncStub(GLsizei n, const GLuint* syncs); void BufferDataHelper( @@ -617,12 +618,10 @@ class GLES2_IMPL_EXPORT GLES2Implementation // Caches certain capabilties state. Return true if cached. bool SetCapabilityState(GLenum cap, bool enabled); - IdHandlerInterface* GetIdHandler(int id_namespace) const; + IdHandlerInterface* GetIdHandler(SharedIdNamespaces id_namespace) const; RangeIdHandlerInterface* GetRangeIdHandler(int id_namespace) const; // IdAllocators for objects that can't be shared among contexts. - // For now, used only for Queries. TODO(hj.r.chung) Should be added for - // Framebuffer and Vertex array objects. - IdAllocator* GetIdAllocator(int id_namespace) const; + IdAllocator* GetIdAllocator(IdNamespaces id_namespace) const; void FinishHelper(); void FlushHelper(); @@ -807,7 +806,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation ShareGroupContextData share_group_context_data_; std::unique_ptr<QueryTracker> query_tracker_; - std::unique_ptr<IdAllocator> query_id_allocator_; + std::unique_ptr<IdAllocator> + id_allocators_[static_cast<int>(IdNamespaces::kNumIdNamespaces)]; std::unique_ptr<BufferTracker> buffer_tracker_; diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h b/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h index ee5230112de..c868c2c90de 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -996,6 +996,10 @@ void BindUniformLocationCHROMIUM(GLuint program, void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override; +void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) override; + void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override; void TraceBeginCHROMIUM(const char* category_name, @@ -1066,7 +1070,8 @@ void ScheduleDCLayerSharedStateCHROMIUM(GLfloat opacity, GLint z_order, const GLfloat* transform) override; -void ScheduleDCLayerCHROMIUM(GLuint contents_texture_id, +void ScheduleDCLayerCHROMIUM(GLsizei num_textures, + const GLuint* contents_texture_ids, const GLfloat* contents_rect, GLuint background_color, GLuint edge_aa_mask, @@ -1227,4 +1232,10 @@ void SetDrawRectangleCHROMIUM(GLint x, void SetEnableDCLayersCHROMIUM(GLboolean enabled) override; +void InitializeDiscardableTextureCHROMIUM(GLuint texture_id) override; + +void UnlockDiscardableTextureCHROMIUM(GLuint texture_id) override; + +bool LockDiscardableTextureCHROMIUM(GLuint texture_id) override; + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index db5d667d606..2be26ed3e2d 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation_impl_autogen.h @@ -446,7 +446,7 @@ GLuint GLES2Implementation::CreateProgram() { GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateProgram(" << ")"); GLuint client_id; - GetIdHandler(id_namespaces::kProgramsAndShaders) + GetIdHandler(SharedIdNamespaces::kProgramsAndShaders) ->MakeIds(this, 0, 1, &client_id); helper_->CreateProgram(client_id); GPU_CLIENT_LOG("returned " << client_id); @@ -459,7 +459,7 @@ GLuint GLES2Implementation::CreateShader(GLenum type) { GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateShader(" << GLES2Util::GetStringShaderType(type) << ")"); GLuint client_id; - GetIdHandler(id_namespaces::kProgramsAndShaders) + GetIdHandler(SharedIdNamespaces::kProgramsAndShaders) ->MakeIds(this, 0, 1, &client_id); helper_->CreateShader(type, client_id); GPU_CLIENT_LOG("returned " << client_id); @@ -681,7 +681,7 @@ GLsync GLES2Implementation::FenceSync(GLenum condition, GLbitfield flags) { return 0; } GLuint client_id; - GetIdHandler(id_namespaces::kSyncs)->MakeIds(this, 0, 1, &client_id); + GetIdHandler(SharedIdNamespaces::kSyncs)->MakeIds(this, 0, 1, &client_id); helper_->FenceSync(client_id); GPU_CLIENT_LOG("returned " << client_id); CheckGLError(); @@ -749,7 +749,7 @@ void GLES2Implementation::GenBuffers(GLsizei n, GLuint* buffers) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - GetIdHandler(id_namespaces::kBuffers)->MakeIds(this, 0, n, buffers); + GetIdHandler(SharedIdNamespaces::kBuffers)->MakeIds(this, 0, n, buffers); GenBuffersHelper(n, buffers); helper_->GenBuffersImmediate(n, buffers); if (share_group_->bind_generates_resource()) @@ -778,11 +778,11 @@ void GLES2Implementation::GenFramebuffers(GLsizei n, GLuint* framebuffers) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - GetIdHandler(id_namespaces::kFramebuffers)->MakeIds(this, 0, n, framebuffers); + IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kFramebuffers); + for (GLsizei ii = 0; ii < n; ++ii) + framebuffers[ii] = id_allocator->AllocateID(); GenFramebuffersHelper(n, framebuffers); helper_->GenFramebuffersImmediate(n, framebuffers); - if (share_group_->bind_generates_resource()) - helper_->CommandBufferHelper::Flush(); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { GPU_CLIENT_LOG(" " << i << ": " << framebuffers[i]); @@ -799,7 +799,7 @@ void GLES2Implementation::GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - GetIdHandler(id_namespaces::kRenderbuffers) + GetIdHandler(SharedIdNamespaces::kRenderbuffers) ->MakeIds(this, 0, n, renderbuffers); GenRenderbuffersHelper(n, renderbuffers); helper_->GenRenderbuffersImmediate(n, renderbuffers); @@ -821,7 +821,7 @@ void GLES2Implementation::GenSamplers(GLsizei n, GLuint* samplers) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - GetIdHandler(id_namespaces::kSamplers)->MakeIds(this, 0, n, samplers); + GetIdHandler(SharedIdNamespaces::kSamplers)->MakeIds(this, 0, n, samplers); GenSamplersHelper(n, samplers); helper_->GenSamplersImmediate(n, samplers); if (share_group_->bind_generates_resource()) @@ -842,7 +842,7 @@ void GLES2Implementation::GenTextures(GLsizei n, GLuint* textures) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - GetIdHandler(id_namespaces::kTextures)->MakeIds(this, 0, n, textures); + GetIdHandler(SharedIdNamespaces::kTextures)->MakeIds(this, 0, n, textures); GenTexturesHelper(n, textures); helper_->GenTexturesImmediate(n, textures); if (share_group_->bind_generates_resource()) @@ -863,11 +863,11 @@ void GLES2Implementation::GenTransformFeedbacks(GLsizei n, GLuint* ids) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - GetIdHandler(id_namespaces::kTransformFeedbacks)->MakeIds(this, 0, n, ids); + IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kTransformFeedbacks); + for (GLsizei ii = 0; ii < n; ++ii) + ids[ii] = id_allocator->AllocateID(); GenTransformFeedbacksHelper(n, ids); helper_->GenTransformFeedbacksImmediate(n, ids); - if (share_group_->bind_generates_resource()) - helper_->CommandBufferHelper::Flush(); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { GPU_CLIENT_LOG(" " << i << ": " << ids[i]); @@ -2926,13 +2926,11 @@ void GLES2Implementation::GenQueriesEXT(GLsizei n, GLuint* queries) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - IdAllocator* id_allocator = GetIdAllocator(id_namespaces::kQueries); + IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kQueries); for (GLsizei ii = 0; ii < n; ++ii) queries[ii] = id_allocator->AllocateID(); GenQueriesEXTHelper(n, queries); helper_->GenQueriesEXTImmediate(n, queries); - if (share_group_->bind_generates_resource()) - helper_->CommandBufferHelper::Flush(); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { GPU_CLIENT_LOG(" " << i << ": " << queries[i]); @@ -2989,11 +2987,11 @@ void GLES2Implementation::GenVertexArraysOES(GLsizei n, GLuint* arrays) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - GetIdHandler(id_namespaces::kVertexArrays)->MakeIds(this, 0, n, arrays); + IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kVertexArrays); + for (GLsizei ii = 0; ii < n; ++ii) + arrays[ii] = id_allocator->AllocateID(); GenVertexArraysOESHelper(n, arrays); helper_->GenVertexArraysOESImmediate(n, arrays); - if (share_group_->bind_generates_resource()) - helper_->CommandBufferHelper::Flush(); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { GPU_CLIENT_LOG(" " << i << ": " << arrays[i]); @@ -3195,6 +3193,21 @@ void GLES2Implementation::BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { CheckGLError(); } +void GLES2Implementation::BindTexImage2DWithInternalformatCHROMIUM( + GLenum target, + GLenum internalformat, + GLint imageId) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() + << "] glBindTexImage2DWithInternalformatCHROMIUM(" + << GLES2Util::GetStringTextureBindTarget(target) << ", " + << GLES2Util::GetStringEnum(internalformat) << ", " + << imageId << ")"); + helper_->BindTexImage2DWithInternalformatCHROMIUM(target, internalformat, + imageId); + CheckGLError(); +} + void GLES2Implementation::ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { GPU_CLIENT_SINGLE_THREAD_CHECK(); diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc b/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc index f193dc55445..20c2508b60c 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/chromium/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -343,20 +343,6 @@ class GenBuffersAPI { } }; -// API wrapper for Framebuffers. -class GenFramebuffersAPI { - public: - static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) { - gl_impl->GenFramebuffers(n, ids); - } - - static void Delete(GLES2Implementation* gl_impl, - GLsizei n, - const GLuint* ids) { - gl_impl->DeleteFramebuffers(n, ids); - } -}; - // API wrapper for Renderbuffers. class GenRenderbuffersAPI { public: @@ -512,7 +498,7 @@ class GLES2ImplementationTest : public testing::Test { scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer(); commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) + - command_buffer()->GetPutOffset(); + command_buffer()->GetServicePutOffset(); ClearCommands(); EXPECT_TRUE(transfer_buffer_->InSync()); @@ -3148,9 +3134,6 @@ TEST_F(GLES2ImplementationTest, TexSubImage3D4Writes) { TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) { FlushGenerationTest<GenBuffersAPI>(); } -TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestFramebuffers) { - FlushGenerationTest<GenFramebuffersAPI>(); -} TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestRenderbuffers) { FlushGenerationTest<GenRenderbuffersAPI>(); } @@ -3164,10 +3147,6 @@ TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestBuffers) { CrossContextGenerationTest<GenBuffersAPI>(); } TEST_F(GLES2ImplementationStrictSharedTest, - CrossContextGenerationTestFramebuffers) { - CrossContextGenerationTest<GenFramebuffersAPI>(); -} -TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestRenderbuffers) { CrossContextGenerationTest<GenRenderbuffersAPI>(); } @@ -3183,10 +3162,6 @@ TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationAutoFlushTest<GenBuffersAPI>(); } TEST_F(GLES2ImplementationStrictSharedTest, - CrossContextGenerationAutoFlushTestFramebuffers) { - CrossContextGenerationAutoFlushTest<GenFramebuffersAPI>(); -} -TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationAutoFlushTestRenderbuffers) { CrossContextGenerationAutoFlushTest<GenRenderbuffersAPI>(); } @@ -3976,8 +3951,7 @@ TEST_F(GLES2ImplementationTest, GenSyncTokenCHROMIUM) { .WillRepeatedly(Return(kNamespaceId)); EXPECT_CALL(*gpu_control_, GetCommandBufferID()) .WillRepeatedly(Return(kCommandBufferId)); - EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData()) - .WillRepeatedly(Return(0)); + EXPECT_CALL(*gpu_control_, GetStreamId()).WillRepeatedly(Return(0)); gl_->GenSyncTokenCHROMIUM(kFenceSync, nullptr); EXPECT_EQ(GL_INVALID_VALUE, CheckError()); @@ -4022,8 +3996,7 @@ TEST_F(GLES2ImplementationTest, GenUnverifiedSyncTokenCHROMIUM) { .WillRepeatedly(Return(kNamespaceId)); EXPECT_CALL(*gpu_control_, GetCommandBufferID()) .WillRepeatedly(Return(kCommandBufferId)); - EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData()) - .WillRepeatedly(Return(0)); + EXPECT_CALL(*gpu_control_, GetStreamId()).WillRepeatedly(Return(0)); gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync, nullptr); EXPECT_EQ(GL_INVALID_VALUE, CheckError()); @@ -4075,8 +4048,7 @@ TEST_F(GLES2ImplementationTest, VerifySyncTokensCHROMIUM) { .WillRepeatedly(Return(kNamespaceId)); EXPECT_CALL(*gpu_control_, GetCommandBufferID()) .WillRepeatedly(Return(kCommandBufferId)); - EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData()) - .WillRepeatedly(Return(0)); + EXPECT_CALL(*gpu_control_, GetStreamId()).WillRepeatedly(Return(0)); EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) .WillOnce(Return(true)); @@ -4131,8 +4103,7 @@ TEST_F(GLES2ImplementationTest, VerifySyncTokensCHROMIUM_Sequence) { .WillRepeatedly(Return(kNamespaceId)); EXPECT_CALL(*gpu_control_, GetCommandBufferID()) .WillRepeatedly(Return(kCommandBufferId)); - EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData()) - .WillRepeatedly(Return(0)); + EXPECT_CALL(*gpu_control_, GetStreamId()).WillRepeatedly(Return(0)); // Generate sync token 1. EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync1)) @@ -4185,7 +4156,7 @@ TEST_F(GLES2ImplementationTest, WaitSyncTokenCHROMIUM) { EXPECT_CALL(*gpu_control_, GetNamespaceID()).WillOnce(Return(kNamespaceId)); EXPECT_CALL(*gpu_control_, GetCommandBufferID()) .WillOnce(Return(kCommandBufferId)); - EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData()).WillOnce(Return(0)); + EXPECT_CALL(*gpu_control_, GetStreamId()).WillOnce(Return(0)); gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token_data); struct Cmds { @@ -4523,7 +4494,7 @@ TEST_F(GLES2ImplementationTest, SignalSyncToken) { EXPECT_CALL(*gpu_control_, IsFenceSyncFlushReceived(fence_sync)) .WillOnce(Return(true)); EXPECT_CALL(*gpu_control_, GetNamespaceID()).WillOnce(Return(GPU_IO)); - EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData()).WillOnce(Return(0)); + EXPECT_CALL(*gpu_control_, GetStreamId()).WillOnce(Return(0)); EXPECT_CALL(*gpu_control_, GetCommandBufferID()) .WillOnce(Return(CommandBufferId::FromUnsafeValue(1))); gpu::SyncToken sync_token; @@ -4555,7 +4526,7 @@ TEST_F(GLES2ImplementationTest, SignalSyncTokenAfterContextLoss) { EXPECT_CALL(*gpu_control_, IsFenceSyncFlushReceived(fence_sync)) .WillOnce(Return(true)); EXPECT_CALL(*gpu_control_, GetNamespaceID()).WillOnce(Return(GPU_IO)); - EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData()).WillOnce(Return(0)); + EXPECT_CALL(*gpu_control_, GetStreamId()).WillOnce(Return(0)); EXPECT_CALL(*gpu_control_, GetCommandBufferID()) .WillOnce(Return(CommandBufferId::FromUnsafeValue(1))); gpu::SyncToken sync_token; @@ -4630,6 +4601,50 @@ TEST_F(GLES2ImplementationManualInitTest, FailInitOnTransferBufferFail) { EXPECT_FALSE(Initialize(init_options)); } +TEST_F(GLES2ImplementationTest, DiscardableMemoryDelete) { + const GLuint texture_id = 1; + EXPECT_FALSE(share_group_->discardable_manager()->TextureIsValid(texture_id)); + gl_->InitializeDiscardableTextureCHROMIUM(texture_id); + EXPECT_TRUE(share_group_->discardable_manager()->TextureIsValid(texture_id)); + + // Deleting a texture should clear its discardable entry. + gl_->DeleteTextures(1, &texture_id); + EXPECT_FALSE(share_group_->discardable_manager()->TextureIsValid(texture_id)); +} + +TEST_F(GLES2ImplementationTest, DiscardableMemoryLockFail) { + const GLuint texture_id = 1; + gl_->InitializeDiscardableTextureCHROMIUM(texture_id); + EXPECT_TRUE(share_group_->discardable_manager()->TextureIsValid(texture_id)); + + // Unlock and delete the handle. + ClientDiscardableHandle client_handle = + share_group_->discardable_manager()->GetHandleForTesting(texture_id); + ServiceDiscardableHandle service_handle(client_handle.BufferForTesting(), + client_handle.byte_offset(), + client_handle.shm_id()); + service_handle.Unlock(); + EXPECT_TRUE(service_handle.Delete()); + + // Trying to re-lock the texture via GL should fail and delete the entry. + EXPECT_FALSE(gl_->LockDiscardableTextureCHROMIUM(texture_id)); + EXPECT_FALSE(share_group_->discardable_manager()->TextureIsValid(texture_id)); +} + +TEST_F(GLES2ImplementationTest, DiscardableMemoryDoubleInitError) { + const GLuint texture_id = 1; + gl_->InitializeDiscardableTextureCHROMIUM(texture_id); + EXPECT_EQ(GL_NO_ERROR, CheckError()); + gl_->InitializeDiscardableTextureCHROMIUM(texture_id); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); +} + +TEST_F(GLES2ImplementationTest, DiscardableMemoryLockError) { + const GLuint texture_id = 1; + EXPECT_FALSE(gl_->LockDiscardableTextureCHROMIUM(texture_id)); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); +} + #include "base/macros.h" #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h" diff --git a/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index cee92feeea8..55e10eaec65 100644 --- a/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -2781,6 +2781,17 @@ TEST_F(GLES2ImplementationTest, BindTexImage2DCHROMIUM) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, BindTexImage2DWithInternalformatCHROMIUM) { + struct Cmds { + cmds::BindTexImage2DWithInternalformatCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(GL_TEXTURE_2D, 2, 3); + + gl_->BindTexImage2DWithInternalformatCHROMIUM(GL_TEXTURE_2D, 2, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, ReleaseTexImage2DCHROMIUM) { struct Cmds { cmds::ReleaseTexImage2DCHROMIUM cmd; diff --git a/chromium/gpu/command_buffer/client/gles2_interface_autogen.h b/chromium/gpu/command_buffer/client/gles2_interface_autogen.h index 65724af5823..d42c6570a80 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_interface_autogen.h @@ -732,6 +732,9 @@ virtual void BindUniformLocationCHROMIUM(GLuint program, GLint location, const char* name) = 0; virtual void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) = 0; +virtual void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) = 0; virtual void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) = 0; virtual void TraceBeginCHROMIUM(const char* category_name, const char* trace_name) = 0; @@ -781,7 +784,8 @@ virtual void ScheduleDCLayerSharedStateCHROMIUM(GLfloat opacity, const GLfloat* clip_rect, GLint z_order, const GLfloat* transform) = 0; -virtual void ScheduleDCLayerCHROMIUM(GLuint contents_texture_id, +virtual void ScheduleDCLayerCHROMIUM(GLsizei num_textures, + const GLuint* contents_texture_ids, const GLfloat* contents_rect, GLuint background_color, GLuint edge_aa_mask, @@ -910,4 +914,7 @@ virtual void SetDrawRectangleCHROMIUM(GLint x, GLint width, GLint height) = 0; virtual void SetEnableDCLayersCHROMIUM(GLboolean enabled) = 0; +virtual void InitializeDiscardableTextureCHROMIUM(GLuint texture_id) = 0; +virtual void UnlockDiscardableTextureCHROMIUM(GLuint texture_id) = 0; +virtual bool LockDiscardableTextureCHROMIUM(GLuint texture_id) = 0; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 54dabbc267b..f70d6713eeb 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -710,6 +710,9 @@ void BindUniformLocationCHROMIUM(GLuint program, GLint location, const char* name) override; void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override; +void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) override; void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override; void TraceBeginCHROMIUM(const char* category_name, const char* trace_name) override; @@ -759,7 +762,8 @@ void ScheduleDCLayerSharedStateCHROMIUM(GLfloat opacity, const GLfloat* clip_rect, GLint z_order, const GLfloat* transform) override; -void ScheduleDCLayerCHROMIUM(GLuint contents_texture_id, +void ScheduleDCLayerCHROMIUM(GLsizei num_textures, + const GLuint* contents_texture_ids, const GLfloat* contents_rect, GLuint background_color, GLuint edge_aa_mask, @@ -883,4 +887,7 @@ void SetDrawRectangleCHROMIUM(GLint x, GLint width, GLint height) override; void SetEnableDCLayersCHROMIUM(GLboolean enabled) override; +void InitializeDiscardableTextureCHROMIUM(GLuint texture_id) override; +void UnlockDiscardableTextureCHROMIUM(GLuint texture_id) override; +bool LockDiscardableTextureCHROMIUM(GLuint texture_id) override; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 5073353be75..93ab09263c9 100644 --- a/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -965,6 +965,10 @@ void GLES2InterfaceStub::BindUniformLocationCHROMIUM(GLuint /* program */, const char* /* name */) {} void GLES2InterfaceStub::BindTexImage2DCHROMIUM(GLenum /* target */, GLint /* imageId */) {} +void GLES2InterfaceStub::BindTexImage2DWithInternalformatCHROMIUM( + GLenum /* target */, + GLenum /* internalformat */, + GLint /* imageId */) {} void GLES2InterfaceStub::ReleaseTexImage2DCHROMIUM(GLenum /* target */, GLint /* imageId */) {} void GLES2InterfaceStub::TraceBeginCHROMIUM(const char* /* category_name */, @@ -1032,7 +1036,8 @@ void GLES2InterfaceStub::ScheduleDCLayerSharedStateCHROMIUM( GLint /* z_order */, const GLfloat* /* transform */) {} void GLES2InterfaceStub::ScheduleDCLayerCHROMIUM( - GLuint /* contents_texture_id */, + GLsizei /* num_textures */, + const GLuint* /* contents_texture_ids */, const GLfloat* /* contents_rect */, GLuint /* background_color */, GLuint /* edge_aa_mask */, @@ -1188,4 +1193,12 @@ void GLES2InterfaceStub::SetDrawRectangleCHROMIUM(GLint /* x */, GLint /* width */, GLint /* height */) {} void GLES2InterfaceStub::SetEnableDCLayersCHROMIUM(GLboolean /* enabled */) {} +void GLES2InterfaceStub::InitializeDiscardableTextureCHROMIUM( + GLuint /* texture_id */) {} +void GLES2InterfaceStub::UnlockDiscardableTextureCHROMIUM( + GLuint /* texture_id */) {} +bool GLES2InterfaceStub::LockDiscardableTextureCHROMIUM( + GLuint /* texture_id */) { + return 0; +} #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_IMPL_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 783d7cc7308..c8dd078740d 100644 --- a/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -710,6 +710,9 @@ void BindUniformLocationCHROMIUM(GLuint program, GLint location, const char* name) override; void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override; +void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) override; void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override; void TraceBeginCHROMIUM(const char* category_name, const char* trace_name) override; @@ -759,7 +762,8 @@ void ScheduleDCLayerSharedStateCHROMIUM(GLfloat opacity, const GLfloat* clip_rect, GLint z_order, const GLfloat* transform) override; -void ScheduleDCLayerCHROMIUM(GLuint contents_texture_id, +void ScheduleDCLayerCHROMIUM(GLsizei num_textures, + const GLuint* contents_texture_ids, const GLfloat* contents_rect, GLuint background_color, GLuint edge_aa_mask, @@ -883,4 +887,7 @@ void SetDrawRectangleCHROMIUM(GLint x, GLint width, GLint height) override; void SetEnableDCLayersCHROMIUM(GLboolean enabled) override; +void InitializeDiscardableTextureCHROMIUM(GLuint texture_id) override; +void UnlockDiscardableTextureCHROMIUM(GLuint texture_id) override; +bool LockDiscardableTextureCHROMIUM(GLuint texture_id) override; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 01db22e23c1..5d229f5e3f4 100644 --- a/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/chromium/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -2054,6 +2054,16 @@ void GLES2TraceImplementation::BindTexImage2DCHROMIUM(GLenum target, gl_->BindTexImage2DCHROMIUM(target, imageId); } +void GLES2TraceImplementation::BindTexImage2DWithInternalformatCHROMIUM( + GLenum target, + GLenum internalformat, + GLint imageId) { + TRACE_EVENT_BINARY_EFFICIENT0( + "gpu", "GLES2Trace::BindTexImage2DWithInternalformatCHROMIUM"); + gl_->BindTexImage2DWithInternalformatCHROMIUM(target, internalformat, + imageId); +} + void GLES2TraceImplementation::ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ReleaseTexImage2DCHROMIUM"); @@ -2212,16 +2222,17 @@ void GLES2TraceImplementation::ScheduleDCLayerSharedStateCHROMIUM( } void GLES2TraceImplementation::ScheduleDCLayerCHROMIUM( - GLuint contents_texture_id, + GLsizei num_textures, + const GLuint* contents_texture_ids, const GLfloat* contents_rect, GLuint background_color, GLuint edge_aa_mask, const GLfloat* bounds_rect, GLuint filter) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ScheduleDCLayerCHROMIUM"); - gl_->ScheduleDCLayerCHROMIUM(contents_texture_id, contents_rect, - background_color, edge_aa_mask, bounds_rect, - filter); + gl_->ScheduleDCLayerCHROMIUM(num_textures, contents_texture_ids, + contents_rect, background_color, edge_aa_mask, + bounds_rect, filter); } void GLES2TraceImplementation::MatrixLoadfCHROMIUM(GLenum matrixMode, @@ -2541,4 +2552,25 @@ void GLES2TraceImplementation::SetEnableDCLayersCHROMIUM(GLboolean enabled) { gl_->SetEnableDCLayersCHROMIUM(enabled); } +void GLES2TraceImplementation::InitializeDiscardableTextureCHROMIUM( + GLuint texture_id) { + TRACE_EVENT_BINARY_EFFICIENT0( + "gpu", "GLES2Trace::InitializeDiscardableTextureCHROMIUM"); + gl_->InitializeDiscardableTextureCHROMIUM(texture_id); +} + +void GLES2TraceImplementation::UnlockDiscardableTextureCHROMIUM( + GLuint texture_id) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "GLES2Trace::UnlockDiscardableTextureCHROMIUM"); + gl_->UnlockDiscardableTextureCHROMIUM(texture_id); +} + +bool GLES2TraceImplementation::LockDiscardableTextureCHROMIUM( + GLuint texture_id) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "GLES2Trace::LockDiscardableTextureCHROMIUM"); + return gl_->LockDiscardableTextureCHROMIUM(texture_id); +} + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_IMPL_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/client/gpu_control.h b/chromium/gpu/command_buffer/client/gpu_control.h index 519712edc4a..f8657455267 100644 --- a/chromium/gpu/command_buffer/client/gpu_control.h +++ b/chromium/gpu/command_buffer/client/gpu_control.h @@ -24,6 +24,10 @@ namespace base { class Lock; } +namespace ui { +class LatencyInfo; +} + namespace gpu { class GpuControlClient; struct SyncToken; @@ -73,7 +77,13 @@ class GPU_EXPORT GpuControl { // the CanWaitUnverifiedSyncToken() function. virtual CommandBufferNamespace GetNamespaceID() const = 0; virtual CommandBufferId GetCommandBufferID() const = 0; - virtual int32_t GetExtraCommandBufferData() const = 0; + + // Returns the stream id for this context. Only relevant for IPC command + // buffer proxy. Used as extra command buffer data in sync tokens. + virtual int32_t GetStreamId() const = 0; + + // Flush any outstanding ordering barriers on given stream. + virtual void FlushOrderingBarrierOnStream(int32_t stream_id) = 0; // Generates a fence sync which should be inserted into the GL command stream. // When the service executes the fence sync it is released. Fence syncs are @@ -115,6 +125,11 @@ class GPU_EXPORT GpuControl { // first so does not need to be flushed. virtual bool CanWaitUnverifiedSyncToken(const SyncToken& sync_token) = 0; + // Add |latency_info| to be reported and augumented with GPU latency + // components next time there is a GPU buffer swap. + virtual void AddLatencyInfo( + const std::vector<ui::LatencyInfo>& latency_info) = 0; + private: DISALLOW_COPY_AND_ASSIGN(GpuControl); }; diff --git a/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc b/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc index a18838311ef..134f55a1841 100644 --- a/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc +++ b/chromium/gpu/command_buffer/client/mapped_memory_unittest.cc @@ -11,11 +11,11 @@ #include <memory> #include "base/bind.h" +#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" -#include "gpu/command_buffer/service/command_buffer_service.h" -#include "gpu/command_buffer/service/command_executor.h" +#include "gpu/command_buffer/service/command_buffer_direct.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -45,23 +45,11 @@ class MappedMemoryTestBase : public testing::Test { .WillRepeatedly(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), Return(error::kNoError))); - { - TransferBufferManager* manager = new TransferBufferManager(nullptr); - transfer_buffer_manager_ = manager; - EXPECT_TRUE(manager->Initialize()); - } + transfer_buffer_manager_ = base::MakeUnique<TransferBufferManager>(nullptr); + command_buffer_.reset(new CommandBufferDirect( + transfer_buffer_manager_.get(), api_mock_.get())); - command_buffer_.reset( - new CommandBufferService(transfer_buffer_manager_.get())); - - executor_.reset( - new CommandExecutor(command_buffer_.get(), api_mock_.get(), NULL)); - command_buffer_->SetPutOffsetChangeCallback(base::Bind( - &CommandExecutor::PutChanged, base::Unretained(executor_.get()))); - command_buffer_->SetGetBufferChangeCallback(base::Bind( - &CommandExecutor::SetGetBuffer, base::Unretained(executor_.get()))); - - api_mock_->set_engine(executor_.get()); + api_mock_->set_command_buffer_service(command_buffer_->service()); helper_.reset(new CommandBufferHelper(command_buffer_.get())); helper_->Initialize(kBufferSize); @@ -70,9 +58,8 @@ class MappedMemoryTestBase : public testing::Test { int32_t GetToken() { return command_buffer_->GetLastState().token; } std::unique_ptr<AsyncAPIMock> api_mock_; - scoped_refptr<TransferBufferManagerInterface> transfer_buffer_manager_; - std::unique_ptr<CommandBufferService> command_buffer_; - std::unique_ptr<CommandExecutor> executor_; + std::unique_ptr<TransferBufferManager> transfer_buffer_manager_; + std::unique_ptr<CommandBufferDirect> command_buffer_; std::unique_ptr<CommandBufferHelper> helper_; base::MessageLoop message_loop_; }; diff --git a/chromium/gpu/command_buffer/client/ring_buffer_test.cc b/chromium/gpu/command_buffer/client/ring_buffer_test.cc index 26124d397e2..86ffa7d9960 100644 --- a/chromium/gpu/command_buffer/client/ring_buffer_test.cc +++ b/chromium/gpu/command_buffer/client/ring_buffer_test.cc @@ -12,11 +12,11 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "gpu/command_buffer/client/cmd_buffer_helper.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" -#include "gpu/command_buffer/service/command_buffer_service.h" -#include "gpu/command_buffer/service/command_executor.h" +#include "gpu/command_buffer/service/command_buffer_direct.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -70,22 +70,11 @@ class BaseRingBufferTest : public testing::Test { .WillRepeatedly(DoAll(Invoke(this, &BaseRingBufferTest::SetToken), Return(error::kNoError))); - { - TransferBufferManager* manager = new TransferBufferManager(nullptr); - transfer_buffer_manager_ = manager; - EXPECT_TRUE(manager->Initialize()); - } - command_buffer_.reset( - new CommandBufferService(transfer_buffer_manager_.get())); - - executor_.reset( - new CommandExecutor(command_buffer_.get(), api_mock_.get(), NULL)); - command_buffer_->SetPutOffsetChangeCallback(base::Bind( - &CommandExecutor::PutChanged, base::Unretained(executor_.get()))); - command_buffer_->SetGetBufferChangeCallback(base::Bind( - &CommandExecutor::SetGetBuffer, base::Unretained(executor_.get()))); + transfer_buffer_manager_ = base::MakeUnique<TransferBufferManager>(nullptr); + command_buffer_.reset(new CommandBufferDirect( + transfer_buffer_manager_.get(), api_mock_.get())); - api_mock_->set_engine(executor_.get()); + api_mock_->set_command_buffer_service(command_buffer_->service()); helper_.reset(new CommandBufferHelper(command_buffer_.get())); helper_->Initialize(kBufferSize); @@ -94,9 +83,8 @@ class BaseRingBufferTest : public testing::Test { int32_t GetToken() { return command_buffer_->GetLastState().token; } std::unique_ptr<AsyncAPIMock> api_mock_; - scoped_refptr<TransferBufferManagerInterface> transfer_buffer_manager_; - std::unique_ptr<CommandBufferService> command_buffer_; - std::unique_ptr<CommandExecutor> executor_; + std::unique_ptr<TransferBufferManager> transfer_buffer_manager_; + std::unique_ptr<CommandBufferDirect> command_buffer_; std::unique_ptr<CommandBufferHelper> helper_; std::vector<const volatile void*> set_token_arguments_; bool delay_set_token_; diff --git a/chromium/gpu/command_buffer/client/share_group.cc b/chromium/gpu/command_buffer/client/share_group.cc index d1041c06e3a..126332cc865 100644 --- a/chromium/gpu/command_buffer/client/share_group.cc +++ b/chromium/gpu/command_buffer/client/share_group.cc @@ -352,16 +352,20 @@ ShareGroup::ShareGroup(bool bind_generates_resource, uint64_t tracing_guid) : bind_generates_resource_(bind_generates_resource), tracing_guid_(tracing_guid) { if (bind_generates_resource) { - for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { - if (i == id_namespaces::kProgramsAndShaders) { + for (int i = 0; + i < static_cast<int>(SharedIdNamespaces::kNumSharedIdNamespaces); + ++i) { + if (i == static_cast<int>(SharedIdNamespaces::kProgramsAndShaders)) { id_handlers_[i].reset(new NonReusedIdHandler()); } else { id_handlers_[i].reset(new IdHandler()); } } } else { - for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { - if (i == id_namespaces::kProgramsAndShaders) { + for (int i = 0; + i < static_cast<int>(SharedIdNamespaces::kNumSharedIdNamespaces); + ++i) { + if (i == static_cast<int>(SharedIdNamespaces::kProgramsAndShaders)) { id_handlers_[i].reset(new NonReusedIdHandler()); } else { id_handlers_[i].reset(new StrictIdHandler(i)); diff --git a/chromium/gpu/command_buffer/client/share_group.h b/chromium/gpu/command_buffer/client/share_group.h index 091b69f2385..fe37ddaff32 100644 --- a/chromium/gpu/command_buffer/client/share_group.h +++ b/chromium/gpu/command_buffer/client/share_group.h @@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/synchronization/lock.h" #include "gles2_impl_export.h" +#include "gpu/command_buffer/client/client_discardable_manager.h" #include "gpu/command_buffer/client/ref_counted.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" @@ -32,6 +33,8 @@ typedef void (GLES2Implementation::*BindIndexedFn)( \ typedef void (GLES2Implementation::*BindIndexedRangeFn)( \ GLenum target, GLuint index, GLuint id, GLintptr offset, GLsizeiptr size); +using SharedIdNamespaces = id_namespaces::SharedIdNamespaces; + class ShareGroupContextData { public: struct IdHandlerData { @@ -47,7 +50,8 @@ class ShareGroupContextData { } private: - IdHandlerData id_handler_data_[id_namespaces::kNumIdNamespaces]; + IdHandlerData id_handler_data_[static_cast<int>( + SharedIdNamespaces::kNumSharedIdNamespaces)]; }; // Base class for IdHandlers @@ -124,8 +128,8 @@ class GLES2_IMPL_EXPORT ShareGroup return bind_generates_resource_; } - IdHandlerInterface* GetIdHandler(int namespace_id) const { - return id_handlers_[namespace_id].get(); + IdHandlerInterface* GetIdHandler(SharedIdNamespaces namespace_id) const { + return id_handlers_[static_cast<int>(namespace_id)].get(); } RangeIdHandlerInterface* GetRangeIdHandler(int range_namespace_id) const { @@ -137,7 +141,9 @@ class GLES2_IMPL_EXPORT ShareGroup } void FreeContext(GLES2Implementation* gl_impl) { - for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { + for (int i = 0; + i < static_cast<int>(SharedIdNamespaces::kNumSharedIdNamespaces); + ++i) { id_handlers_[i]->FreeContext(gl_impl); } for (auto& range_id_handler : range_id_handlers_) { @@ -147,6 +153,10 @@ class GLES2_IMPL_EXPORT ShareGroup uint64_t TracingGUID() const { return tracing_guid_; } + ClientDiscardableManager* discardable_manager() { + return &discardable_manager_; + } + // Mark the ShareGroup as lost when an error occurs on any context in the // group. This is thread safe as contexts may be on different threads. void Lose(); @@ -162,11 +172,12 @@ class GLES2_IMPL_EXPORT ShareGroup // Install a new program info manager. Used for testing only; void SetProgramInfoManagerForTesting(ProgramInfoManager* manager); - std::unique_ptr<IdHandlerInterface> - id_handlers_[id_namespaces::kNumIdNamespaces]; + std::unique_ptr<IdHandlerInterface> id_handlers_[static_cast<int>( + SharedIdNamespaces::kNumSharedIdNamespaces)]; std::unique_ptr<RangeIdHandlerInterface> range_id_handlers_[id_namespaces::kNumRangeIdNamespaces]; std::unique_ptr<ProgramInfoManager> program_info_manager_; + ClientDiscardableManager discardable_manager_; bool bind_generates_resource_; uint64_t tracing_guid_; diff --git a/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc b/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc index 369adfd83aa..aba8988403e 100644 --- a/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc +++ b/chromium/gpu/command_buffer/client/transfer_buffer_unittest.cc @@ -235,7 +235,7 @@ class MockClientCommandBufferCanFail : public MockClientCommandBufferMockFlush { scoped_refptr<gpu::Buffer> RealCreateTransferBuffer(size_t size, int32_t* id) { - return MockCommandBufferBase::CreateTransferBuffer(size, id); + return MockClientCommandBufferMockFlush::CreateTransferBuffer(size, id); } }; diff --git a/chromium/gpu/command_buffer/cmd_buffer_functions.txt b/chromium/gpu/command_buffer/cmd_buffer_functions.txt index a1055e89b3f..f806109bdc7 100644 --- a/chromium/gpu/command_buffer/cmd_buffer_functions.txt +++ b/chromium/gpu/command_buffer/cmd_buffer_functions.txt @@ -293,6 +293,7 @@ GL_APICALL GLuint GL_APIENTRY glCreateAndConsumeTextureCHROMIUM (GLenumTex GL_APICALL void GL_APIENTRY glCreateAndConsumeTextureINTERNAL (GLenumTextureBindTarget target, GLuint texture, const GLbyte* mailbox); GL_APICALL void GL_APIENTRY glBindUniformLocationCHROMIUM (GLidProgram program, GLint location, const char* name); GL_APICALL void GL_APIENTRY glBindTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId); +GL_APICALL void GL_APIENTRY glBindTexImage2DWithInternalformatCHROMIUM (GLenumTextureBindTarget target, GLenum internalformat, GLint imageId); GL_APICALL void GL_APIENTRY glReleaseTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId); GL_APICALL void GL_APIENTRY glTraceBeginCHROMIUM (const char* category_name, const char* trace_name); GL_APICALL void GL_APIENTRY glTraceEndCHROMIUM (void); @@ -314,7 +315,7 @@ GL_APICALL void GL_APIENTRY glSwapInterval (GLint interval); GL_APICALL void GL_APIENTRY glFlushDriverCachesCHROMIUM (void); GL_APICALL GLuint GL_APIENTRY glGetLastFlushIdCHROMIUM (void); GL_APICALL void GL_APIENTRY glScheduleDCLayerSharedStateCHROMIUM (GLfloat opacity, GLboolean is_clipped, const GLfloat* clip_rect, GLint z_order, const GLfloat* transform); -GL_APICALL void GL_APIENTRY glScheduleDCLayerCHROMIUM (GLuint contents_texture_id, const GLfloat* contents_rect, GLuint background_color, GLuint edge_aa_mask, const GLfloat* bounds_rect, GLuint filter); +GL_APICALL void GL_APIENTRY glScheduleDCLayerCHROMIUM (GLsizei num_textures, const GLuint* contents_texture_ids, const GLfloat* contents_rect, GLuint background_color, GLuint edge_aa_mask, const GLfloat* bounds_rect, GLuint filter); // Extension CHROMIUM_path_rendering. GL_APICALL void GL_APIENTRY glMatrixLoadfCHROMIUM (GLenumMatrixMode matrixMode, const GLfloat* m); @@ -371,3 +372,8 @@ GL_APICALL void GL_APIENTRY glSetDrawRectangleCHROMIUM (GLint x, GLint y // Extension CHROMIUM_dc_overlays GL_APICALL void GL_APIENTRY glSetEnableDCLayersCHROMIUM (GLboolean enabled); + +// Extension CHROMIUM_discardable_textures +GL_APICALL void GL_APIENTRY glInitializeDiscardableTextureCHROMIUM (GLuint texture_id); +GL_APICALL void GL_APIENTRY glUnlockDiscardableTextureCHROMIUM (GLuint texture_id); +GL_APICALL bool GL_APIENTRY glLockDiscardableTextureCHROMIUM (GLuint texture_id); diff --git a/chromium/gpu/command_buffer/common/BUILD.gn b/chromium/gpu/command_buffer/common/BUILD.gn index 4b69e04e114..633e79119d3 100644 --- a/chromium/gpu/command_buffer/common/BUILD.gn +++ b/chromium/gpu/command_buffer/common/BUILD.gn @@ -53,6 +53,8 @@ source_set("common_sources") { "mailbox.h", "mailbox_holder.cc", "mailbox_holder.h", + "scheduling_priority.cc", + "scheduling_priority.h", "sync_token.cc", "sync_token.h", "texture_in_use_response.h", diff --git a/chromium/gpu/command_buffer/common/capabilities.h b/chromium/gpu/command_buffer/common/capabilities.h index 9cfa984a671..7950779e952 100644 --- a/chromium/gpu/command_buffer/common/capabilities.h +++ b/chromium/gpu/command_buffer/common/capabilities.h @@ -139,6 +139,7 @@ struct GPU_EXPORT Capabilities { bool blend_equation_advanced = false; bool blend_equation_advanced_coherent = false; bool texture_rg = false; + bool texture_norm16 = false; bool texture_half_float_linear = false; bool color_buffer_half_float_rgba = false; bool image_ycbcr_422 = false; diff --git a/chromium/gpu/command_buffer/common/command_buffer.h b/chromium/gpu/command_buffer/common/command_buffer.h index 789c6f8965a..a438ba04f25 100644 --- a/chromium/gpu/command_buffer/common/command_buffer.h +++ b/chromium/gpu/command_buffer/common/command_buffer.h @@ -25,8 +25,8 @@ class GPU_EXPORT CommandBuffer { release_count(0), error(error::kNoError), context_lost_reason(error::kUnknown), - generation(0) { - } + generation(0), + set_get_buffer_count(0) {} // The offset (in entries) from which the reader is reading. int32_t get_offset; @@ -52,6 +52,10 @@ class GPU_EXPORT CommandBuffer { // time a new state is retrieved from the command processor, so that // consistency can be kept even if IPC messages are processed out-of-order. uint32_t generation; + + // Number of times SetGetBuffer was called. This allows the client to verify + // that |get| corresponds (or not) to the last buffer it set. + uint32_t set_get_buffer_count; }; struct ConsoleMessage { @@ -95,11 +99,15 @@ class GPU_EXPORT CommandBuffer { virtual State WaitForTokenInRange(int32_t start, int32_t end) = 0; // The writer calls this to wait until the current get offset is within a - // specific range, inclusive. Can return early if an error is generated. - virtual State WaitForGetOffsetInRange(int32_t start, int32_t end) = 0; + // specific range, inclusive, after SetGetBuffer was called exactly + // set_get_buffer_count times. Can return early if an error is generated. + virtual State WaitForGetOffsetInRange(uint32_t set_get_buffer_count, + int32_t start, + int32_t end) = 0; // Sets the buffer commands are read from. - // Also resets the get and put offsets to 0. + // Also resets the get and put offsets to 0, and increments + // set_get_buffer_count. virtual void SetGetBuffer(int32_t transfer_buffer_id) = 0; // Create a transfer buffer of the given size. Returns its ID or -1 on diff --git a/chromium/gpu/command_buffer/common/command_buffer_mock.cc b/chromium/gpu/command_buffer/common/command_buffer_mock.cc deleted file mode 100644 index a64dc452c32..00000000000 --- a/chromium/gpu/command_buffer/common/command_buffer_mock.cc +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2011 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/common/command_buffer_mock.h" - -namespace gpu { - -MockCommandBuffer::MockCommandBuffer() { - ON_CALL(*this, GetTransferBuffer(testing::_)) - .WillByDefault(testing::Return(scoped_refptr<gpu::Buffer>())); -} - -MockCommandBuffer::~MockCommandBuffer() {} - -} // namespace gpu diff --git a/chromium/gpu/command_buffer/common/command_buffer_mock.h b/chromium/gpu/command_buffer/common/command_buffer_mock.h deleted file mode 100644 index ff17e50f462..00000000000 --- a/chromium/gpu/command_buffer/common/command_buffer_mock.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2011 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_COMMON_COMMAND_BUFFER_MOCK_H_ -#define GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_MOCK_H_ - -#include <stddef.h> -#include <stdint.h> - -#include "base/macros.h" -#include "gpu/command_buffer/service/command_buffer_service.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace gpu { - -// An NPObject that implements a shared memory command buffer and a synchronous -// API to manage the put and get pointers. -class MockCommandBuffer : public CommandBufferServiceBase { - public: - MockCommandBuffer(); - virtual ~MockCommandBuffer(); - - MOCK_METHOD0(GetLastState, State()); - MOCK_METHOD0(GetLastToken, int32_t()); - MOCK_METHOD1(Flush, void(int32_t put_offset)); - MOCK_METHOD1(OrderingBarrier, void(int32_t put_offset)); - MOCK_METHOD2(WaitForTokenInRange, State(int32_t start, int32_t end)); - MOCK_METHOD2(WaitForGetOffsetInRange, State(int32_t start, int32_t end)); - MOCK_METHOD1(SetGetBuffer, void(int32_t transfer_buffer_id)); - MOCK_METHOD1(SetGetOffset, void(int32_t get_offset)); - MOCK_METHOD1(SetReleaseCount, void(uint64_t release_count)); - MOCK_METHOD2(CreateTransferBuffer, - scoped_refptr<gpu::Buffer>(size_t size, int32_t* id)); - MOCK_METHOD1(DestroyTransferBuffer, void(int32_t id)); - MOCK_METHOD1(GetTransferBuffer, scoped_refptr<gpu::Buffer>(int32_t id)); - MOCK_METHOD1(SetToken, void(int32_t token)); - MOCK_METHOD1(SetParseError, void(error::Error error)); - MOCK_METHOD1(SetContextLostReason, - void(error::ContextLostReason context_lost_reason)); - MOCK_METHOD0(InsertSyncPoint, uint32_t()); - MOCK_METHOD0(GetPutOffset, int32_t()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockCommandBuffer); -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_MOCK_H_ diff --git a/chromium/gpu/command_buffer/common/discardable_handle.cc b/chromium/gpu/command_buffer/common/discardable_handle.cc index 987ad821f45..d7fa9cd642c 100644 --- a/chromium/gpu/command_buffer/common/discardable_handle.cc +++ b/chromium/gpu/command_buffer/common/discardable_handle.cc @@ -30,11 +30,11 @@ DiscardableHandleBase& DiscardableHandleBase::operator=( DiscardableHandleBase& DiscardableHandleBase::operator=( DiscardableHandleBase&& other) = default; -bool DiscardableHandleBase::IsLockedForTesting() { +bool DiscardableHandleBase::IsLockedForTesting() const { return kHandleLockedStart <= base::subtle::NoBarrier_Load(AsAtomic()); } -bool DiscardableHandleBase::IsDeletedForTesting() { +bool DiscardableHandleBase::IsDeletedForTesting() const { return kHandleDeleted == base::subtle::NoBarrier_Load(AsAtomic()); } @@ -114,4 +114,11 @@ bool ServiceDiscardableHandle::Delete() { AsAtomic(), kHandleUnlocked, kHandleDeleted); } +void ServiceDiscardableHandle::ForceDelete() { + // No barrier is needed as all GPU process access happens on a single thread, + // and communication of dependent data between the GPU process and the + // renderer process happens across the command buffer and includes barriers. + base::subtle::NoBarrier_Store(AsAtomic(), kHandleDeleted); +} + } // namespace gpu diff --git a/chromium/gpu/command_buffer/common/discardable_handle.h b/chromium/gpu/command_buffer/common/discardable_handle.h index a3b17691da9..7d4c52868f2 100644 --- a/chromium/gpu/command_buffer/common/discardable_handle.h +++ b/chromium/gpu/command_buffer/common/discardable_handle.h @@ -37,8 +37,9 @@ class GPU_EXPORT DiscardableHandleBase { uint32_t byte_offset() const { return byte_offset_; } // Test only functions. - bool IsLockedForTesting(); - bool IsDeletedForTesting(); + bool IsLockedForTesting() const; + bool IsDeletedForTesting() const; + scoped_refptr<Buffer> BufferForTesting() const { return buffer_; } protected: DiscardableHandleBase(scoped_refptr<Buffer> buffer, @@ -98,6 +99,11 @@ class GPU_EXPORT ServiceDiscardableHandle : public DiscardableHandleBase { // Tries to delete the handle. Returns true if successfully deleted. Returns // false if the handle is locked client-side and cannot be deleted. bool Delete(); + + // Deletes the handle, regardless of the handle's state. This should be + // called in response to glDeleteTextures, which may be called while the + // handle is in the locked or unlocked state. + void ForceDelete(); }; } // namespace gpu diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format.h b/chromium/gpu/command_buffer/common/gles2_cmd_format.h index c1801f00b91..2e8fdf9b544 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format.h @@ -60,28 +60,47 @@ static_assert(GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT == 4, namespace id_namespaces { // These are used when contexts share resources. -enum IdNamespaces { +enum class SharedIdNamespaces { kBuffers, - kFramebuffers, kProgramsAndShaders, kRenderbuffers, kTextures, + kSamplers, + kSyncs, + kNumSharedIdNamespaces +}; + +enum class IdNamespaces { + kFramebuffers, kQueries, kVertexArrays, - kSamplers, kTransformFeedbacks, - kSyncs, kNumIdNamespaces }; enum RangeIdNamespaces { kPaths, kNumRangeIdNamespaces }; // These numbers must not change -static_assert(kBuffers == 0, "kBuffers should equal 0"); -static_assert(kFramebuffers == 1, "kFramebuffers should equal 1"); -static_assert(kProgramsAndShaders == 2, "kProgramsAndShaders should equal 2"); -static_assert(kRenderbuffers == 3, "kRenderbuffers should equal 3"); -static_assert(kTextures == 4, "kTextures should equal 4"); +static_assert(static_cast<int>(SharedIdNamespaces::kBuffers) == 0, + "kBuffers should equal 0"); +static_assert(static_cast<int>(SharedIdNamespaces::kProgramsAndShaders) == 1, + "kProgramsAndShaders should equal 1"); +static_assert(static_cast<int>(SharedIdNamespaces::kRenderbuffers) == 2, + "kRenderbuffers should equal 2"); +static_assert(static_cast<int>(SharedIdNamespaces::kTextures) == 3, + "kTextures should equal 3"); +static_assert(static_cast<int>(SharedIdNamespaces::kSamplers) == 4, + "kSamplers should equal 4"); +static_assert(static_cast<int>(SharedIdNamespaces::kSyncs) == 5, + "kProgramsAndShaders should equal 5"); +static_assert(static_cast<int>(IdNamespaces::kFramebuffers) == 0, + "kFramebuffers should equal 0"); +static_assert(static_cast<int>(IdNamespaces::kQueries) == 1, + "kQueries should equal 1"); +static_assert(static_cast<int>(IdNamespaces::kVertexArrays) == 2, + "kVertexArrays should equal 2"); +static_assert(static_cast<int>(IdNamespaces::kTransformFeedbacks) == 3, + "kTransformFeedbacks should equal 3"); static_assert(kPaths == 0, "kPaths should equal 0"); } // namespace id_namespaces @@ -289,7 +308,7 @@ static_assert(offsetof(UniformBlocksHeader, num_uniform_blocks) == 0, namespace cmds { -#include "../common/gles2_cmd_format_autogen.h" +#include "gpu/command_buffer/common/gles2_cmd_format_autogen.h" #pragma pack(pop) diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 2f1e47f72dd..1407ca840dc 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -13084,6 +13084,52 @@ static_assert(offsetof(BindTexImage2DCHROMIUM, target) == 4, static_assert(offsetof(BindTexImage2DCHROMIUM, imageId) == 8, "offset of BindTexImage2DCHROMIUM imageId should be 8"); +struct BindTexImage2DWithInternalformatCHROMIUM { + typedef BindTexImage2DWithInternalformatCHROMIUM ValueType; + static const CommandId kCmdId = kBindTexImage2DWithInternalformatCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _target, GLenum _internalformat, GLint _imageId) { + SetHeader(); + target = _target; + internalformat = _internalformat; + imageId = _imageId; + } + + void* Set(void* cmd, GLenum _target, GLenum _internalformat, GLint _imageId) { + static_cast<ValueType*>(cmd)->Init(_target, _internalformat, _imageId); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + uint32_t internalformat; + int32_t imageId; +}; + +static_assert(sizeof(BindTexImage2DWithInternalformatCHROMIUM) == 16, + "size of BindTexImage2DWithInternalformatCHROMIUM should be 16"); +static_assert( + offsetof(BindTexImage2DWithInternalformatCHROMIUM, header) == 0, + "offset of BindTexImage2DWithInternalformatCHROMIUM header should be 0"); +static_assert( + offsetof(BindTexImage2DWithInternalformatCHROMIUM, target) == 4, + "offset of BindTexImage2DWithInternalformatCHROMIUM target should be 4"); +static_assert(offsetof(BindTexImage2DWithInternalformatCHROMIUM, + internalformat) == 8, + "offset of BindTexImage2DWithInternalformatCHROMIUM " + "internalformat should be 8"); +static_assert( + offsetof(BindTexImage2DWithInternalformatCHROMIUM, imageId) == 12, + "offset of BindTexImage2DWithInternalformatCHROMIUM imageId should be 12"); + struct ReleaseTexImage2DCHROMIUM { typedef ReleaseTexImage2DCHROMIUM ValueType; static const CommandId kCmdId = kReleaseTexImage2DCHROMIUM; @@ -13891,14 +13937,14 @@ struct ScheduleDCLayerCHROMIUM { void SetHeader() { header.SetCmd<ValueType>(); } - void Init(GLuint _contents_texture_id, + void Init(GLsizei _num_textures, GLuint _background_color, GLuint _edge_aa_mask, GLuint _filter, GLuint _shm_id, GLuint _shm_offset) { SetHeader(); - contents_texture_id = _contents_texture_id; + num_textures = _num_textures; background_color = _background_color; edge_aa_mask = _edge_aa_mask; filter = _filter; @@ -13907,20 +13953,20 @@ struct ScheduleDCLayerCHROMIUM { } void* Set(void* cmd, - GLuint _contents_texture_id, + GLsizei _num_textures, GLuint _background_color, GLuint _edge_aa_mask, GLuint _filter, GLuint _shm_id, GLuint _shm_offset) { - static_cast<ValueType*>(cmd)->Init(_contents_texture_id, _background_color, + static_cast<ValueType*>(cmd)->Init(_num_textures, _background_color, _edge_aa_mask, _filter, _shm_id, _shm_offset); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; - uint32_t contents_texture_id; + int32_t num_textures; uint32_t background_color; uint32_t edge_aa_mask; uint32_t filter; @@ -13932,9 +13978,8 @@ static_assert(sizeof(ScheduleDCLayerCHROMIUM) == 28, "size of ScheduleDCLayerCHROMIUM should be 28"); static_assert(offsetof(ScheduleDCLayerCHROMIUM, header) == 0, "offset of ScheduleDCLayerCHROMIUM header should be 0"); -static_assert( - offsetof(ScheduleDCLayerCHROMIUM, contents_texture_id) == 4, - "offset of ScheduleDCLayerCHROMIUM contents_texture_id should be 4"); +static_assert(offsetof(ScheduleDCLayerCHROMIUM, num_textures) == 4, + "offset of ScheduleDCLayerCHROMIUM num_textures should be 4"); static_assert(offsetof(ScheduleDCLayerCHROMIUM, background_color) == 8, "offset of ScheduleDCLayerCHROMIUM background_color should be 8"); static_assert(offsetof(ScheduleDCLayerCHROMIUM, edge_aa_mask) == 12, @@ -15899,4 +15944,120 @@ static_assert(offsetof(SetEnableDCLayersCHROMIUM, header) == 0, static_assert(offsetof(SetEnableDCLayersCHROMIUM, enabled) == 4, "offset of SetEnableDCLayersCHROMIUM enabled should be 4"); +struct InitializeDiscardableTextureCHROMIUM { + typedef InitializeDiscardableTextureCHROMIUM ValueType; + static const CommandId kCmdId = kInitializeDiscardableTextureCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _texture_id, uint32_t _shm_id, uint32_t _shm_offset) { + SetHeader(); + texture_id = _texture_id; + shm_id = _shm_id; + shm_offset = _shm_offset; + } + + void* Set(void* cmd, + GLuint _texture_id, + uint32_t _shm_id, + uint32_t _shm_offset) { + static_cast<ValueType*>(cmd)->Init(_texture_id, _shm_id, _shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t texture_id; + uint32_t shm_id; + uint32_t shm_offset; +}; + +static_assert(sizeof(InitializeDiscardableTextureCHROMIUM) == 16, + "size of InitializeDiscardableTextureCHROMIUM should be 16"); +static_assert( + offsetof(InitializeDiscardableTextureCHROMIUM, header) == 0, + "offset of InitializeDiscardableTextureCHROMIUM header should be 0"); +static_assert( + offsetof(InitializeDiscardableTextureCHROMIUM, texture_id) == 4, + "offset of InitializeDiscardableTextureCHROMIUM texture_id should be 4"); +static_assert( + offsetof(InitializeDiscardableTextureCHROMIUM, shm_id) == 8, + "offset of InitializeDiscardableTextureCHROMIUM shm_id should be 8"); +static_assert( + offsetof(InitializeDiscardableTextureCHROMIUM, shm_offset) == 12, + "offset of InitializeDiscardableTextureCHROMIUM shm_offset should be 12"); + +struct UnlockDiscardableTextureCHROMIUM { + typedef UnlockDiscardableTextureCHROMIUM ValueType; + static const CommandId kCmdId = kUnlockDiscardableTextureCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _texture_id) { + SetHeader(); + texture_id = _texture_id; + } + + void* Set(void* cmd, GLuint _texture_id) { + static_cast<ValueType*>(cmd)->Init(_texture_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t texture_id; +}; + +static_assert(sizeof(UnlockDiscardableTextureCHROMIUM) == 8, + "size of UnlockDiscardableTextureCHROMIUM should be 8"); +static_assert(offsetof(UnlockDiscardableTextureCHROMIUM, header) == 0, + "offset of UnlockDiscardableTextureCHROMIUM header should be 0"); +static_assert( + offsetof(UnlockDiscardableTextureCHROMIUM, texture_id) == 4, + "offset of UnlockDiscardableTextureCHROMIUM texture_id should be 4"); + +struct LockDiscardableTextureCHROMIUM { + typedef LockDiscardableTextureCHROMIUM ValueType; + static const CommandId kCmdId = kLockDiscardableTextureCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _texture_id) { + SetHeader(); + texture_id = _texture_id; + } + + void* Set(void* cmd, GLuint _texture_id) { + static_cast<ValueType*>(cmd)->Init(_texture_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t texture_id; +}; + +static_assert(sizeof(LockDiscardableTextureCHROMIUM) == 8, + "size of LockDiscardableTextureCHROMIUM should be 8"); +static_assert(offsetof(LockDiscardableTextureCHROMIUM, header) == 0, + "offset of LockDiscardableTextureCHROMIUM header should be 0"); +static_assert( + offsetof(LockDiscardableTextureCHROMIUM, texture_id) == 4, + "offset of LockDiscardableTextureCHROMIUM texture_id should be 4"); + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 1bf9ced5675..2d00751e477 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -4434,6 +4434,21 @@ TEST_F(GLES2FormatTest, BindTexImage2DCHROMIUM) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, BindTexImage2DWithInternalformatCHROMIUM) { + cmds::BindTexImage2DWithInternalformatCHROMIUM& cmd = + *GetBufferAs<cmds::BindTexImage2DWithInternalformatCHROMIUM>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), + static_cast<GLenum>(12), static_cast<GLint>(13)); + EXPECT_EQ(static_cast<uint32_t>( + cmds::BindTexImage2DWithInternalformatCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.internalformat); + EXPECT_EQ(static_cast<GLint>(13), cmd.imageId); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, ReleaseTexImage2DCHROMIUM) { cmds::ReleaseTexImage2DCHROMIUM& cmd = *GetBufferAs<cmds::ReleaseTexImage2DCHROMIUM>(); @@ -4692,13 +4707,13 @@ TEST_F(GLES2FormatTest, ScheduleDCLayerCHROMIUM) { cmds::ScheduleDCLayerCHROMIUM& cmd = *GetBufferAs<cmds::ScheduleDCLayerCHROMIUM>(); void* next_cmd = - cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), + cmd.Set(&cmd, static_cast<GLsizei>(11), static_cast<GLuint>(12), static_cast<GLuint>(13), static_cast<GLuint>(14), static_cast<GLuint>(15), static_cast<GLuint>(16)); EXPECT_EQ(static_cast<uint32_t>(cmds::ScheduleDCLayerCHROMIUM::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<GLuint>(11), cmd.contents_texture_id); + EXPECT_EQ(static_cast<GLsizei>(11), cmd.num_textures); EXPECT_EQ(static_cast<GLuint>(12), cmd.background_color); EXPECT_EQ(static_cast<GLuint>(13), cmd.edge_aa_mask); EXPECT_EQ(static_cast<GLuint>(14), cmd.filter); @@ -5324,4 +5339,43 @@ TEST_F(GLES2FormatTest, SetEnableDCLayersCHROMIUM) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, InitializeDiscardableTextureCHROMIUM) { + cmds::InitializeDiscardableTextureCHROMIUM& cmd = + *GetBufferAs<cmds::InitializeDiscardableTextureCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13)); + EXPECT_EQ( + static_cast<uint32_t>(cmds::InitializeDiscardableTextureCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.texture_id); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.shm_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, UnlockDiscardableTextureCHROMIUM) { + cmds::UnlockDiscardableTextureCHROMIUM& cmd = + *GetBufferAs<cmds::UnlockDiscardableTextureCHROMIUM>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11)); + EXPECT_EQ( + static_cast<uint32_t>(cmds::UnlockDiscardableTextureCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.texture_id); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, LockDiscardableTextureCHROMIUM) { + cmds::LockDiscardableTextureCHROMIUM& cmd = + *GetBufferAs<cmds::LockDiscardableTextureCHROMIUM>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11)); + EXPECT_EQ(static_cast<uint32_t>(cmds::LockDiscardableTextureCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.texture_id); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_ diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index ffef2d5e609..21f3fffe477 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -281,59 +281,63 @@ OP(CreateAndConsumeTextureINTERNALImmediate) /* 522 */ \ OP(BindUniformLocationCHROMIUMBucket) /* 523 */ \ OP(BindTexImage2DCHROMIUM) /* 524 */ \ - OP(ReleaseTexImage2DCHROMIUM) /* 525 */ \ - OP(TraceBeginCHROMIUM) /* 526 */ \ - OP(TraceEndCHROMIUM) /* 527 */ \ - OP(DiscardFramebufferEXTImmediate) /* 528 */ \ - OP(LoseContextCHROMIUM) /* 529 */ \ - OP(InsertFenceSyncCHROMIUM) /* 530 */ \ - OP(WaitSyncTokenCHROMIUM) /* 531 */ \ - OP(DrawBuffersEXTImmediate) /* 532 */ \ - OP(DiscardBackbufferCHROMIUM) /* 533 */ \ - OP(ScheduleOverlayPlaneCHROMIUM) /* 534 */ \ - OP(ScheduleCALayerSharedStateCHROMIUM) /* 535 */ \ - OP(ScheduleCALayerCHROMIUM) /* 536 */ \ - OP(ScheduleCALayerInUseQueryCHROMIUMImmediate) /* 537 */ \ - OP(CommitOverlayPlanesCHROMIUM) /* 538 */ \ - OP(SwapInterval) /* 539 */ \ - OP(FlushDriverCachesCHROMIUM) /* 540 */ \ - OP(ScheduleDCLayerSharedStateCHROMIUM) /* 541 */ \ - OP(ScheduleDCLayerCHROMIUM) /* 542 */ \ - OP(MatrixLoadfCHROMIUMImmediate) /* 543 */ \ - OP(MatrixLoadIdentityCHROMIUM) /* 544 */ \ - OP(GenPathsCHROMIUM) /* 545 */ \ - OP(DeletePathsCHROMIUM) /* 546 */ \ - OP(IsPathCHROMIUM) /* 547 */ \ - OP(PathCommandsCHROMIUM) /* 548 */ \ - OP(PathParameterfCHROMIUM) /* 549 */ \ - OP(PathParameteriCHROMIUM) /* 550 */ \ - OP(PathStencilFuncCHROMIUM) /* 551 */ \ - OP(StencilFillPathCHROMIUM) /* 552 */ \ - OP(StencilStrokePathCHROMIUM) /* 553 */ \ - OP(CoverFillPathCHROMIUM) /* 554 */ \ - OP(CoverStrokePathCHROMIUM) /* 555 */ \ - OP(StencilThenCoverFillPathCHROMIUM) /* 556 */ \ - OP(StencilThenCoverStrokePathCHROMIUM) /* 557 */ \ - OP(StencilFillPathInstancedCHROMIUM) /* 558 */ \ - OP(StencilStrokePathInstancedCHROMIUM) /* 559 */ \ - OP(CoverFillPathInstancedCHROMIUM) /* 560 */ \ - OP(CoverStrokePathInstancedCHROMIUM) /* 561 */ \ - OP(StencilThenCoverFillPathInstancedCHROMIUM) /* 562 */ \ - OP(StencilThenCoverStrokePathInstancedCHROMIUM) /* 563 */ \ - OP(BindFragmentInputLocationCHROMIUMBucket) /* 564 */ \ - OP(ProgramPathFragmentInputGenCHROMIUM) /* 565 */ \ - OP(GetBufferSubDataAsyncCHROMIUM) /* 566 */ \ - OP(CoverageModulationCHROMIUM) /* 567 */ \ - OP(BlendBarrierKHR) /* 568 */ \ - OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 569 */ \ - OP(BindFragDataLocationIndexedEXTBucket) /* 570 */ \ - OP(BindFragDataLocationEXTBucket) /* 571 */ \ - OP(GetFragDataIndexEXT) /* 572 */ \ - OP(UniformMatrix4fvStreamTextureMatrixCHROMIUMImmediate) /* 573 */ \ - OP(OverlayPromotionHintCHROMIUM) /* 574 */ \ - OP(SwapBuffersWithBoundsCHROMIUMImmediate) /* 575 */ \ - OP(SetDrawRectangleCHROMIUM) /* 576 */ \ - OP(SetEnableDCLayersCHROMIUM) /* 577 */ + OP(BindTexImage2DWithInternalformatCHROMIUM) /* 525 */ \ + OP(ReleaseTexImage2DCHROMIUM) /* 526 */ \ + OP(TraceBeginCHROMIUM) /* 527 */ \ + OP(TraceEndCHROMIUM) /* 528 */ \ + OP(DiscardFramebufferEXTImmediate) /* 529 */ \ + OP(LoseContextCHROMIUM) /* 530 */ \ + OP(InsertFenceSyncCHROMIUM) /* 531 */ \ + OP(WaitSyncTokenCHROMIUM) /* 532 */ \ + OP(DrawBuffersEXTImmediate) /* 533 */ \ + OP(DiscardBackbufferCHROMIUM) /* 534 */ \ + OP(ScheduleOverlayPlaneCHROMIUM) /* 535 */ \ + OP(ScheduleCALayerSharedStateCHROMIUM) /* 536 */ \ + OP(ScheduleCALayerCHROMIUM) /* 537 */ \ + OP(ScheduleCALayerInUseQueryCHROMIUMImmediate) /* 538 */ \ + OP(CommitOverlayPlanesCHROMIUM) /* 539 */ \ + OP(SwapInterval) /* 540 */ \ + OP(FlushDriverCachesCHROMIUM) /* 541 */ \ + OP(ScheduleDCLayerSharedStateCHROMIUM) /* 542 */ \ + OP(ScheduleDCLayerCHROMIUM) /* 543 */ \ + OP(MatrixLoadfCHROMIUMImmediate) /* 544 */ \ + OP(MatrixLoadIdentityCHROMIUM) /* 545 */ \ + OP(GenPathsCHROMIUM) /* 546 */ \ + OP(DeletePathsCHROMIUM) /* 547 */ \ + OP(IsPathCHROMIUM) /* 548 */ \ + OP(PathCommandsCHROMIUM) /* 549 */ \ + OP(PathParameterfCHROMIUM) /* 550 */ \ + OP(PathParameteriCHROMIUM) /* 551 */ \ + OP(PathStencilFuncCHROMIUM) /* 552 */ \ + OP(StencilFillPathCHROMIUM) /* 553 */ \ + OP(StencilStrokePathCHROMIUM) /* 554 */ \ + OP(CoverFillPathCHROMIUM) /* 555 */ \ + OP(CoverStrokePathCHROMIUM) /* 556 */ \ + OP(StencilThenCoverFillPathCHROMIUM) /* 557 */ \ + OP(StencilThenCoverStrokePathCHROMIUM) /* 558 */ \ + OP(StencilFillPathInstancedCHROMIUM) /* 559 */ \ + OP(StencilStrokePathInstancedCHROMIUM) /* 560 */ \ + OP(CoverFillPathInstancedCHROMIUM) /* 561 */ \ + OP(CoverStrokePathInstancedCHROMIUM) /* 562 */ \ + OP(StencilThenCoverFillPathInstancedCHROMIUM) /* 563 */ \ + OP(StencilThenCoverStrokePathInstancedCHROMIUM) /* 564 */ \ + OP(BindFragmentInputLocationCHROMIUMBucket) /* 565 */ \ + OP(ProgramPathFragmentInputGenCHROMIUM) /* 566 */ \ + OP(GetBufferSubDataAsyncCHROMIUM) /* 567 */ \ + OP(CoverageModulationCHROMIUM) /* 568 */ \ + OP(BlendBarrierKHR) /* 569 */ \ + OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 570 */ \ + OP(BindFragDataLocationIndexedEXTBucket) /* 571 */ \ + OP(BindFragDataLocationEXTBucket) /* 572 */ \ + OP(GetFragDataIndexEXT) /* 573 */ \ + OP(UniformMatrix4fvStreamTextureMatrixCHROMIUMImmediate) /* 574 */ \ + OP(OverlayPromotionHintCHROMIUM) /* 575 */ \ + OP(SwapBuffersWithBoundsCHROMIUMImmediate) /* 576 */ \ + OP(SetDrawRectangleCHROMIUM) /* 577 */ \ + OP(SetEnableDCLayersCHROMIUM) /* 578 */ \ + OP(InitializeDiscardableTextureCHROMIUM) /* 579 */ \ + OP(UnlockDiscardableTextureCHROMIUM) /* 580 */ \ + OP(LockDiscardableTextureCHROMIUM) /* 581 */ enum CommandId { kOneBeforeStartPoint = diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc b/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc index 92b2c4bb92a..bcf61504aa5 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc +++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils.cc @@ -1471,6 +1471,7 @@ void GLES2Util::GetColorFormatComponentSizes( case GL_R16F: case GL_R16UI: case GL_R16I: + case GL_R16_EXT: *r = 16; break; case GL_R32F: @@ -1765,6 +1766,8 @@ uint32_t GLES2Util::ConvertToSizedFormat(uint32_t format, uint32_t type) { return GL_R16F; case GL_FLOAT: return GL_R32F; + case GL_UNSIGNED_SHORT: + return GL_R16_EXT; default: NOTREACHED(); break; diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils.h b/chromium/gpu/command_buffer/common/gles2_cmd_utils.h index cd74561267a..6375f9d8600 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_utils.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils.h @@ -257,7 +257,7 @@ class GLES2_UTILS_EXPORT GLES2Util { unsigned int elements_per_unit, uint32_t* dst); - #include "../common/gles2_cmd_utils_autogen.h" +#include "gpu/command_buffer/common/gles2_cmd_utils_autogen.h" private: static std::string GetQualifiedEnumString( diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 104637b5d4a..ba8396bdeab 100644 --- a/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/chromium/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -16,7 +16,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0, "GL_FALSE", }, { - 0x00, "GL_CLOSE_PATH_CHROMIUM", + 0x00, "GL_CLOSE_PATH_NV", }, { 0x0000, "GL_POINTS", @@ -31,13 +31,13 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x00000002, "GL_CONTEXT_FLAG_DEBUG_BIT_KHR", }, { - 0x00000004, "GL_GEOMETRY_SHADER_BIT_EXT", + 0x00000004, "GL_GEOMETRY_SHADER_BIT_OES", }, { - 0x00000008, "GL_TESS_CONTROL_SHADER_BIT_EXT", + 0x00000008, "GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR", }, { - 0x00000010, "GL_TESS_EVALUATION_SHADER_BIT_EXT", + 0x00000010, "GL_TESS_EVALUATION_SHADER_BIT_OES", }, { 0x00000020, "GL_COLOR_BUFFER_BIT5_QCOM", @@ -76,13 +76,13 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0001, "GL_LINES", }, { - 0x00010000, "GL_STENCIL_BUFFER_BIT0_QCOM", + 0x00010000, "GL_FONT_X_MIN_BOUNDS_BIT_NV", }, { 0x0002, "GL_LINE_LOOP", }, { - 0x00020000, "GL_STENCIL_BUFFER_BIT1_QCOM", + 0x00020000, "GL_FONT_Y_MIN_BOUNDS_BIT_NV", }, { 0x0003, "GL_LINE_STRIP", @@ -91,7 +91,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0004, "GL_TRIANGLES", }, { - 0x00040000, "GL_STENCIL_BUFFER_BIT2_QCOM", + 0x00040000, "GL_FONT_X_MAX_BOUNDS_BIT_NV", }, { 0x0005, "GL_TRIANGLE_STRIP", @@ -100,58 +100,70 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0006, "GL_TRIANGLE_FAN", }, { - 0x0007, "GL_QUADS_EXT", + 0x0007, "GL_QUADS_OES", }, { 0x0008, "GL_MAP_INVALIDATE_BUFFER_BIT_EXT", }, { - 0x00080000, "GL_STENCIL_BUFFER_BIT3_QCOM", + 0x00080000, "GL_FONT_Y_MAX_BOUNDS_BIT_NV", }, { - 0x000A, "GL_LINES_ADJACENCY_EXT", + 0x000A, "GL_LINES_ADJACENCY_OES", }, { - 0x000B, "GL_LINE_STRIP_ADJACENCY_EXT", + 0x000B, "GL_LINE_STRIP_ADJACENCY_OES", }, { - 0x000C, "GL_TRIANGLES_ADJACENCY_EXT", + 0x000C, "GL_TRIANGLES_ADJACENCY_OES", }, { - 0x000D, "GL_TRIANGLE_STRIP_ADJACENCY_EXT", + 0x000D, "GL_TRIANGLE_STRIP_ADJACENCY_OES", }, { - 0x000E, "GL_PATCHES_EXT", + 0x000E, "GL_PATCHES_OES", }, { 0x0010, "GL_MAP_FLUSH_EXPLICIT_BIT_EXT", }, { - 0x00100000, "GL_STENCIL_BUFFER_BIT4_QCOM", + 0x00100000, "GL_FONT_UNITS_PER_EM_BIT_NV", }, { 0x0020, "GL_MAP_UNSYNCHRONIZED_BIT_EXT", }, { - 0x00200000, "GL_STENCIL_BUFFER_BIT5_QCOM", + 0x00200000, "GL_FONT_ASCENDER_BIT_NV", }, { - 0x00400000, "GL_STENCIL_BUFFER_BIT6_QCOM", + 0x0040, "GL_MAP_PERSISTENT_BIT_EXT", }, { - 0x00800000, "GL_STENCIL_BUFFER_BIT7_QCOM", + 0x00400000, "GL_FONT_DESCENDER_BIT_NV", }, { - 0x01000000, "GL_MULTISAMPLE_BUFFER_BIT0_QCOM", + 0x0080, "GL_MAP_COHERENT_BIT_EXT", }, { - 0x02, "GL_MOVE_TO_CHROMIUM", + 0x00800000, "GL_FONT_HEIGHT_BIT_NV", + }, + { + 0x01, "GL_BOLD_BIT_NV", + }, + { + 0x0100, "GL_DYNAMIC_STORAGE_BIT_EXT", + }, + { + 0x01000000, "GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV", + }, + { + 0x02, "GL_MOVE_TO_NV", }, { 0x0200, "GL_NEVER", }, { - 0x02000000, "GL_MULTISAMPLE_BUFFER_BIT1_QCOM", + 0x02000000, "GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV", }, { 0x0201, "GL_LESS", @@ -175,6 +187,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0207, "GL_ALWAYS", }, { + 0x03, "GL_RELATIVE_MOVE_TO_NV", + }, + { 0x0300, "GL_SRC_COLOR", }, { @@ -202,10 +217,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0308, "GL_SRC_ALPHA_SATURATE", }, { - 0x04, "GL_LINE_TO_CHROMIUM", + 0x04, "GL_LINE_TO_NV", }, { - 0x04000000, "GL_MULTISAMPLE_BUFFER_BIT2_QCOM", + 0x04000000, "GL_FONT_UNDERLINE_POSITION_BIT_NV", }, { 0x0404, "GL_FRONT", @@ -217,6 +232,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0408, "GL_FRONT_AND_BACK", }, { + 0x05, "GL_RELATIVE_LINE_TO_NV", + }, + { 0x0500, "GL_INVALID_ENUM", }, { @@ -241,7 +259,19 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0507, "GL_CONTEXT_LOST_KHR", }, { - 0x08000000, "GL_MULTISAMPLE_BUFFER_BIT3_QCOM", + 0x06, "GL_HORIZONTAL_LINE_TO_NV", + }, + { + 0x07, "GL_RELATIVE_HORIZONTAL_LINE_TO_NV", + }, + { + 0x08, "GL_VERTICAL_LINE_TO_NV", + }, + { + 0x08000000, "GL_FONT_UNDERLINE_THICKNESS_BIT_NV", + }, + { + 0x09, "GL_RELATIVE_VERTICAL_LINE_TO_NV", }, { 0x0900, "GL_CW", @@ -250,12 +280,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0901, "GL_CCW", }, { - 0x0A, "GL_QUADRATIC_CURVE_TO_CHROMIUM", + 0x0A, "GL_QUADRATIC_CURVE_TO_NV", + }, + { + 0x0B, "GL_RELATIVE_QUADRATIC_CURVE_TO_NV", }, { 0x0B21, "GL_LINE_WIDTH", }, { + 0x0B40, "GL_POLYGON_MODE_NV", + }, + { 0x0B44, "GL_CULL_FACE", }, { @@ -310,10 +346,16 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0BA2, "GL_VIEWPORT", }, { - 0x0BA6, "GL_PATH_MODELVIEW_MATRIX_CHROMIUM", + 0x0BA3, "GL_PATH_MODELVIEW_STACK_DEPTH_NV", + }, + { + 0x0BA4, "GL_PATH_PROJECTION_STACK_DEPTH_NV", + }, + { + 0x0BA6, "GL_PATH_MODELVIEW_MATRIX_NV", }, { - 0x0BA7, "GL_PATH_PROJECTION_MATRIX_CHROMIUM", + 0x0BA7, "GL_PATH_PROJECTION_MATRIX_NV", }, { 0x0BC0, "GL_ALPHA_TEST_QCOM", @@ -331,7 +373,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0BE2, "GL_BLEND", }, { - 0x0C, "GL_CUBIC_CURVE_TO_CHROMIUM", + 0x0C, "GL_CUBIC_CURVE_TO_NV", }, { 0x0C01, "GL_DRAW_BUFFER_EXT", @@ -364,6 +406,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0CF5, "GL_UNPACK_ALIGNMENT", }, { + 0x0D, "GL_RELATIVE_CUBIC_CURVE_TO_NV", + }, + { 0x0D02, "GL_PACK_ROW_LENGTH", }, { @@ -382,6 +427,12 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0D33, "GL_MAX_TEXTURE_SIZE", }, { + 0x0D36, "GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV", + }, + { + 0x0D38, "GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV", + }, + { 0x0D3A, "GL_MAX_VIEWPORT_DIMS", }, { @@ -409,13 +460,28 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x0DE1, "GL_TEXTURE_2D", }, { + 0x0E, "GL_SMOOTH_QUADRATIC_CURVE_TO_NV", + }, + { + 0x0F, "GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV", + }, + { 0x1, "GL_CA_LAYER_EDGE_LEFT_CHROMIUM", }, { - 0x10000000, "GL_MULTISAMPLE_BUFFER_BIT4_QCOM", + 0x10, "GL_SMOOTH_CUBIC_CURVE_TO_NV", + }, + { + 0x100, "GL_GLYPH_HAS_KERNING_BIT_NV", + }, + { + 0x10000000, "GL_FONT_HAS_KERNING_BIT_NV", }, { - 0x1004, "GL_TEXTURE_BORDER_COLOR_EXT", + 0x1004, "GL_TEXTURE_BORDER_COLOR_OES", + }, + { + 0x11, "GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV", }, { 0x1100, "GL_DONT_CARE", @@ -427,6 +493,15 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x1102, "GL_NICEST", }, { + 0x12, "GL_SMALL_CCW_ARC_TO_NV", + }, + { + 0x13, "GL_RELATIVE_SMALL_CCW_ARC_TO_NV", + }, + { + 0x14, "GL_SMALL_CW_ARC_TO_NV", + }, + { 0x1400, "GL_BYTE", }, { @@ -454,21 +529,39 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x140C, "GL_FIXED", }, { + 0x140E, "GL_INT64_NV", + }, + { + 0x140F, "GL_UNSIGNED_INT64_NV", + }, + { + 0x15, "GL_RELATIVE_SMALL_CW_ARC_TO_NV", + }, + { 0x1506, "GL_XOR_NV", }, { 0x150A, "GL_INVERT", }, { - 0x1700, "GL_PATH_MODELVIEW_CHROMIUM", + 0x16, "GL_LARGE_CCW_ARC_TO_NV", + }, + { + 0x17, "GL_RELATIVE_LARGE_CCW_ARC_TO_NV", }, { - 0x1701, "GL_PATH_PROJECTION_CHROMIUM", + 0x1700, "GL_PATH_MODELVIEW_NV", + }, + { + 0x1701, "GL_PATH_PROJECTION_NV", }, { 0x1702, "GL_TEXTURE", }, { + 0x18, "GL_LARGE_CW_ARC_TO_NV", + }, + { 0x1800, "GL_COLOR_EXT", }, { @@ -478,6 +571,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x1802, "GL_STENCIL_EXT", }, { + 0x19, "GL_RELATIVE_LARGE_CW_ARC_TO_NV", + }, + { 0x1901, "GL_STENCIL_INDEX_OES", }, { @@ -508,7 +604,19 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x190A, "GL_LUMINANCE_ALPHA", }, { - 0x1A, "GL_CONIC_CURVE_TO_CHROMIUM", + 0x1A, "GL_CONIC_CURVE_TO_NV", + }, + { + 0x1B, "GL_RELATIVE_CONIC_CURVE_TO_NV", + }, + { + 0x1B00, "GL_POINT_NV", + }, + { + 0x1B01, "GL_LINE_NV", + }, + { + 0x1B02, "GL_FILL_NV", }, { 0x1D00, "GL_FLAT_CHROMIUM", @@ -541,7 +649,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x2, "GL_CA_LAYER_EDGE_RIGHT_CHROMIUM", }, { - 0x20000000, "GL_MULTISAMPLE_BUFFER_BIT5_QCOM", + 0x20, "GL_GLYPH_VERTICAL_BEARING_X_BIT_NV", + }, + { + 0x20000000, "GL_FONT_NUM_GLYPH_INDICES_BIT_NV", }, { 0x2400, "GL_EYE_LINEAR_CHROMIUM", @@ -586,6 +697,12 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x2A00, "GL_POLYGON_OFFSET_UNITS", }, { + 0x2A01, "GL_POLYGON_OFFSET_POINT_NV", + }, + { + 0x2A02, "GL_POLYGON_OFFSET_LINE_NV", + }, + { 0x3000, "GL_CLIP_DISTANCE0_APPLE", }, { @@ -616,6 +733,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x4, "GL_CA_LAYER_EDGE_BOTTOM_CHROMIUM", }, { + 0x40, "GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV", + }, + { 0x40000000, "GL_MULTISAMPLE_BUFFER_BIT6_QCOM", }, { @@ -655,6 +775,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8, "GL_CA_LAYER_EDGE_TOP_CHROMIUM", }, { + 0x80, "GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV", + }, + { 0x80000000, "GL_MULTISAMPLE_BUFFER_BIT7_QCOM", }, { @@ -676,10 +799,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8006, "GL_FUNC_ADD", }, { - 0x8007, "GL_MIN_EXT", + 0x8007, "GL_MIN", }, { - 0x8008, "GL_MAX_EXT", + 0x8008, "GL_MAX", }, { 0x8009, "GL_BLEND_EQUATION", @@ -721,6 +844,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8052, "GL_RGB10_EXT", }, { + 0x8054, "GL_RGB16_EXT", + }, + { 0x8056, "GL_RGBA4", }, { @@ -733,6 +859,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8059, "GL_RGB10_A2_EXT", }, { + 0x805B, "GL_RGBA16_EXT", + }, + { 0x8069, "GL_TEXTURE_BINDING_2D", }, { @@ -802,7 +931,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x80E9, "GL_MAX_ELEMENTS_INDICES", }, { - 0x812D, "GL_CLAMP_TO_BORDER_EXT", + 0x812D, "GL_CLAMP_TO_BORDER_OES", }, { 0x812F, "GL_CLAMP_TO_EDGE", @@ -874,7 +1003,13 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x821D, "GL_NUM_EXTENSIONS", }, { - 0x8221, "GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED", + 0x821F, "GL_BUFFER_IMMUTABLE_STORAGE_EXT", + }, + { + 0x8220, "GL_BUFFER_STORAGE_FLAGS_EXT", + }, + { + 0x8221, "GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES", }, { 0x8227, "GL_RG_EXT", @@ -886,9 +1021,15 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8229, "GL_R8_EXT", }, { + 0x822A, "GL_R16_EXT", + }, + { 0x822B, "GL_RG8_EXT", }, { + 0x822C, "GL_RG16_EXT", + }, + { 0x822D, "GL_R16F_EXT", }, { @@ -1012,10 +1153,22 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x825A, "GL_PROGRAM_PIPELINE_BINDING_EXT", }, { - 0x825E, "GL_LAYER_PROVOKING_VERTEX_EXT", + 0x825B, "GL_MAX_VIEWPORTS_OES", + }, + { + 0x825C, "GL_VIEWPORT_SUBPIXEL_BITS_OES", + }, + { + 0x825D, "GL_VIEWPORT_BOUNDS_RANGE_OES", + }, + { + 0x825E, "GL_LAYER_PROVOKING_VERTEX_OES", + }, + { + 0x825F, "GL_VIEWPORT_INDEX_PROVOKING_VERTEX_OES", }, { - 0x8260, "GL_UNDEFINED_VERTEX_EXT", + 0x8260, "GL_UNDEFINED_VERTEX_OES", }, { 0x8261, "GL_NO_RESET_NOTIFICATION_KHR", @@ -1039,16 +1192,16 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x826D, "GL_DEBUG_GROUP_STACK_DEPTH_KHR", }, { - 0x82DB, "GL_TEXTURE_VIEW_MIN_LEVEL_EXT", + 0x82DB, "GL_TEXTURE_VIEW_MIN_LEVEL_OES", }, { - 0x82DC, "GL_TEXTURE_VIEW_NUM_LEVELS_EXT", + 0x82DC, "GL_TEXTURE_VIEW_NUM_LEVELS_OES", }, { - 0x82DD, "GL_TEXTURE_VIEW_MIN_LAYER_EXT", + 0x82DD, "GL_TEXTURE_VIEW_MIN_LAYER_OES", }, { - 0x82DE, "GL_TEXTURE_VIEW_NUM_LAYERS_EXT", + 0x82DE, "GL_TEXTURE_VIEW_NUM_LAYERS_OES", }, { 0x82DF, "GL_TEXTURE_IMMUTABLE_LEVELS", @@ -1066,12 +1219,21 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x82E3, "GL_QUERY_KHR", }, { + 0x82E4, "GL_PROGRAM_PIPELINE_KHR", + }, + { 0x82E6, "GL_SAMPLER_KHR", }, { 0x82E8, "GL_MAX_LABEL_LENGTH_KHR", }, { + 0x82F9, "GL_MAX_CULL_DISTANCES_EXT", + }, + { + 0x82FA, "GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT", + }, + { 0x82FB, "GL_CONTEXT_RELEASE_BEHAVIOR_KHR", }, { @@ -1114,6 +1276,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x83FB, "GL_PERFQUERY_WAIT_INTEL", }, { + 0x83FE, "GL_CONSERVATIVE_RASTERIZATION_INTEL", + }, + { 0x846D, "GL_ALIASED_POINT_SIZE_RANGE", }, { @@ -1219,6 +1384,12 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x84E0, "GL_ACTIVE_TEXTURE", }, { + 0x84E3, "GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV", + }, + { + 0x84E4, "GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV", + }, + { 0x84E8, "GL_MAX_RENDERBUFFER_SIZE", }, { @@ -1480,16 +1651,16 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED", }, { - 0x886C, "GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT", + 0x886C, "GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES", }, { - 0x886D, "GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT", + 0x886D, "GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES", }, { 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS", }, { - 0x887F, "GL_GEOMETRY_SHADER_INVOCATIONS_EXT", + 0x887F, "GL_GEOMETRY_SHADER_INVOCATIONS_OES", }, { 0x8892, "GL_ARRAY_BUFFER", @@ -1600,13 +1771,13 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8914, "GL_SAMPLES_PASSED_ARB", }, { - 0x8916, "GL_GEOMETRY_LINKED_VERTICES_OUT_EXT", + 0x8916, "GL_GEOMETRY_LINKED_VERTICES_OUT_OES", }, { - 0x8917, "GL_GEOMETRY_LINKED_INPUT_TYPE_EXT", + 0x8917, "GL_GEOMETRY_LINKED_INPUT_TYPE_OES", }, { - 0x8918, "GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT", + 0x8918, "GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES", }, { 0x8919, "GL_SAMPLER_BINDING", @@ -1630,7 +1801,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8A2B, "GL_MAX_VERTEX_UNIFORM_BLOCKS", }, { - 0x8A2C, "GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT", + 0x8A2C, "GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES", }, { 0x8A2D, "GL_MAX_FRAGMENT_UNIFORM_BLOCKS", @@ -1648,7 +1819,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8A31, "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", }, { - 0x8A32, "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT", + 0x8A32, "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES", }, { 0x8A33, "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", @@ -1975,6 +2146,12 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8BDC, "GL_STATE_RESTORE", }, { + 0x8BE7, "GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT", + }, + { + 0x8BFA, "GL_TEXTURE_PROTECTED_EXT", + }, + { 0x8C00, "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG", }, { @@ -1999,19 +2176,19 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8C1D, "GL_TEXTURE_BINDING_2D_ARRAY", }, { - 0x8C29, "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT", + 0x8C29, "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES", }, { - 0x8C2A, "GL_TEXTURE_BUFFER_EXT", + 0x8C2A, "GL_TEXTURE_BUFFER_OES", }, { - 0x8C2B, "GL_MAX_TEXTURE_BUFFER_SIZE_EXT", + 0x8C2B, "GL_MAX_TEXTURE_BUFFER_SIZE_OES", }, { - 0x8C2C, "GL_TEXTURE_BINDING_BUFFER_EXT", + 0x8C2C, "GL_TEXTURE_BINDING_BUFFER_OES", }, { - 0x8C2D, "GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT", + 0x8C2D, "GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES", }, { 0x8C2F, "GL_ANY_SAMPLES_PASSED_EXT", @@ -2089,7 +2266,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8C85, "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE", }, { - 0x8C87, "GL_PRIMITIVES_GENERATED_EXT", + 0x8C87, "GL_PRIMITIVES_GENERATED_OES", }, { 0x8C88, "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN", @@ -2236,6 +2413,54 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8CEF, "GL_COLOR_ATTACHMENT15_EXT", }, { + 0x8CF0, "GL_COLOR_ATTACHMENT16", + }, + { + 0x8CF1, "GL_COLOR_ATTACHMENT17", + }, + { + 0x8CF2, "GL_COLOR_ATTACHMENT18", + }, + { + 0x8CF3, "GL_COLOR_ATTACHMENT19", + }, + { + 0x8CF4, "GL_COLOR_ATTACHMENT20", + }, + { + 0x8CF5, "GL_COLOR_ATTACHMENT21", + }, + { + 0x8CF6, "GL_COLOR_ATTACHMENT22", + }, + { + 0x8CF7, "GL_COLOR_ATTACHMENT23", + }, + { + 0x8CF8, "GL_COLOR_ATTACHMENT24", + }, + { + 0x8CF9, "GL_COLOR_ATTACHMENT25", + }, + { + 0x8CFA, "GL_COLOR_ATTACHMENT26", + }, + { + 0x8CFB, "GL_COLOR_ATTACHMENT27", + }, + { + 0x8CFC, "GL_COLOR_ATTACHMENT28", + }, + { + 0x8CFD, "GL_COLOR_ATTACHMENT29", + }, + { + 0x8CFE, "GL_COLOR_ATTACHMENT30", + }, + { + 0x8CFF, "GL_COLOR_ATTACHMENT31", + }, + { 0x8D00, "GL_DEPTH_ATTACHMENT", }, { @@ -2371,10 +2596,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8D9F, "GL_INT_2_10_10_10_REV", }, { - 0x8DA7, "GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT", + 0x8DA7, "GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES", }, { - 0x8DA8, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT", + 0x8DA8, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES", }, { 0x8DAD, "GL_FLOAT_32_UNSIGNED_INT_24_8_REV", @@ -2386,7 +2611,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8DC1, "GL_SAMPLER_2D_ARRAY", }, { - 0x8DC2, "GL_SAMPLER_BUFFER_EXT", + 0x8DC2, "GL_SAMPLER_BUFFER_OES", }, { 0x8DC4, "GL_SAMPLER_2D_ARRAY_SHADOW_NV", @@ -2416,7 +2641,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8DCF, "GL_INT_SAMPLER_2D_ARRAY", }, { - 0x8DD0, "GL_INT_SAMPLER_BUFFER_EXT", + 0x8DD0, "GL_INT_SAMPLER_BUFFER_OES", }, { 0x8DD2, "GL_UNSIGNED_INT_SAMPLER_2D", @@ -2431,19 +2656,19 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8DD7, "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY", }, { - 0x8DD8, "GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT", + 0x8DD8, "GL_UNSIGNED_INT_SAMPLER_BUFFER_OES", }, { - 0x8DD9, "GL_GEOMETRY_SHADER_EXT", + 0x8DD9, "GL_GEOMETRY_SHADER_OES", }, { - 0x8DDF, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT", + 0x8DDF, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES", }, { - 0x8DE0, "GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT", + 0x8DE0, "GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES", }, { - 0x8DE1, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT", + 0x8DE1, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES", }, { 0x8DF0, "GL_LOW_FLOAT", @@ -2488,10 +2713,28 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8DFD, "GL_MAX_FRAGMENT_UNIFORM_VECTORS", }, { - 0x8E1E, "GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT", + 0x8E13, "GL_QUERY_WAIT_NV", + }, + { + 0x8E14, "GL_QUERY_NO_WAIT_NV", + }, + { + 0x8E15, "GL_QUERY_BY_REGION_WAIT_NV", + }, + { + 0x8E16, "GL_QUERY_BY_REGION_NO_WAIT_NV", + }, + { + 0x8E1B, "GL_POLYGON_OFFSET_CLAMP_EXT", + }, + { + 0x8E1E, "GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES", + }, + { + 0x8E1F, "GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES", }, { - 0x8E1F, "GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT", + 0x8E20, "GL_COLOR_SAMPLES_NV", }, { 0x8E22, "GL_TRANSFORM_FEEDBACK", @@ -2524,13 +2767,16 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8E45, "GL_TEXTURE_SWIZZLE_A", }, { - 0x8E4D, "GL_FIRST_VERTEX_CONVENTION_EXT", + 0x8E4D, "GL_FIRST_VERTEX_CONVENTION_OES", + }, + { + 0x8E4E, "GL_LAST_VERTEX_CONVENTION_OES", }, { - 0x8E4E, "GL_LAST_VERTEX_CONVENTION_EXT", + 0x8E50, "GL_SAMPLE_LOCATION_NV", }, { - 0x8E5A, "GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT", + 0x8E5A, "GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES", }, { 0x8E5B, "GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES", @@ -2542,73 +2788,73 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8E5D, "GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES", }, { - 0x8E72, "GL_PATCH_VERTICES_EXT", + 0x8E72, "GL_PATCH_VERTICES_OES", }, { - 0x8E75, "GL_TESS_CONTROL_OUTPUT_VERTICES_EXT", + 0x8E75, "GL_TESS_CONTROL_OUTPUT_VERTICES_OES", }, { - 0x8E76, "GL_TESS_GEN_MODE_EXT", + 0x8E76, "GL_TESS_GEN_MODE_OES", }, { - 0x8E77, "GL_TESS_GEN_SPACING_EXT", + 0x8E77, "GL_TESS_GEN_SPACING_OES", }, { - 0x8E78, "GL_TESS_GEN_VERTEX_ORDER_EXT", + 0x8E78, "GL_TESS_GEN_VERTEX_ORDER_OES", }, { - 0x8E79, "GL_TESS_GEN_POINT_MODE_EXT", + 0x8E79, "GL_TESS_GEN_POINT_MODE_OES", }, { - 0x8E7A, "GL_ISOLINES_EXT", + 0x8E7A, "GL_ISOLINES_OES", }, { - 0x8E7B, "GL_FRACTIONAL_ODD_EXT", + 0x8E7B, "GL_FRACTIONAL_ODD_OES", }, { - 0x8E7C, "GL_FRACTIONAL_EVEN_EXT", + 0x8E7C, "GL_FRACTIONAL_EVEN_OES", }, { - 0x8E7D, "GL_MAX_PATCH_VERTICES_EXT", + 0x8E7D, "GL_MAX_PATCH_VERTICES_OES", }, { - 0x8E7E, "GL_MAX_TESS_GEN_LEVEL_EXT", + 0x8E7E, "GL_MAX_TESS_GEN_LEVEL_OES", }, { - 0x8E7F, "GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT", + 0x8E7F, "GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES", }, { - 0x8E80, "GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT", + 0x8E80, "GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES", }, { - 0x8E81, "GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT", + 0x8E81, "GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES", }, { - 0x8E82, "GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT", + 0x8E82, "GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES", }, { - 0x8E83, "GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT", + 0x8E83, "GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES", }, { - 0x8E84, "GL_MAX_TESS_PATCH_COMPONENTS_EXT", + 0x8E84, "GL_MAX_TESS_PATCH_COMPONENTS_OES", }, { - 0x8E85, "GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT", + 0x8E85, "GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES", }, { - 0x8E86, "GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT", + 0x8E86, "GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES", }, { - 0x8E87, "GL_TESS_EVALUATION_SHADER_EXT", + 0x8E87, "GL_TESS_EVALUATION_SHADER_OES", }, { - 0x8E88, "GL_TESS_CONTROL_SHADER_EXT", + 0x8E88, "GL_TESS_CONTROL_SHADER_OES", }, { - 0x8E89, "GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT", + 0x8E89, "GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES", }, { - 0x8E8A, "GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT", + 0x8E8A, "GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES", }, { 0x8ED0, "GL_COVERAGE_COMPONENT_NV", @@ -2635,6 +2881,24 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8ED7, "GL_COVERAGE_AUTOMATIC_NV", }, { + 0x8F10, "GL_INCLUSIVE_EXT", + }, + { + 0x8F11, "GL_EXCLUSIVE_EXT", + }, + { + 0x8F12, "GL_WINDOW_RECTANGLE_EXT", + }, + { + 0x8F13, "GL_WINDOW_RECTANGLE_MODE_EXT", + }, + { + 0x8F14, "GL_MAX_WINDOW_RECTANGLES_EXT", + }, + { + 0x8F15, "GL_NUM_WINDOW_RECTANGLES_EXT", + }, + { 0x8F36, "GL_COPY_READ_BUFFER_NV", }, { @@ -2662,6 +2926,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8F67, "GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT", }, { + 0x8F69, "GL_TEXTURE_ASTC_DECODE_PRECISION_EXT", + }, + { 0x8F94, "GL_R8_SNORM", }, { @@ -2674,6 +2941,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8F97, "GL_RGBA8_SNORM", }, { + 0x8F98, "GL_R16_SNORM_EXT", + }, + { + 0x8F99, "GL_RG16_SNORM_EXT", + }, + { + 0x8F9A, "GL_RGB16_SNORM_EXT", + }, + { + 0x8F9B, "GL_RGBA16_SNORM_EXT", + }, + { 0x8F9C, "GL_SIGNED_NORMALIZED", }, { @@ -2695,136 +2974,355 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x8FBB, "GL_GPU_DISJOINT_EXT", }, { + 0x8FBD, "GL_SR8_EXT", + }, + { + 0x8FBE, "GL_SRG8_EXT", + }, + { 0x8FC4, "GL_SHADER_BINARY_VIV", }, { - 0x9009, "GL_TEXTURE_CUBE_MAP_ARRAY_EXT", + 0x8FE0, "GL_INT8_NV", + }, + { + 0x8FE1, "GL_INT8_VEC2_NV", + }, + { + 0x8FE2, "GL_INT8_VEC3_NV", + }, + { + 0x8FE3, "GL_INT8_VEC4_NV", + }, + { + 0x8FE4, "GL_INT16_NV", }, { - 0x900A, "GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT", + 0x8FE5, "GL_INT16_VEC2_NV", }, { - 0x900C, "GL_SAMPLER_CUBE_MAP_ARRAY_EXT", + 0x8FE6, "GL_INT16_VEC3_NV", }, { - 0x900D, "GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT", + 0x8FE7, "GL_INT16_VEC4_NV", }, { - 0x900E, "GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT", + 0x8FE9, "GL_INT64_VEC2_NV", }, { - 0x900F, "GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT", + 0x8FEA, "GL_INT64_VEC3_NV", }, { - 0x9051, "GL_IMAGE_BUFFER_EXT", + 0x8FEB, "GL_INT64_VEC4_NV", }, { - 0x9054, "GL_IMAGE_CUBE_MAP_ARRAY_EXT", + 0x8FEC, "GL_UNSIGNED_INT8_NV", }, { - 0x905C, "GL_INT_IMAGE_BUFFER_EXT", + 0x8FED, "GL_UNSIGNED_INT8_VEC2_NV", }, { - 0x905F, "GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT", + 0x8FEE, "GL_UNSIGNED_INT8_VEC3_NV", }, { - 0x9067, "GL_UNSIGNED_INT_IMAGE_BUFFER_EXT", + 0x8FEF, "GL_UNSIGNED_INT8_VEC4_NV", }, { - 0x906A, "GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT", + 0x8FF0, "GL_UNSIGNED_INT16_NV", + }, + { + 0x8FF1, "GL_UNSIGNED_INT16_VEC2_NV", + }, + { + 0x8FF2, "GL_UNSIGNED_INT16_VEC3_NV", + }, + { + 0x8FF3, "GL_UNSIGNED_INT16_VEC4_NV", + }, + { + 0x8FF5, "GL_UNSIGNED_INT64_VEC2_NV", + }, + { + 0x8FF6, "GL_UNSIGNED_INT64_VEC3_NV", + }, + { + 0x8FF7, "GL_UNSIGNED_INT64_VEC4_NV", + }, + { + 0x8FF8, "GL_FLOAT16_NV", + }, + { + 0x8FF9, "GL_FLOAT16_VEC2_NV", + }, + { + 0x8FFA, "GL_FLOAT16_VEC3_NV", + }, + { + 0x8FFB, "GL_FLOAT16_VEC4_NV", + }, + { + 0x9009, "GL_TEXTURE_CUBE_MAP_ARRAY_OES", + }, + { + 0x900A, "GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES", + }, + { + 0x900C, "GL_SAMPLER_CUBE_MAP_ARRAY_OES", + }, + { + 0x900D, "GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES", + }, + { + 0x900E, "GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES", + }, + { + 0x900F, "GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES", + }, + { + 0x9051, "GL_IMAGE_BUFFER_OES", + }, + { + 0x9054, "GL_IMAGE_CUBE_MAP_ARRAY_OES", + }, + { + 0x905C, "GL_INT_IMAGE_BUFFER_OES", + }, + { + 0x905F, "GL_INT_IMAGE_CUBE_MAP_ARRAY_OES", + }, + { + 0x9067, "GL_UNSIGNED_INT_IMAGE_BUFFER_OES", + }, + { + 0x906A, "GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES", }, { 0x906F, "GL_RGB10_A2UI", }, { - 0x9075, "GL_PATH_STROKE_WIDTH_CHROMIUM", + 0x9070, "GL_PATH_FORMAT_SVG_NV", + }, + { + 0x9071, "GL_PATH_FORMAT_PS_NV", + }, + { + 0x9072, "GL_STANDARD_FONT_NAME_NV", + }, + { + 0x9073, "GL_SYSTEM_FONT_NAME_NV", + }, + { + 0x9074, "GL_FILE_NAME_NV", + }, + { + 0x9075, "GL_PATH_STROKE_WIDTH_NV", + }, + { + 0x9076, "GL_PATH_END_CAPS_NV", + }, + { + 0x9077, "GL_PATH_INITIAL_END_CAP_NV", + }, + { + 0x9078, "GL_PATH_TERMINAL_END_CAP_NV", + }, + { + 0x9079, "GL_PATH_JOIN_STYLE_NV", + }, + { + 0x907A, "GL_PATH_MITER_LIMIT_NV", + }, + { + 0x907B, "GL_PATH_DASH_CAPS_NV", + }, + { + 0x907C, "GL_PATH_INITIAL_DASH_CAP_NV", + }, + { + 0x907D, "GL_PATH_TERMINAL_DASH_CAP_NV", }, { - 0x9076, "GL_PATH_END_CAPS_CHROMIUM", + 0x907E, "GL_PATH_DASH_OFFSET_NV", }, { - 0x9079, "GL_PATH_JOIN_STYLE_CHROMIUM", + 0x907F, "GL_PATH_CLIENT_LENGTH_NV", }, { 0x907a, "GL_PATH_MITER_LIMIT_CHROMIUM", }, { + 0x9080, "GL_PATH_FILL_MODE_NV", + }, + { + 0x9081, "GL_PATH_FILL_MASK_NV", + }, + { + 0x9082, "GL_PATH_FILL_COVER_MODE_NV", + }, + { + 0x9083, "GL_PATH_STROKE_COVER_MODE_NV", + }, + { + 0x9084, "GL_PATH_STROKE_MASK_NV", + }, + { 0x9086, "GL_PATH_STROKE_BOUND_CHROMIUM", }, { - 0x9088, "GL_COUNT_UP_CHROMIUM", + 0x9088, "GL_COUNT_UP_NV", + }, + { + 0x9089, "GL_COUNT_DOWN_NV", + }, + { + 0x908A, "GL_PATH_OBJECT_BOUNDING_BOX_NV", + }, + { + 0x908B, "GL_CONVEX_HULL_NV", + }, + { + 0x908D, "GL_BOUNDING_BOX_NV", + }, + { + 0x908E, "GL_TRANSLATE_X_NV", + }, + { + 0x908F, "GL_TRANSLATE_Y_NV", + }, + { + 0x9090, "GL_TRANSLATE_2D_NV", + }, + { + 0x9091, "GL_TRANSLATE_3D_NV", + }, + { + 0x9092, "GL_AFFINE_2D_NV", + }, + { + 0x9094, "GL_AFFINE_3D_NV", + }, + { + 0x9096, "GL_TRANSPOSE_AFFINE_2D_NV", + }, + { + 0x9098, "GL_TRANSPOSE_AFFINE_3D_NV", + }, + { + 0x909A, "GL_UTF8_NV", + }, + { + 0x909B, "GL_UTF16_NV", + }, + { + 0x909C, "GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV", + }, + { + 0x909D, "GL_PATH_COMMAND_COUNT_NV", + }, + { + 0x909E, "GL_PATH_COORD_COUNT_NV", + }, + { + 0x909F, "GL_PATH_DASH_ARRAY_COUNT_NV", + }, + { + 0x90A0, "GL_PATH_COMPUTED_LENGTH_NV", + }, + { + 0x90A1, "GL_PATH_FILL_BOUNDING_BOX_NV", + }, + { + 0x90A2, "GL_PATH_STROKE_BOUNDING_BOX_NV", + }, + { + 0x90A3, "GL_SQUARE_NV", + }, + { + 0x90A4, "GL_ROUND_NV", + }, + { + 0x90A5, "GL_TRIANGULAR_NV", + }, + { + 0x90A6, "GL_BEVEL_NV", + }, + { + 0x90A7, "GL_MITER_REVERT_NV", + }, + { + 0x90A8, "GL_MITER_TRUNCATE_NV", }, { - 0x9089, "GL_COUNT_DOWN_CHROMIUM", + 0x90A9, "GL_SKIP_MISSING_GLYPH_NV", }, { - 0x908B, "GL_CONVEX_HULL_CHROMIUM", + 0x90AA, "GL_USE_MISSING_GLYPH_NV", }, { - 0x908D, "GL_BOUNDING_BOX_CHROMIUM", + 0x90AB, "GL_PATH_ERROR_POSITION_NV", }, { - 0x908E, "GL_TRANSLATE_X_CHROMIUM", + 0x90AD, "GL_ACCUM_ADJACENT_PAIRS_NV", }, { - 0x908F, "GL_TRANSLATE_Y_CHROMIUM", + 0x90AE, "GL_ADJACENT_PAIRS_NV", }, { - 0x9090, "GL_TRANSLATE_2D_CHROMIUM", + 0x90AF, "GL_FIRST_TO_REST_NV", }, { - 0x9091, "GL_TRANSLATE_3D_CHROMIUM", + 0x90B0, "GL_PATH_GEN_MODE_NV", }, { - 0x9092, "GL_AFFINE_2D_CHROMIUM", + 0x90B1, "GL_PATH_GEN_COEFF_NV", }, { - 0x9094, "GL_AFFINE_3D_CHROMIUM", + 0x90B3, "GL_PATH_GEN_COMPONENTS_NV", }, { - 0x9096, "GL_TRANSPOSE_AFFINE_2D_CHROMIUM", + 0x90B4, "GL_PATH_DASH_OFFSET_RESET_NV", }, { - 0x9098, "GL_TRANSPOSE_AFFINE_3D_CHROMIUM", + 0x90B5, "GL_MOVE_TO_RESETS_NV", }, { - 0x909C, "GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM", + 0x90B6, "GL_MOVE_TO_CONTINUES_NV", }, { - 0x90A4, "GL_ROUND_CHROMIUM", + 0x90B7, "GL_PATH_STENCIL_FUNC_NV", }, { - 0x90A6, "GL_BEVEL_CHROMIUM", + 0x90B8, "GL_PATH_STENCIL_REF_NV", }, { - 0x90A7, "GL_MITER_REVERT_CHROMIUM", + 0x90B9, "GL_PATH_STENCIL_VALUE_MASK_NV", }, { - 0x90B7, "GL_PATH_STENCIL_FUNC_CHROMIUM", + 0x90BD, "GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV", }, { - 0x90B8, "GL_PATH_STENCIL_REF_CHROMIUM", + 0x90BE, "GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV", }, { - 0x90B9, "GL_PATH_STENCIL_VALUE_MASK_CHROMIUM", + 0x90BF, "GL_PATH_COVER_DEPTH_FUNC_NV", }, { - 0x90CB, "GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT", + 0x90CB, "GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES", }, { - 0x90CC, "GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT", + 0x90CC, "GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES", }, { - 0x90CD, "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT", + 0x90CD, "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES", }, { - 0x90D7, "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT", + 0x90D7, "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES", }, { - 0x90D8, "GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT", + 0x90D8, "GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES", }, { - 0x90D9, "GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT", + 0x90D9, "GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES", }, { 0x90F0, "GL_COLOR_ATTACHMENT_EXT", @@ -2845,6 +3343,9 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x90a4, "GL_ROUND_CHROMIUM", }, { + 0x9100, "GL_TEXTURE_2D_MULTISAMPLE", + }, + { 0x9102, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES", }, { @@ -2911,10 +3412,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x9122, "GL_MAX_VERTEX_OUTPUT_COMPONENTS", }, { - 0x9123, "GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT", + 0x9123, "GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES", }, { - 0x9124, "GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT", + 0x9124, "GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES", }, { 0x9125, "GL_MAX_FRAGMENT_INPUT_COMPONENTS", @@ -2944,6 +3445,27 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x9138, "GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG", }, { + 0x9139, "GL_CUBIC_IMG", + }, + { + 0x913A, "GL_CUBIC_MIPMAP_NEAREST_IMG", + }, + { + 0x913B, "GL_CUBIC_MIPMAP_LINEAR_IMG", + }, + { + 0x913C, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG", + }, + { + 0x913D, "GL_NUM_DOWNSAMPLE_SCALES_IMG", + }, + { + 0x913E, "GL_DOWNSAMPLE_SCALES_IMG", + }, + { + 0x913F, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG", + }, + { 0x9143, "GL_MAX_DEBUG_MESSAGE_LENGTH_KHR", }, { @@ -2971,13 +3493,46 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x9154, "GL_VERTEX_ARRAY_OBJECT_EXT", }, { - 0x919D, "GL_TEXTURE_BUFFER_OFFSET_EXT", + 0x9195, "GL_VIRTUAL_PAGE_SIZE_X_EXT", + }, + { + 0x9196, "GL_VIRTUAL_PAGE_SIZE_Y_EXT", + }, + { + 0x9197, "GL_VIRTUAL_PAGE_SIZE_Z_EXT", + }, + { + 0x9198, "GL_MAX_SPARSE_TEXTURE_SIZE_EXT", + }, + { + 0x9199, "GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT", + }, + { + 0x919A, "GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT", + }, + { + 0x919D, "GL_TEXTURE_BUFFER_OFFSET_OES", + }, + { + 0x919E, "GL_TEXTURE_BUFFER_SIZE_OES", }, { - 0x919E, "GL_TEXTURE_BUFFER_SIZE_EXT", + 0x919F, "GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES", }, { - 0x919F, "GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT", + 0x91A6, "GL_TEXTURE_SPARSE_EXT", + }, + { + 0x91A7, "GL_VIRTUAL_PAGE_SIZE_INDEX_EXT", + }, + { + 0x91A8, "GL_NUM_VIRTUAL_PAGE_SIZES_EXT", + }, + { + 0x91A9, "GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT", + }, + { + 0x91AA, "GL_NUM_SPARSE_LEVELS_EXT", }, { 0x9243, "GL_UNPACK_COLORSPACE_CONVERSION_CHROMIUM", @@ -3187,49 +3742,196 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x92B4, "GL_INVERT_OVG_NV", }, { - 0x92BE, "GL_PRIMITIVE_BOUNDING_BOX_EXT", + 0x92BE, "GL_PRIMITIVE_BOUNDING_BOX_OES", }, { - 0x92CD, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT", + 0x92CD, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES", }, { - 0x92CE, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT", + 0x92CE, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES", }, { - 0x92CF, "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT", + 0x92CF, "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES", }, { - 0x92D3, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT", + 0x92D3, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES", }, { - 0x92D4, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT", + 0x92D4, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES", }, { - 0x92D5, "GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT", + 0x92D5, "GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES", + }, + { + 0x92DD, "GL_FRAGMENT_COVERAGE_TO_COLOR_NV", + }, + { + 0x92DE, "GL_FRAGMENT_COVERAGE_COLOR_NV", }, { 0x92E0, "GL_DEBUG_OUTPUT_KHR", }, { - 0x92E7, "GL_IS_PER_PATCH_EXT", + 0x92E7, "GL_IS_PER_PATCH_OES", + }, + { + 0x9307, "GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES", + }, + { + 0x9308, "GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES", }, { - 0x9307, "GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT", + 0x9309, "GL_REFERENCED_BY_GEOMETRY_SHADER_OES", }, { - 0x9308, "GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT", + 0x930F, "GL_LOCATION_INDEX_EXT", }, { - 0x9309, "GL_REFERENCED_BY_GEOMETRY_SHADER_EXT", + 0x9312, "GL_FRAMEBUFFER_DEFAULT_LAYERS_OES", }, { - 0x9312, "GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT", + 0x9317, "GL_MAX_FRAMEBUFFER_LAYERS_OES", }, { - 0x9317, "GL_MAX_FRAMEBUFFER_LAYERS_EXT", + 0x9327, "GL_RASTER_MULTISAMPLE_EXT", }, { - 0x9332, "GL_COVERAGE_MODULATION_CHROMIUM", + 0x9328, "GL_RASTER_SAMPLES_EXT", + }, + { + 0x9329, "GL_MAX_RASTER_SAMPLES_EXT", + }, + { + 0x932A, "GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT", + }, + { + 0x932B, "GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT", + }, + { + 0x932C, "GL_EFFECTIVE_RASTER_SAMPLES_EXT", + }, + { + 0x932D, "GL_DEPTH_SAMPLES_NV", + }, + { + 0x932E, "GL_STENCIL_SAMPLES_NV", + }, + { + 0x932F, "GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV", + }, + { + 0x9330, "GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV", + }, + { + 0x9331, "GL_COVERAGE_MODULATION_TABLE_NV", + }, + { + 0x9332, "GL_COVERAGE_MODULATION_NV", + }, + { + 0x9333, "GL_COVERAGE_MODULATION_TABLE_SIZE_NV", + }, + { + 0x933C, "GL_FILL_RECTANGLE_NV", + }, + { + 0x933D, "GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV", + }, + { + 0x933E, "GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV", + }, + { + 0x933F, "GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV", + }, + { + 0x9340, "GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV", + }, + { + 0x9341, "GL_PROGRAMMABLE_SAMPLE_LOCATION_NV", + }, + { + 0x9342, "GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV", + }, + { + 0x9343, "GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV", + }, + { + 0x9346, "GL_CONSERVATIVE_RASTERIZATION_NV", + }, + { + 0x9347, "GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV", + }, + { + 0x9348, "GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV", + }, + { + 0x9349, "GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV", + }, + { + 0x9350, "GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV", + }, + { + 0x9351, "GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV", + }, + { + 0x9352, "GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV", + }, + { + 0x9353, "GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV", + }, + { + 0x9354, "GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV", + }, + { + 0x9355, "GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV", + }, + { + 0x9356, "GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV", + }, + { + 0x9357, "GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV", + }, + { + 0x9358, "GL_VIEWPORT_SWIZZLE_X_NV", + }, + { + 0x9359, "GL_VIEWPORT_SWIZZLE_Y_NV", + }, + { + 0x935A, "GL_VIEWPORT_SWIZZLE_Z_NV", + }, + { + 0x935B, "GL_VIEWPORT_SWIZZLE_W_NV", + }, + { + 0x9368, "GL_FONT_GLYPHS_AVAILABLE_NV", + }, + { + 0x9369, "GL_FONT_TARGET_UNAVAILABLE_NV", + }, + { + 0x936A, "GL_FONT_UNAVAILABLE_NV", + }, + { + 0x936B, "GL_FONT_UNINTELLIGIBLE_NV", + }, + { + 0x936C, "GL_STANDARD_FONT_FORMAT_NV", + }, + { + 0x936D, "GL_FRAGMENT_INPUT_NV", + }, + { + 0x9371, "GL_MULTISAMPLES_NV", + }, + { + 0x9372, "GL_SUPERSAMPLE_SCALE_X_NV", + }, + { + 0x9373, "GL_SUPERSAMPLE_SCALE_Y_NV", + }, + { + 0x9374, "GL_CONFORMANT_NV", }, { 0x9380, "GL_NUM_SAMPLE_COUNTS", @@ -3448,10 +4150,99 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { 0x9500, "GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL", }, { + 0x954D, "GL_CONSERVATIVE_RASTER_MODE_NV", + }, + { + 0x954E, "GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV", + }, + { + 0x954F, "GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV", + }, + { + 0x9630, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR", + }, + { + 0x9631, "GL_MAX_VIEWS_OVR", + }, + { + 0x9632, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR", + }, + { + 0x9633, "GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR", + }, + { + 0x9650, "GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT", + }, + { + 0x9651, "GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT", + }, + { + 0x9652, + "GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_" + "EXT", + }, + { + 0xC0, "GL_SHARED_EDGE_NV", + }, + { + 0xE8, "GL_ROUNDED_RECT_NV", + }, + { + 0xE9, "GL_RELATIVE_ROUNDED_RECT_NV", + }, + { + 0xEA, "GL_ROUNDED_RECT2_NV", + }, + { + 0xEB, "GL_RELATIVE_ROUNDED_RECT2_NV", + }, + { + 0xEC, "GL_ROUNDED_RECT4_NV", + }, + { + 0xED, "GL_RELATIVE_ROUNDED_RECT4_NV", + }, + { + 0xEE, "GL_ROUNDED_RECT8_NV", + }, + { + 0xEF, "GL_RELATIVE_ROUNDED_RECT8_NV", + }, + { + 0xF0, "GL_RESTART_PATH_NV", + }, + { + 0xF2, "GL_DUP_FIRST_CUBIC_CURVE_TO_NV", + }, + { + 0xF4, "GL_DUP_LAST_CUBIC_CURVE_TO_NV", + }, + { + 0xF6, "GL_RECT_NV", + }, + { + 0xF7, "GL_RELATIVE_RECT_NV", + }, + { + 0xF8, "GL_CIRCULAR_CCW_ARC_TO_NV", + }, + { + 0xFA, "GL_CIRCULAR_CW_ARC_TO_NV", + }, + { + 0xFC, "GL_CIRCULAR_TANGENT_ARC_TO_NV", + }, + { + 0xFE, "GL_ARC_TO_NV", + }, + { + 0xFF, "GL_RELATIVE_ARC_TO_NV", + }, + { 0xFFFFFFFF, "GL_ALL_SHADER_BITS_EXT", }, { - 1, "GL_ES_VERSION_2_0", + 1, "GL_GLES_PROTOTYPES", }, { 16, "GL_MAILBOX_SIZE_CHROMIUM", diff --git a/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.cc b/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.cc index 0159b48fde1..481f0b21c90 100644 --- a/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.cc +++ b/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.cc @@ -50,18 +50,6 @@ gfx::BufferFormat BufferFormatForInternalFormat(unsigned internalformat) { } // namespace -gfx::BufferFormat DefaultBufferFormatForImageFormat(unsigned internalformat) { - switch (internalformat) { - case GL_RGB: - return gfx::BufferFormat::BGRX_8888; - case GL_RGBA: - return gfx::BufferFormat::RGBA_8888; - default: - NOTREACHED(); - return gfx::BufferFormat::RGBA_8888; - } -} - bool IsImageFormatCompatibleWithGpuMemoryBufferFormat( unsigned internalformat, gfx::BufferFormat format) { diff --git a/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.h b/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.h index aa8c567dee0..9f1dfbd42f1 100644 --- a/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.h +++ b/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.h @@ -14,11 +14,6 @@ namespace gpu { struct Capabilities; -// Returns a valid GpuMemoryBuffer format given a valid internalformat as -// defined by CHROMIUM_image. -GPU_EXPORT gfx::BufferFormat DefaultBufferFormatForImageFormat( - unsigned internalformat); - // Returns true if |internalformat| is compatible with |format|. GPU_EXPORT bool IsImageFormatCompatibleWithGpuMemoryBufferFormat( unsigned internalformat, diff --git a/chromium/gpu/command_buffer/common/scheduling_priority.cc b/chromium/gpu/command_buffer/common/scheduling_priority.cc new file mode 100644 index 00000000000..62b6456c921 --- /dev/null +++ b/chromium/gpu/command_buffer/common/scheduling_priority.cc @@ -0,0 +1,28 @@ +// Copyright 2017 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/common/scheduling_priority.h" + +#include "base/logging.h" + +namespace gpu { + +const char* SchedulingPriorityToString(SchedulingPriority priority) { + switch (priority) { + case SchedulingPriority::kHighest: + return "Highest"; + case SchedulingPriority::kHigh: + return "High"; + case SchedulingPriority::kNormal: + return "Normal"; + case SchedulingPriority::kLow: + return "Low"; + case SchedulingPriority::kLowest: + return "Lowest"; + } + NOTREACHED(); + return ""; +} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/common/scheduling_priority.h b/chromium/gpu/command_buffer/common/scheduling_priority.h new file mode 100644 index 00000000000..ca93809f608 --- /dev/null +++ b/chromium/gpu/command_buffer/common/scheduling_priority.h @@ -0,0 +1,32 @@ +// Copyright 2017 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_COMMON_SCHEDULING_PRIORITY_H_ +#define GPU_COMMAND_BUFFER_COMMON_SCHEDULING_PRIORITY_H_ + +#include "gpu/gpu_export.h" + +namespace gpu { + +enum class SchedulingPriority { + // The Highest and High priorities can be used by priveleged clients only. + // This priority should be used for UI contexts. + kHighest, + // This priority is used by the scheduler for prioritizing contexts which have + // outstanding sync token waits. + kHigh, + // The following priorities can be used on unprivileged clients. + // This priority should be used as the default priority for all contexts. + kNormal, + kLow, + // This priority should be used for worker contexts. + kLowest, + kLast = kLowest +}; + +GPU_EXPORT const char* SchedulingPriorityToString(SchedulingPriority priority); + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_COMMON_SCHEDULING_PRIORITY_H_ diff --git a/chromium/gpu/command_buffer/service/BUILD.gn b/chromium/gpu/command_buffer/service/BUILD.gn index bf045d8f437..c87a3f7d859 100644 --- a/chromium/gpu/command_buffer/service/BUILD.gn +++ b/chromium/gpu/command_buffer/service/BUILD.gn @@ -28,16 +28,14 @@ target(link_target_type, "service_sources") { visibility = [ "//gpu/*" ] sources = [ + "async_api_interface.h", "buffer_manager.cc", "buffer_manager.h", "client_service_map.h", - "cmd_buffer_engine.h", - "cmd_parser.cc", - "cmd_parser.h", + "command_buffer_direct.cc", + "command_buffer_direct.h", "command_buffer_service.cc", "command_buffer_service.h", - "command_executor.cc", - "command_executor.h", "common_decoder.cc", "common_decoder.h", "context_group.cc", @@ -122,7 +120,11 @@ target(link_target_type, "service_sources") { "renderbuffer_manager.h", "sampler_manager.cc", "sampler_manager.h", + "scheduler.cc", + "scheduler.h", "sequence_id.h", + "service_discardable_manager.cc", + "service_discardable_manager.h", "service_utils.cc", "service_utils.h", "shader_manager.cc", diff --git a/chromium/gpu/command_buffer/service/async_api_interface.h b/chromium/gpu/command_buffer/service/async_api_interface.h new file mode 100644 index 00000000000..2b46ff1affb --- /dev/null +++ b/chromium/gpu/command_buffer/service/async_api_interface.h @@ -0,0 +1,45 @@ +// Copyright 2017 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. + +// This file contains the command parser class. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_ASYNC_API_INTERFACE_H_ +#define GPU_COMMAND_BUFFER_SERVICE_ASYNC_API_INTERFACE_H_ + +#include <stddef.h> +#include <stdint.h> + +#include "base/strings/string_piece.h" +#include "gpu/command_buffer/common/constants.h" +#include "gpu/gpu_export.h" + +namespace gpu { + +// This class defines the interface for an asynchronous API handler, that +// is responsible for de-multiplexing commands and their arguments. +class GPU_EXPORT AsyncAPIInterface { + public: + AsyncAPIInterface() {} + virtual ~AsyncAPIInterface() {} + + virtual void BeginDecoding() = 0; + virtual void EndDecoding() = 0; + + // Executes multiple commands. + // Parameters: + // num_commands: maximum number of commands to execute from buffer. + // buffer: pointer to first command entry to process. + // num_entries: number of sequential command buffer entries in buffer. + // entries_processed: if not 0, is set to the number of entries processed. + virtual error::Error DoCommands(unsigned int num_commands, + const volatile void* buffer, + int num_entries, + int* entries_processed) = 0; + + virtual base::StringPiece GetLogPrefix() = 0; +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_ASYNC_API_INTERFACE_H_ diff --git a/chromium/gpu/command_buffer/service/cmd_buffer_engine.h b/chromium/gpu/command_buffer/service/cmd_buffer_engine.h deleted file mode 100644 index eaf8309d636..00000000000 --- a/chromium/gpu/command_buffer/service/cmd_buffer_engine.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2011 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. - -// This file defines the CommandBufferEngine class, providing the main loop for -// the service, exposing the RPC API, managing the command parser. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CMD_BUFFER_ENGINE_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CMD_BUFFER_ENGINE_H_ - -#include <stdint.h> - -#include "base/macros.h" -#include "gpu/command_buffer/common/buffer.h" - -namespace gpu { - -class CommandBufferEngine { - public: - CommandBufferEngine() { - } - - virtual ~CommandBufferEngine() { - } - - // Gets the base address and size of a registered shared memory buffer. - // Parameters: - // shm_id: the identifier for the shared memory buffer. - virtual scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32_t shm_id) = 0; - - // Sets the token value. - virtual void set_token(int32_t token) = 0; - - // Sets the shared memory buffer used for commands. - virtual bool SetGetBuffer(int32_t transfer_buffer_id) = 0; - - // Sets the "get" pointer. Return false if offset is out of range. - virtual bool SetGetOffset(int32_t offset) = 0; - - // Gets the "get" pointer. - virtual int32_t GetGetOffset() = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(CommandBufferEngine); -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_SERVICE_CMD_BUFFER_ENGINE_H_ diff --git a/chromium/gpu/command_buffer/service/cmd_parser.cc b/chromium/gpu/command_buffer/service/cmd_parser.cc deleted file mode 100644 index 2178cd5ba8b..00000000000 --- a/chromium/gpu/command_buffer/service/cmd_parser.cc +++ /dev/null @@ -1,118 +0,0 @@ -// 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. - -// This file contains the implementation of the command parser. - -#include "gpu/command_buffer/service/cmd_parser.h" - -#include <stddef.h> - -#include "base/logging.h" -#include "base/trace_event/trace_event.h" - -namespace gpu { - -CommandParser::CommandParser(AsyncAPIInterface* handler) - : get_(0), - put_(0), - buffer_(NULL), - entry_count_(0), - handler_(handler) { -} - -void CommandParser::SetBuffer( - void* shm_address, - size_t shm_size, - ptrdiff_t offset, - size_t size) { - // check proper alignments. - DCHECK_EQ(0, (reinterpret_cast<intptr_t>(shm_address)) % 4); - DCHECK_EQ(0, offset % 4); - DCHECK_EQ(0u, size % 4); - // check that the command buffer fits into the memory buffer. - DCHECK_GE(shm_size, offset + size); - get_ = 0; - put_ = 0; - char* buffer_begin = static_cast<char*>(shm_address) + offset; - buffer_ = reinterpret_cast<CommandBufferEntry*>(buffer_begin); - entry_count_ = size / 4; -} - -// Process one command, reading the header from the command buffer, and -// forwarding the command index and the arguments to the handler. -// Note that: -// - validation needs to happen on a copy of the data (to avoid race -// conditions). This function only validates the header, leaving the arguments -// validation to the handler, so it can pass a reference to them. -// - get_ is modified *after* the command has been executed. -error::Error CommandParser::ProcessCommands(int num_commands) { - int num_entries = put_ < get_ ? entry_count_ - get_ : put_ - get_; - int entries_processed = 0; - - error::Error result = handler_->DoCommands( - num_commands, buffer_ + get_, num_entries, &entries_processed); - - get_ += entries_processed; - if (get_ == entry_count_) - get_ = 0; - - return result; -} - -// Processes all the commands, while the buffer is not empty. Stop if an error -// is encountered. -error::Error CommandParser::ProcessAllCommands() { - while (!IsEmpty()) { - error::Error error = ProcessCommands(kParseCommandsSlice); - if (error) - return error; - } - return error::kNoError; -} - -// Decode multiple commands, and call the corresponding GL functions. -// NOTE: buffer is a pointer to the command buffer. As such, it could be -// changed by a (malicious) client at any time, so if validation has to happen, -// it should operate on a copy of them. -error::Error AsyncAPIInterface::DoCommands(unsigned int num_commands, - const volatile void* buffer, - int num_entries, - int* entries_processed) { - int commands_to_process = num_commands; - error::Error result = error::kNoError; - const volatile CommandBufferEntry* cmd_data = - static_cast<const volatile CommandBufferEntry*>(buffer); - int process_pos = 0; - - while (process_pos < num_entries && result == error::kNoError && - commands_to_process--) { - CommandHeader header = CommandHeader::FromVolatile(cmd_data->value_header); - if (header.size == 0) { - DVLOG(1) << "Error: zero sized command in command buffer"; - return error::kInvalidSize; - } - - if (static_cast<int>(header.size) + process_pos > num_entries) { - DVLOG(1) << "Error: get offset out of bounds"; - return error::kOutOfBounds; - } - - const unsigned int command = header.command; - const unsigned int arg_count = header.size - 1; - - result = DoCommand(command, arg_count, cmd_data); - - if (result != error::kDeferCommandUntilLater) { - process_pos += header.size; - cmd_data += header.size; - } - } - - if (entries_processed) - *entries_processed = process_pos; - - return result; -} - -} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/cmd_parser.h b/chromium/gpu/command_buffer/service/cmd_parser.h deleted file mode 100644 index 96514399538..00000000000 --- a/chromium/gpu/command_buffer/service/cmd_parser.h +++ /dev/null @@ -1,112 +0,0 @@ -// 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. - -// This file contains the command parser class. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CMD_PARSER_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CMD_PARSER_H_ - -#include <stddef.h> -#include <stdint.h> - -#include "gpu/command_buffer/common/cmd_buffer_common.h" -#include "gpu/command_buffer/common/constants.h" -#include "gpu/gpu_export.h" - -namespace gpu { - -class AsyncAPIInterface; - -// Command parser class. This class parses commands from a shared memory -// buffer, to implement some asynchronous RPC mechanism. -class GPU_EXPORT CommandParser { - public: - static const int kParseCommandsSlice = 20; - - explicit CommandParser(AsyncAPIInterface* handler); - - // Sets the buffer to read commands from. - void SetBuffer( - void* shm_address, - size_t shm_size, - ptrdiff_t offset, - size_t size); - - // Gets the "get" pointer. The get pointer is an index into the command - // buffer considered as an array of CommandBufferEntry. - CommandBufferOffset get() const { return get_; } - - // Sets the "get" pointer. The get pointer is an index into the command buffer - // considered as an array of CommandBufferEntry. - bool set_get(CommandBufferOffset get) { - if (get >= 0 && get < entry_count_) { - get_ = get; - return true; - } - return false; - } - - // Sets the "put" pointer. The put pointer is an index into the command - // buffer considered as an array of CommandBufferEntry. - void set_put(CommandBufferOffset put) { put_ = put; } - - // Gets the "put" pointer. The put pointer is an index into the command - // buffer considered as an array of CommandBufferEntry. - CommandBufferOffset put() const { return put_; } - - // Checks whether there are commands to process. - bool IsEmpty() const { return put_ == get_; } - - // Processes one command, updating the get pointer. This will return an error - // if there are no commands in the buffer. - error::Error ProcessCommands(int num_commands); - - // Processes all commands until get == put. - error::Error ProcessAllCommands(); - - private: - CommandBufferOffset get_; - CommandBufferOffset put_; - volatile CommandBufferEntry* buffer_; - int32_t entry_count_; - AsyncAPIInterface* handler_; -}; - -// This class defines the interface for an asynchronous API handler, that -// is responsible for de-multiplexing commands and their arguments. -class GPU_EXPORT AsyncAPIInterface { - public: - AsyncAPIInterface() {} - virtual ~AsyncAPIInterface() {} - - // Executes a single command. - // Parameters: - // command: the command index. - // arg_count: the number of CommandBufferEntry arguments. - // cmd_data: the command data. - // Returns: - // error::kNoError if no error was found, one of - // error::Error otherwise. - virtual error::Error DoCommand(unsigned int command, - unsigned int arg_count, - const volatile void* cmd_data) = 0; - - // Executes multiple commands. - // Parameters: - // num_commands: maximum number of commands to execute from buffer. - // buffer: pointer to first command entry to process. - // num_entries: number of sequential command buffer entries in buffer. - // entries_processed: if not 0, is set to the number of entries processed. - virtual error::Error DoCommands(unsigned int num_commands, - const volatile void* buffer, - int num_entries, - int* entries_processed); - - // Returns a name for a command. Useful for logging / debuging. - virtual const char* GetCommandName(unsigned int command_id) const = 0; -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_SERVICE_CMD_PARSER_H_ diff --git a/chromium/gpu/command_buffer/service/cmd_parser_test.cc b/chromium/gpu/command_buffer/service/cmd_parser_test.cc deleted file mode 100644 index b1ed3a27eb2..00000000000 --- a/chromium/gpu/command_buffer/service/cmd_parser_test.cc +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright (c) 2011 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 command parser. - -#include <stddef.h> - -#include <memory> - -#include "base/logging.h" -#include "gpu/command_buffer/service/cmd_parser.h" -#include "gpu/command_buffer/service/mocks.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace gpu { - -using testing::_; -using testing::Invoke; -using testing::Mock; -using testing::Return; -using testing::Sequence; -using testing::SetArgPointee; -using testing::Truly; - -// Test fixture for CommandParser test - Creates a mock AsyncAPIInterface, and -// a fixed size memory buffer. Also provides a simple API to create a -// CommandParser. -class CommandParserTest : public testing::Test { - protected: - virtual void SetUp() { - api_mock_.reset(new AsyncAPIMock(false)); - buffer_entry_count_ = 20; - buffer_.reset(new CommandBufferEntry[buffer_entry_count_]); - } - virtual void TearDown() {} - - void AddDoCommandsExpect(error::Error _return, - unsigned int num_commands, - int num_entries, - int num_processed) { - EXPECT_CALL(*api_mock_, DoCommands(num_commands, _, num_entries, _)) - .InSequence(sequence_) - .WillOnce(DoAll(SetArgPointee<3>(num_processed), Return(_return))); - } - - // Creates a parser, with a buffer of the specified size (in entries). - CommandParser *MakeParser(unsigned int entry_count) { - size_t shm_size = buffer_entry_count_ * - sizeof(CommandBufferEntry); // NOLINT - size_t command_buffer_size = entry_count * - sizeof(CommandBufferEntry); // NOLINT - DCHECK_LE(command_buffer_size, shm_size); - CommandParser* parser = new CommandParser(api_mock()); - - parser->SetBuffer(buffer(), shm_size, 0, command_buffer_size); - return parser; - } - - unsigned int buffer_entry_count() { return 20; } - AsyncAPIMock *api_mock() { return api_mock_.get(); } - CommandBufferEntry *buffer() { return buffer_.get(); } - private: - unsigned int buffer_entry_count_; - std::unique_ptr<AsyncAPIMock> api_mock_; - std::unique_ptr<CommandBufferEntry[]> buffer_; - Sequence sequence_; -}; - -// Tests initialization conditions. -TEST_F(CommandParserTest, TestInit) { - std::unique_ptr<CommandParser> parser(MakeParser(10)); - EXPECT_EQ(0, parser->get()); - EXPECT_EQ(0, parser->put()); - EXPECT_TRUE(parser->IsEmpty()); -} - -// Tests simple commands. -TEST_F(CommandParserTest, TestSimple) { - std::unique_ptr<CommandParser> parser(MakeParser(10)); - CommandBufferOffset put = parser->put(); - CommandHeader header; - - // add a single command, no args - header.size = 1; - header.command = 123; - buffer()[put++].value_header = header; - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - AddDoCommandsExpect(error::kNoError, 1, 1, 1); - EXPECT_EQ(error::kNoError, parser->ProcessCommands(1)); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); - - // add a single command, 2 args - header.size = 3; - header.command = 456; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 2134; - buffer()[put++].value_float = 1.f; - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - AddDoCommandsExpect(error::kNoError, 1, 3, 3); - EXPECT_EQ(error::kNoError, parser->ProcessCommands(1)); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); -} - -// Tests having multiple commands in the buffer. -TEST_F(CommandParserTest, TestMultipleCommands) { - std::unique_ptr<CommandParser> parser(MakeParser(10)); - CommandBufferOffset put = parser->put(); - CommandHeader header; - - // add 2 commands, test with single ProcessCommands() - header.size = 2; - header.command = 789; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 5151; - - CommandBufferOffset put_cmd2 = put; - header.size = 2; - header.command = 876; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 3434; - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - // Process up to 1 command. 4 entries remaining. - AddDoCommandsExpect(error::kNoError, 1, 4, 2); - EXPECT_EQ(error::kNoError, parser->ProcessCommands(1)); - EXPECT_EQ(put_cmd2, parser->get()); - - // Process up to 1 command. 2 entries remaining. - AddDoCommandsExpect(error::kNoError, 1, 2, 2); - EXPECT_EQ(error::kNoError, parser->ProcessCommands(1)); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); - - // add 2 commands again, test with ProcessAllCommands() - header.size = 2; - header.command = 123; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 5656; - - header.size = 2; - header.command = 321; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 7878; - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - // 4 entries remaining. - AddDoCommandsExpect( - error::kNoError, CommandParser::kParseCommandsSlice, 4, 4); - EXPECT_EQ(error::kNoError, parser->ProcessAllCommands()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); -} - -// Tests that the parser will wrap correctly at the end of the buffer. -TEST_F(CommandParserTest, TestWrap) { - std::unique_ptr<CommandParser> parser(MakeParser(5)); - CommandBufferOffset put = parser->put(); - CommandHeader header; - - // add 3 commands with no args (1 word each) - for (unsigned int i = 0; i < 3; ++i) { - header.size = 1; - header.command = i; - buffer()[put++].value_header = header; - } - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - // Process up to 10 commands. 3 entries remaining to put. - AddDoCommandsExpect(error::kNoError, 10, 3, 3); - EXPECT_EQ(error::kNoError, parser->ProcessCommands(10)); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); - - // add 1 command with 1 arg (2 words). That should put us at the end of the - // buffer. - header.size = 2; - header.command = 3; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 5; - - DCHECK_EQ(5, put); - put = 0; - - // add 1 command with 1 arg (2 words). - header.size = 2; - header.command = 4; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 6; - - // 2 entries remaining to end of buffer. - AddDoCommandsExpect( - error::kNoError, CommandParser::kParseCommandsSlice, 2, 2); - // 2 entries remaining to put. - AddDoCommandsExpect( - error::kNoError, CommandParser::kParseCommandsSlice, 2, 2); - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - EXPECT_EQ(error::kNoError, parser->ProcessAllCommands()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); -} - -// Tests error conditions. -TEST_F(CommandParserTest, TestError) { - const unsigned int kNumEntries = 5; - std::unique_ptr<CommandParser> parser(MakeParser(kNumEntries)); - CommandBufferOffset put = parser->put(); - CommandHeader header; - - EXPECT_FALSE(parser->set_get(-1)); - EXPECT_FALSE(parser->set_get(kNumEntries)); - - // Generate a command with size 0. - header.size = 0; - header.command = 3; - buffer()[put++].value_header = header; - - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - AddDoCommandsExpect( - error::kInvalidSize, CommandParser::kParseCommandsSlice, 1, 0); - EXPECT_EQ(error::kInvalidSize, - parser->ProcessAllCommands()); - // check that no DoCommand call was made. - Mock::VerifyAndClearExpectations(api_mock()); - - parser.reset(MakeParser(5)); - put = parser->put(); - - // Generate a command with size 6, extends beyond the end of the buffer. - header.size = 6; - header.command = 3; - buffer()[put++].value_header = header; - - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - AddDoCommandsExpect( - error::kOutOfBounds, CommandParser::kParseCommandsSlice, 1, 0); - EXPECT_EQ(error::kOutOfBounds, - parser->ProcessAllCommands()); - // check that no DoCommand call was made. - Mock::VerifyAndClearExpectations(api_mock()); - - parser.reset(MakeParser(5)); - put = parser->put(); - - // Generates 2 commands. - header.size = 1; - header.command = 3; - buffer()[put++].value_header = header; - CommandBufferOffset put_post_fail = put; - header.size = 1; - header.command = 4; - buffer()[put++].value_header = header; - - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - // have the first command fail to parse. - AddDoCommandsExpect( - error::kUnknownCommand, CommandParser::kParseCommandsSlice, 2, 1); - EXPECT_EQ(error::kUnknownCommand, - parser->ProcessAllCommands()); - // check that only one command was executed, and that get reflects that - // correctly. - EXPECT_EQ(put_post_fail, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); - // make the second one succeed, and check that the parser recovered fine. - AddDoCommandsExpect( - error::kNoError, CommandParser::kParseCommandsSlice, 1, 1); - EXPECT_EQ(error::kNoError, parser->ProcessAllCommands()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); -} - -TEST_F(CommandParserTest, SetBuffer) { - std::unique_ptr<CommandParser> parser(MakeParser(3)); - CommandBufferOffset put = parser->put(); - CommandHeader header; - - // add a single command, no args - header.size = 2; - header.command = 123; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 456; - parser->set_put(put); - - AddDoCommandsExpect( - error::kNoError, CommandParser::kParseCommandsSlice, 2, 2); - EXPECT_EQ(error::kNoError, parser->ProcessAllCommands()); - // We should have advanced 2 entries - EXPECT_EQ(2, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); - - std::unique_ptr<CommandBufferEntry[]> buffer2(new CommandBufferEntry[2]); - parser->SetBuffer( - buffer2.get(), sizeof(CommandBufferEntry) * 2, 0, - sizeof(CommandBufferEntry) * 2); - // The put and get should have reset to 0. - EXPECT_EQ(0, parser->get()); - EXPECT_EQ(0, parser->put()); -} - -} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/command_buffer_direct.cc b/chromium/gpu/command_buffer/service/command_buffer_direct.cc new file mode 100644 index 00000000000..2f1643dd5f6 --- /dev/null +++ b/chromium/gpu/command_buffer/service/command_buffer_direct.cc @@ -0,0 +1,183 @@ +// Copyright 2017 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/command_buffer_direct.h" + +#include "base/bind.h" +#include "gpu/command_buffer/service/sync_point_manager.h" +#include "gpu/command_buffer/service/transfer_buffer_manager.h" + +namespace gpu { + +namespace { + +uint64_t g_next_command_buffer_id = 1; +bool AlwaysTrue() { + return true; +} + +} // anonymous namespace + +CommandBufferDirect::CommandBufferDirect( + TransferBufferManager* transfer_buffer_manager, + AsyncAPIInterface* handler) + : CommandBufferDirect(transfer_buffer_manager, + handler, + base::Bind(&AlwaysTrue), + nullptr) {} + +CommandBufferDirect::CommandBufferDirect( + TransferBufferManager* transfer_buffer_manager, + AsyncAPIInterface* handler, + const MakeCurrentCallback& callback, + SyncPointManager* sync_point_manager) + : service_(transfer_buffer_manager, handler), + make_current_callback_(callback), + sync_point_manager_(sync_point_manager), + command_buffer_id_( + CommandBufferId::FromUnsafeValue(g_next_command_buffer_id++)) { + if (sync_point_manager_) { + sync_point_order_data_ = sync_point_manager_->CreateSyncPointOrderData(); + sync_point_client_state_ = sync_point_manager_->CreateSyncPointClientState( + GetNamespaceID(), GetCommandBufferID(), + sync_point_order_data_->sequence_id()); + } else { + sync_point_order_data_ = nullptr; + sync_point_client_state_ = nullptr; + } +} + +CommandBufferDirect::~CommandBufferDirect() { + sync_point_manager_ = nullptr; + if (sync_point_order_data_) { + sync_point_order_data_->Destroy(); + sync_point_order_data_ = nullptr; + } + if (sync_point_client_state_) { + sync_point_client_state_->Destroy(); + sync_point_client_state_ = nullptr; + } +} + +CommandBuffer::State CommandBufferDirect::GetLastState() { + service_.UpdateState(); + return service_.GetState(); +} + +CommandBuffer::State CommandBufferDirect::WaitForTokenInRange(int32_t start, + int32_t end) { + State state = GetLastState(); + DCHECK(state.error != error::kNoError || InRange(start, end, state.token)); + return state; +} + +CommandBuffer::State CommandBufferDirect::WaitForGetOffsetInRange( + uint32_t set_get_buffer_count, + int32_t start, + int32_t end) { + State state = GetLastState(); + DCHECK(state.error != error::kNoError || + (InRange(start, end, state.get_offset) && + (set_get_buffer_count == state.set_get_buffer_count))); + return state; +} + +void CommandBufferDirect::Flush(int32_t put_offset) { + if (!make_current_callback_.Run()) { + service_.SetParseError(error::kLostContext); + return; + } + uint32_t order_num = 0; + if (sync_point_manager_) { + // If sync point manager is supported, assign order numbers to commands. + if (paused_order_num_) { + // Was previous paused, continue to process the order number. + order_num = paused_order_num_; + paused_order_num_ = 0; + } else { + order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber(); + } + sync_point_order_data_->BeginProcessingOrderNumber(order_num); + } + + if (pause_commands_) { + // Do not process commands, simply store the current order number. + paused_order_num_ = order_num; + + sync_point_order_data_->PauseProcessingOrderNumber(order_num); + return; + } + + service_.Flush(put_offset); + if (sync_point_manager_) { + // Finish processing order number here. + sync_point_order_data_->FinishProcessingOrderNumber(order_num); + } +} + +void CommandBufferDirect::OrderingBarrier(int32_t put_offset) { + Flush(put_offset); +} + +void CommandBufferDirect::SetGetBuffer(int32_t transfer_buffer_id) { + service_.SetGetBuffer(transfer_buffer_id); +} + +scoped_refptr<Buffer> CommandBufferDirect::CreateTransferBuffer(size_t size, + int32_t* id) { + return service_.CreateTransferBuffer(size, id); +} + +void CommandBufferDirect::DestroyTransferBuffer(int32_t id) { + service_.DestroyTransferBuffer(id); +} + +gpu::CommandBufferNamespace CommandBufferDirect::GetNamespaceID() const { + return gpu::CommandBufferNamespace::IN_PROCESS; +} + +CommandBufferId CommandBufferDirect::GetCommandBufferID() const { + return command_buffer_id_; +} + +void CommandBufferDirect::SetCommandsPaused(bool paused) { + pause_commands_ = paused; +} + +void CommandBufferDirect::OnFenceSyncRelease(uint64_t release) { + DCHECK(sync_point_client_state_); + service_.SetReleaseCount(release); + sync_point_client_state_->ReleaseFenceSync(release); +} + +bool CommandBufferDirect::OnWaitSyncToken(const SyncToken& sync_token) { + DCHECK(sync_point_manager_); + if (sync_point_manager_->IsSyncTokenReleased(sync_token)) + return false; + service_.SetScheduled(false); + return true; +} + +void CommandBufferDirect::SignalSyncToken(const gpu::SyncToken& sync_token, + const base::Closure& callback) { + if (sync_point_manager_) { + DCHECK(!paused_order_num_); + uint32_t order_num = + sync_point_order_data_->GenerateUnprocessedOrderNumber(); + sync_point_order_data_->BeginProcessingOrderNumber(order_num); + if (!sync_point_client_state_->Wait(sync_token, callback)) + callback.Run(); + sync_point_order_data_->FinishProcessingOrderNumber(order_num); + } else { + callback.Run(); + } +} + +scoped_refptr<Buffer> CommandBufferDirect::CreateTransferBufferWithId( + size_t size, + int32_t id) { + return service_.CreateTransferBufferWithId(size, id); +} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/command_buffer_direct.h b/chromium/gpu/command_buffer/service/command_buffer_direct.h new file mode 100644 index 00000000000..4bcbe4ee40a --- /dev/null +++ b/chromium/gpu/command_buffer/service/command_buffer_direct.h @@ -0,0 +1,75 @@ +// Copyright 2017 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_SERVICE_COMMAND_BUFFER_DIRECT_H_ +#define GPU_COMMAND_BUFFER_SERVICE_COMMAND_BUFFER_DIRECT_H_ + +#include "base/callback.h" +#include "gpu/command_buffer/common/command_buffer_id.h" +#include "gpu/command_buffer/common/constants.h" +#include "gpu/command_buffer/service/command_buffer_service.h" +#include "gpu/gpu_export.h" + +namespace gpu { + +class AsyncAPIInterface; +class TransferBufferManager; +class SyncPointClientState; +class SyncPointManager; +class SyncPointOrderData; +struct SyncToken; + +class GPU_EXPORT CommandBufferDirect : public CommandBuffer { + public: + using MakeCurrentCallback = base::Callback<bool()>; + + CommandBufferDirect(TransferBufferManager* transfer_buffer_manager, + AsyncAPIInterface* handler, + const MakeCurrentCallback& callback, + SyncPointManager* sync_point_manager); + CommandBufferDirect(TransferBufferManager* transfer_buffer_manager, + AsyncAPIInterface* handler); + + ~CommandBufferDirect() override; + + CommandBufferServiceBase* service() { return &service_; } + + // CommandBuffer implementation: + CommandBuffer::State GetLastState() override; + void Flush(int32_t put_offset) override; + void OrderingBarrier(int32_t put_offset) override; + CommandBuffer::State WaitForTokenInRange(int32_t start, int32_t end) override; + CommandBuffer::State WaitForGetOffsetInRange(uint32_t set_get_buffer_count, + int32_t start, + int32_t end) override; + void SetGetBuffer(int32_t transfer_buffer_id) override; + scoped_refptr<Buffer> CreateTransferBuffer(size_t size, int32_t* id) override; + void DestroyTransferBuffer(int32_t id) override; + + CommandBufferNamespace GetNamespaceID() const; + CommandBufferId GetCommandBufferID() const; + + void SetCommandsPaused(bool paused); + void OnFenceSyncRelease(uint64_t release); + bool OnWaitSyncToken(const SyncToken& sync_token); + void SignalSyncToken(const gpu::SyncToken& sync_token, + const base::Closure& callback); + + scoped_refptr<Buffer> CreateTransferBufferWithId(size_t size, int32_t id); + + private: + CommandBufferService service_; + MakeCurrentCallback make_current_callback_; + SyncPointManager* sync_point_manager_; + + scoped_refptr<SyncPointOrderData> sync_point_order_data_; + scoped_refptr<SyncPointClientState> sync_point_client_state_; + bool pause_commands_ = false; + uint32_t paused_order_num_ = 0; + const CommandBufferId command_buffer_id_; +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_COMMAND_BUFFER_DIRECT_H diff --git a/chromium/gpu/command_buffer/service/command_buffer_service.cc b/chromium/gpu/command_buffer/service/command_buffer_service.cc index 3e6a92c320b..bee52abb567 100644 --- a/chromium/gpu/command_buffer/service/command_buffer_service.cc +++ b/chromium/gpu/command_buffer/service/command_buffer_service.cc @@ -40,82 +40,84 @@ class MemoryBufferBacking : public BufferBacking { } // anonymous namespace CommandBufferService::CommandBufferService( - TransferBufferManagerInterface* transfer_buffer_manager) - : ring_buffer_id_(-1), - shared_state_(nullptr), - num_entries_(0), - get_offset_(0), - put_offset_(0), - transfer_buffer_manager_(transfer_buffer_manager), - token_(0), - release_count_(0), - generation_(0), - error_(error::kNoError), - context_lost_reason_(error::kUnknown) {} + TransferBufferManager* transfer_buffer_manager, + AsyncAPIInterface* handler) + : transfer_buffer_manager_(transfer_buffer_manager), handler_(handler) { + state_.token = 0; +} CommandBufferService::~CommandBufferService() {} -CommandBufferService::State CommandBufferService::GetLastState() { - State state; - state.get_offset = get_offset_; - state.token = token_; - state.release_count = release_count_; - state.error = error_; - state.context_lost_reason = context_lost_reason_; - state.generation = ++generation_; - - return state; -} - void CommandBufferService::UpdateState() { - if (shared_state_) { - CommandBufferService::State state = GetLastState(); - shared_state_->Write(state); - } -} - -CommandBuffer::State CommandBufferService::WaitForTokenInRange(int32_t start, - int32_t end) { - DCHECK(error_ != error::kNoError || InRange(start, end, token_)); - return GetLastState(); -} - -CommandBuffer::State CommandBufferService::WaitForGetOffsetInRange( - int32_t start, - int32_t end) { - DCHECK(error_ != error::kNoError || InRange(start, end, get_offset_)); - return GetLastState(); + ++state_.generation; + if (shared_state_) + shared_state_->Write(state_); } void CommandBufferService::Flush(int32_t put_offset) { if (put_offset < 0 || put_offset >= num_entries_) { - error_ = gpu::error::kOutOfBounds; + SetParseError(gpu::error::kOutOfBounds); return; } + TRACE_EVENT1("gpu", "CommandBufferService:PutChanged", "handler", + handler_->GetLogPrefix().as_string()); + put_offset_ = put_offset; - if (!put_offset_change_callback_.is_null()) - put_offset_change_callback_.Run(); -} + DCHECK(buffer_); + + if (state_.error != error::kNoError) + return; + + DCHECK(scheduled()); + + error::Error error = error::kNoError; + handler_->BeginDecoding(); + while (put_offset_ != state_.get_offset) { + if (PauseExecution()) + break; + + error = ProcessCommands(kParseCommandsSlice); + + if (error::IsError(error)) { + SetParseError(error); + break; + } + + if (!command_processed_callback_.is_null()) + command_processed_callback_.Run(); + + if (!scheduled()) + break; + } -void CommandBufferService::OrderingBarrier(int32_t put_offset) { - Flush(put_offset); + handler_->EndDecoding(); } void CommandBufferService::SetGetBuffer(int32_t transfer_buffer_id) { - DCHECK_EQ(-1, ring_buffer_id_); - DCHECK_EQ(put_offset_, get_offset_); // Only if it's empty. + DCHECK_EQ(put_offset_, state_.get_offset); // Only if it's empty. + put_offset_ = 0; + state_.get_offset = 0; + ++state_.set_get_buffer_count; + // If the buffer is invalid we handle it gracefully. // This means ring_buffer_ can be NULL. ring_buffer_ = GetTransferBuffer(transfer_buffer_id); ring_buffer_id_ = transfer_buffer_id; - int32_t size = ring_buffer_.get() ? ring_buffer_->size() : 0; - num_entries_ = size / sizeof(CommandBufferEntry); - put_offset_ = 0; - SetGetOffset(0); - if (!get_buffer_change_callback_.is_null()) { - get_buffer_change_callback_.Run(ring_buffer_id_); + if (ring_buffer_) { + int32_t size = ring_buffer_->size(); + volatile void* memory = ring_buffer_->memory(); + // check proper alignments. + DCHECK_EQ( + 0u, (reinterpret_cast<intptr_t>(memory)) % alignof(CommandBufferEntry)); + DCHECK_EQ(0u, size % sizeof(CommandBufferEntry)); + + num_entries_ = size / sizeof(CommandBufferEntry); + buffer_ = reinterpret_cast<volatile CommandBufferEntry*>(memory); + } else { + num_entries_ = 0; + buffer_ = nullptr; } UpdateState(); @@ -132,14 +134,13 @@ void CommandBufferService::SetSharedStateBuffer( UpdateState(); } -void CommandBufferService::SetGetOffset(int32_t get_offset) { - DCHECK(get_offset >= 0 && get_offset < num_entries_); - get_offset_ = get_offset; +CommandBuffer::State CommandBufferService::GetState() { + return state_; } void CommandBufferService::SetReleaseCount(uint64_t release_count) { - DCHECK(release_count >= release_count_); - release_count_ = release_count; + DCHECK(release_count >= state_.release_count); + state_.release_count = release_count; UpdateState(); } @@ -157,9 +158,10 @@ void CommandBufferService::DestroyTransferBuffer(int32_t id) { transfer_buffer_manager_->DestroyTransferBuffer(id); if (id == ring_buffer_id_) { ring_buffer_id_ = -1; - ring_buffer_ = NULL; + ring_buffer_ = nullptr; + buffer_ = nullptr; num_entries_ = 0; - get_offset_ = 0; + state_.get_offset = 0; put_offset_ = 0; } } @@ -180,22 +182,21 @@ scoped_refptr<Buffer> CommandBufferService::CreateTransferBufferWithId( int32_t id) { if (!RegisterTransferBuffer(id, base::MakeUnique<MemoryBufferBacking>(size))) { - if (error_ == error::kNoError) - error_ = gpu::error::kOutOfBounds; - return NULL; + SetParseError(gpu::error::kOutOfBounds); + return nullptr; } return GetTransferBuffer(id); } void CommandBufferService::SetToken(int32_t token) { - token_ = token; + state_.token = token; UpdateState(); } void CommandBufferService::SetParseError(error::Error error) { - if (error_ == error::kNoError) { - error_ = error; + if (state_.error == error::kNoError) { + state_.error = error; if (!parse_error_callback_.is_null()) parse_error_callback_.Run(); } @@ -203,21 +204,17 @@ void CommandBufferService::SetParseError(error::Error error) { void CommandBufferService::SetContextLostReason( error::ContextLostReason reason) { - context_lost_reason_ = reason; + state_.context_lost_reason = reason; } -int32_t CommandBufferService::GetPutOffset() { - return put_offset_; +void CommandBufferService::SetPauseExecutionCallback( + const PauseExecutionCallback& callback) { + pause_execution_callback_ = callback; } -void CommandBufferService::SetPutOffsetChangeCallback( +void CommandBufferService::SetCommandProcessedCallback( const base::Closure& callback) { - put_offset_change_callback_ = callback; -} - -void CommandBufferService::SetGetBufferChangeCallback( - const GetBufferChangedCallback& callback) { - get_buffer_change_callback_ = callback; + command_processed_callback_ = callback; } void CommandBufferService::SetParseErrorCallback( @@ -225,4 +222,39 @@ void CommandBufferService::SetParseErrorCallback( parse_error_callback_ = callback; } +void CommandBufferService::SetScheduled(bool scheduled) { + TRACE_EVENT2("gpu", "CommandBufferService:SetScheduled", "this", this, + "scheduled", scheduled); + scheduled_ = scheduled; +} + +bool CommandBufferService::PauseExecution() { + if (pause_execution_callback_.is_null()) + return false; + + bool pause = pause_execution_callback_.Run(); + if (paused_ != pause) { + TRACE_COUNTER_ID1("gpu", "CommandBufferService::Paused", this, pause); + paused_ = pause; + } + return pause; +} + +error::Error CommandBufferService::ProcessCommands(int num_commands) { + int num_entries = put_offset_ < state_.get_offset + ? num_entries_ - state_.get_offset + : put_offset_ - state_.get_offset; + + int entries_processed = 0; + error::Error result = + handler_->DoCommands(num_commands, buffer_ + state_.get_offset, + num_entries, &entries_processed); + + state_.get_offset += entries_processed; + if (state_.get_offset == num_entries_) + state_.get_offset = 0; + + return result; +} + } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/command_buffer_service.h b/chromium/gpu/command_buffer/service/command_buffer_service.h index 9e030db0456..96296c22492 100644 --- a/chromium/gpu/command_buffer/service/command_buffer_service.h +++ b/chromium/gpu/command_buffer/service/command_buffer_service.h @@ -14,15 +14,18 @@ #include "base/macros.h" #include "gpu/command_buffer/common/command_buffer.h" #include "gpu/command_buffer/common/command_buffer_shared.h" +#include "gpu/command_buffer/service/async_api_interface.h" namespace gpu { -class TransferBufferManagerInterface; +class TransferBufferManager; -class GPU_EXPORT CommandBufferServiceBase : public CommandBuffer { +class GPU_EXPORT CommandBufferServiceBase { public: - // Sets the current get offset. This can be called from any thread. - virtual void SetGetOffset(int32_t get_offset) = 0; + virtual ~CommandBufferServiceBase() {} + + // Gets the current state of the service. + virtual CommandBuffer::State GetState() = 0; // Set the release count for the last fence sync seen in the command stream. virtual void SetReleaseCount(uint64_t release_count) = 0; @@ -41,82 +44,96 @@ class GPU_EXPORT CommandBufferServiceBase : public CommandBuffer { // NOTE: if calling this in conjunction with SetParseError, // call this first. virtual void SetContextLostReason(error::ContextLostReason) = 0; - - // Allows the reader to obtain the current put offset. - virtual int32_t GetPutOffset() = 0; }; +union CommandBufferEntry; + // An object that implements a shared memory command buffer and a synchronous // API to manage the put and get pointers. class GPU_EXPORT CommandBufferService : public CommandBufferServiceBase { public: - typedef base::Callback<bool(int32_t)> GetBufferChangedCallback; - explicit CommandBufferService( - TransferBufferManagerInterface* transfer_buffer_manager); - ~CommandBufferService() override; + static const int kParseCommandsSlice = 20; + using PauseExecutionCallback = base::Callback<bool(void)>; - // CommandBuffer implementation: - State GetLastState() override; - void Flush(int32_t put_offset) override; - void OrderingBarrier(int32_t put_offset) override; - State WaitForTokenInRange(int32_t start, int32_t end) override; - State WaitForGetOffsetInRange(int32_t start, int32_t end) override; - void SetGetBuffer(int32_t transfer_buffer_id) override; - scoped_refptr<Buffer> CreateTransferBuffer(size_t size, int32_t* id) override; - void DestroyTransferBuffer(int32_t id) override; + CommandBufferService(TransferBufferManager* transfer_buffer_manager, + AsyncAPIInterface* handler); + ~CommandBufferService() override; // CommandBufferServiceBase implementation: - void SetGetOffset(int32_t get_offset) override; + CommandBuffer::State GetState() override; void SetReleaseCount(uint64_t release_count) override; scoped_refptr<Buffer> GetTransferBuffer(int32_t id) override; void SetToken(int32_t token) override; void SetParseError(error::Error error) override; void SetContextLostReason(error::ContextLostReason) override; - int32_t GetPutOffset() override; - - // Sets a callback that is called whenever the put offset is changed. When - // called with sync==true, the callback must not return until some progress - // has been made (unless the command buffer is empty), i.e. the get offset - // must have changed. It need not process the entire command buffer though. - // This allows concurrency between the writer and the reader while giving the - // writer a means of waiting for the reader to make some progress before - // attempting to write more to the command buffer. Takes ownership of - // callback. - virtual void SetPutOffsetChangeCallback(const base::Closure& callback); - // Sets a callback that is called whenever the get buffer is changed. - virtual void SetGetBufferChangeCallback( - const GetBufferChangedCallback& callback); - virtual void SetParseErrorCallback(const base::Closure& callback); + + void SetPauseExecutionCallback(const PauseExecutionCallback& callback); + void SetCommandProcessedCallback(const base::Closure& callback); + void SetParseErrorCallback(const base::Closure& callback); // Setup the shared memory that shared state should be copied into. void SetSharedStateBuffer(std::unique_ptr<BufferBacking> shared_state_buffer); - // Copy the current state into the shared state transfer buffer. + // Increments the generation and copies the current state into the shared + // state transfer buffer. void UpdateState(); - // Registers an existing shared memory object and get an ID that can be used + // Flushes up to the put_offset and calls the PutOffsetChangeCallback to + // execute commands. + void Flush(int32_t put_offset); + + // Sets the get buffer and call the GetBufferChangeCallback. + void SetGetBuffer(int32_t transfer_buffer_id); + + // Registers an existing shared memory object with a given ID that can be used // to identify it in the command buffer. bool RegisterTransferBuffer(int32_t id, std::unique_ptr<BufferBacking> buffer); + + // Unregisters and destroys the transfer buffer associated with the given id. + void DestroyTransferBuffer(int32_t id); + + // Creates an in-process transfer buffer and register it with a newly created + // id. + scoped_refptr<Buffer> CreateTransferBuffer(size_t size, int32_t* id); + + // Creates an in-process transfer buffer and register it with a given id. scoped_refptr<Buffer> CreateTransferBufferWithId(size_t size, int32_t id); + // Sets whether commands should be processed by this scheduler. Setting to + // false unschedules. Setting to true reschedules. + void SetScheduled(bool scheduled); + + bool scheduled() const { return scheduled_; } + + int32_t put_offset() const { return put_offset_; } + private: - int32_t ring_buffer_id_; + bool PauseExecution(); + error::Error ProcessCommands(int num_commands); + + TransferBufferManager* transfer_buffer_manager_; + AsyncAPIInterface* handler_; + + CommandBuffer::State state_; + int32_t put_offset_ = 0; + + int32_t ring_buffer_id_ = -1; + int32_t num_entries_ = 0; scoped_refptr<Buffer> ring_buffer_; + volatile CommandBufferEntry* buffer_ = nullptr; + std::unique_ptr<BufferBacking> shared_state_buffer_; - CommandBufferSharedState* shared_state_; - int32_t num_entries_; - int32_t get_offset_; - int32_t put_offset_; - base::Closure put_offset_change_callback_; - GetBufferChangedCallback get_buffer_change_callback_; + CommandBufferSharedState* shared_state_ = nullptr; + + // If this callback returns true, exit FlushHelper early. + PauseExecutionCallback pause_execution_callback_; + base::Closure command_processed_callback_; base::Closure parse_error_callback_; - scoped_refptr<TransferBufferManagerInterface> transfer_buffer_manager_; - int32_t token_; - uint64_t release_count_; - uint32_t generation_; - error::Error error_; - error::ContextLostReason context_lost_reason_; + + // Whether the scheduler is currently able to process more commands. + bool scheduled_ = true; + bool paused_ = false; DISALLOW_COPY_AND_ASSIGN(CommandBufferService); }; diff --git a/chromium/gpu/command_buffer/service/command_buffer_service_unittest.cc b/chromium/gpu/command_buffer/service/command_buffer_service_unittest.cc index d2d8b3c2e6e..d5df30dd727 100644 --- a/chromium/gpu/command_buffer/service/command_buffer_service_unittest.cc +++ b/chromium/gpu/command_buffer/service/command_buffer_service_unittest.cc @@ -1,153 +1,507 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 command parser. + #include <stddef.h> -#include <stdint.h> #include <memory> -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/threading/thread.h" -#include "gpu/command_buffer/common/cmd_buffer_common.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/service/command_buffer_service.h" +#include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" -#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using base::SharedMemory; +namespace gpu { + using testing::_; -using testing::DoAll; +using testing::Mock; using testing::Return; -using testing::SetArgumentPointee; -using testing::StrictMock; - -namespace gpu { +using testing::Sequence; +using testing::SetArgPointee; +// Test fixture for CommandBufferService test - Creates a mock +// AsyncAPIInterface, and a fixed size memory buffer. Also provides a simple API +// to create a CommandBufferService. class CommandBufferServiceTest : public testing::Test { + public: + MOCK_METHOD0(OnCommandProcessed, void()); + protected: - void SetUp() override { - { - TransferBufferManager* manager = new TransferBufferManager(nullptr); - transfer_buffer_manager_ = manager; - EXPECT_TRUE(manager->Initialize()); - } - command_buffer_.reset( - new CommandBufferService(transfer_buffer_manager_.get())); + virtual void SetUp() { api_mock_.reset(new AsyncAPIMock(false)); } + virtual void TearDown() {} + + void AddDoCommandsExpect(error::Error _return, + int num_entries, + int num_processed) { + EXPECT_CALL(*api_mock_, DoCommands(_, _, num_entries, _)) + .InSequence(sequence_) + .WillOnce(DoAll(SetArgPointee<3>(num_processed), Return(_return))); } - int32_t GetGetOffset() { return command_buffer_->GetLastState().get_offset; } + // Creates a CommandBufferService, with a buffer of the specified size (in + // entries). + void MakeService(unsigned int entry_count) { + transfer_buffer_manager_ = base::MakeUnique<TransferBufferManager>(nullptr); + command_buffer_service_ = base::MakeUnique<CommandBufferService>( + transfer_buffer_manager_.get(), api_mock()); + command_buffer_service_->SetParseErrorCallback(base::Bind( + &CommandBufferServiceTest::OnParseError, base::Unretained(this))); + SetNewGetBuffer(entry_count * sizeof(CommandBufferEntry)); + } - int32_t GetPutOffset() { return command_buffer_->GetPutOffset(); } + AsyncAPIMock* api_mock() { return api_mock_.get(); } + CommandBufferEntry* buffer() { + return static_cast<CommandBufferEntry*>(buffer_->memory()); + } - int32_t GetToken() { return command_buffer_->GetLastState().token; } + CommandBufferService* command_buffer_service() { + return command_buffer_service_.get(); + } + int32_t GetGet() { return command_buffer_service_->GetState().get_offset; } + int32_t GetPut() { return command_buffer_service_->put_offset(); } - int32_t GetError() { return command_buffer_->GetLastState().error; } + error::Error SetPutAndProcessAllCommands(int32_t put) { + command_buffer_service_->Flush(put); + EXPECT_EQ(put, GetPut()); + return command_buffer_service_->GetState().error; + } - bool Initialize(size_t entries) { - size_t size = entries * sizeof(CommandBufferEntry); - int32_t id; - command_buffer_->CreateTransferBuffer(size, &id); - EXPECT_GT(id, 0); - command_buffer_->SetGetBuffer(id); - return true; + int32_t SetNewGetBuffer(size_t size) { + int32_t id = 0; + buffer_ = command_buffer_service_->CreateTransferBuffer(size, &id); + command_buffer_service_->SetGetBuffer(id); + return id; } - scoped_refptr<TransferBufferManagerInterface> transfer_buffer_manager_; - std::unique_ptr<CommandBufferService> command_buffer_; + void AdvancePut(int32_t entries) { + DCHECK(entries > 0); + CommandBufferOffset put = GetPut(); + CommandHeader header; + header.size = entries; + header.command = 1; + buffer()[put].value_header = header; + put += entries; + AddDoCommandsExpect(error::kNoError, entries, entries); + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(put)); + EXPECT_EQ(put, GetPut()); + Mock::VerifyAndClearExpectations(api_mock()); + } + + MOCK_METHOD0(OnParseError, void()); + + private: + std::unique_ptr<AsyncAPIMock> api_mock_; + std::unique_ptr<TransferBufferManager> transfer_buffer_manager_; + std::unique_ptr<CommandBufferService> command_buffer_service_; + scoped_refptr<Buffer> buffer_; + Sequence sequence_; }; -TEST_F(CommandBufferServiceTest, InitializesCommandBuffer) { - EXPECT_TRUE(Initialize(1024)); - CommandBuffer::State state = command_buffer_->GetLastState(); - EXPECT_EQ(0, state.get_offset); - EXPECT_EQ(0, command_buffer_->GetPutOffset()); +// Tests initialization conditions. +TEST_F(CommandBufferServiceTest, TestInit) { + MakeService(10); + CommandBuffer::State state = command_buffer_service()->GetState(); + EXPECT_EQ(0, GetGet()); + EXPECT_EQ(0, GetPut()); EXPECT_EQ(0, state.token); EXPECT_EQ(error::kNoError, state.error); } -namespace { +TEST_F(CommandBufferServiceTest, TestEmpty) { + MakeService(10); + EXPECT_CALL(*api_mock(), DoCommands(_, _, _, _)).Times(0); -class CallbackTest { - public: - virtual void PutOffsetChanged() = 0; - virtual bool GetBufferChanged(int32_t id) = 0; -}; + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(0)); + EXPECT_EQ(0, GetGet()); +} -class MockCallbackTest : public CallbackTest { - public: - MOCK_METHOD0(PutOffsetChanged, void()); - MOCK_METHOD1(GetBufferChanged, bool(int32_t)); -}; +// Tests simple commands. +TEST_F(CommandBufferServiceTest, TestSimple) { + MakeService(10); + CommandBufferOffset put = GetPut(); + CommandHeader header; + + // add a single command, no args + header.size = 1; + header.command = 123; + buffer()[put++].value_header = header; + + AddDoCommandsExpect(error::kNoError, 1, 1); + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(put)); + EXPECT_EQ(put, GetGet()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add a single command, 2 args + header.size = 3; + header.command = 456; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 2134; + buffer()[put++].value_float = 1.f; + + AddDoCommandsExpect(error::kNoError, 3, 3); + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(put)); + EXPECT_EQ(put, GetGet()); + Mock::VerifyAndClearExpectations(api_mock()); +} + +// Tests having multiple commands in the buffer. +TEST_F(CommandBufferServiceTest, TestMultipleCommands) { + MakeService(10); + CommandBufferOffset put = GetPut(); + CommandHeader header; + + // add 2 commands, test with single ProcessAllCommands() + header.size = 2; + header.command = 789; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 5151; + + header.size = 2; + header.command = 876; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 3434; + + // Process commands. 4 entries remaining. + AddDoCommandsExpect(error::kNoError, 4, 4); + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(put)); + EXPECT_EQ(put, GetGet()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add 2 commands again, test with ProcessAllCommands() + header.size = 2; + header.command = 123; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 5656; + + header.size = 2; + header.command = 321; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 7878; + + // 4 entries remaining. + AddDoCommandsExpect(error::kNoError, 4, 4); + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(put)); + EXPECT_EQ(put, GetGet()); + Mock::VerifyAndClearExpectations(api_mock()); +} + +// Tests that the parser will wrap correctly at the end of the buffer. +TEST_F(CommandBufferServiceTest, TestWrap) { + MakeService(5); + CommandBufferOffset put = GetPut(); + CommandHeader header; + + // add 3 commands with no args (1 word each) + for (unsigned int i = 0; i < 3; ++i) { + header.size = 1; + header.command = i; + buffer()[put++].value_header = header; + } + + // Process up to 10 commands. 3 entries remaining to put. + AddDoCommandsExpect(error::kNoError, 3, 3); + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(put)); + EXPECT_EQ(put, GetGet()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add 1 command with 1 arg (2 words). That should put us at the end of the + // buffer. + header.size = 2; + header.command = 3; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 5; + + DCHECK_EQ(5, put); + put = 0; + + // add 1 command with 1 arg (2 words). + header.size = 2; + header.command = 4; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 6; -} // anonymous namespace - -TEST_F(CommandBufferServiceTest, CanSyncGetAndPutOffset) { - Initialize(1024); - - std::unique_ptr<StrictMock<MockCallbackTest>> change_callback( - new StrictMock<MockCallbackTest>); - command_buffer_->SetPutOffsetChangeCallback( - base::Bind( - &CallbackTest::PutOffsetChanged, - base::Unretained(change_callback.get()))); - - EXPECT_CALL(*change_callback, PutOffsetChanged()); - command_buffer_->Flush(2); - EXPECT_EQ(0, GetGetOffset()); - EXPECT_EQ(2, GetPutOffset()); - - EXPECT_CALL(*change_callback, PutOffsetChanged()); - command_buffer_->Flush(4); - EXPECT_EQ(0, GetGetOffset()); - EXPECT_EQ(4, GetPutOffset()); - - command_buffer_->SetGetOffset(2); - EXPECT_EQ(2, GetGetOffset()); - EXPECT_CALL(*change_callback, PutOffsetChanged()); - command_buffer_->Flush(6); - - command_buffer_->Flush(-1); - EXPECT_NE(error::kNoError, GetError()); - command_buffer_->Flush(1024); - EXPECT_NE(error::kNoError, GetError()); + // 2 entries remaining to end of buffer. + AddDoCommandsExpect(error::kNoError, 2, 2); + // 2 entries remaining to put. + AddDoCommandsExpect(error::kNoError, 2, 2); + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(put)); + EXPECT_EQ(put, GetGet()); + Mock::VerifyAndClearExpectations(api_mock()); } -TEST_F(CommandBufferServiceTest, SetGetBuffer) { - int32_t ring_buffer_id; - command_buffer_->CreateTransferBuffer(1024, &ring_buffer_id); - EXPECT_GT(ring_buffer_id, 0); +// Tests error conditions. +TEST_F(CommandBufferServiceTest, TestError) { + const unsigned int kNumEntries = 5; + MakeService(kNumEntries); + CommandBufferOffset put = GetPut(); + CommandHeader header; - std::unique_ptr<StrictMock<MockCallbackTest>> change_callback( - new StrictMock<MockCallbackTest>); - command_buffer_->SetGetBufferChangeCallback( - base::Bind( - &CallbackTest::GetBufferChanged, - base::Unretained(change_callback.get()))); + // Generate a command with size 0. + header.size = 0; + header.command = 3; + buffer()[put++].value_header = header; - EXPECT_CALL(*change_callback, GetBufferChanged(ring_buffer_id)) - .WillOnce(Return(true)); + AddDoCommandsExpect(error::kInvalidSize, 1, 0); + EXPECT_CALL(*this, OnParseError()).Times(1); + EXPECT_EQ(error::kInvalidSize, SetPutAndProcessAllCommands(put)); + // check that no DoCommand call was made. + Mock::VerifyAndClearExpectations(api_mock()); + Mock::VerifyAndClearExpectations(this); - command_buffer_->SetGetBuffer(ring_buffer_id); - EXPECT_EQ(0, GetGetOffset()); + MakeService(5); + put = GetPut(); + + // Generate a command with size 6, extends beyond the end of the buffer. + header.size = 6; + header.command = 3; + buffer()[put++].value_header = header; + + AddDoCommandsExpect(error::kOutOfBounds, 1, 0); + EXPECT_CALL(*this, OnParseError()).Times(1); + EXPECT_EQ(error::kOutOfBounds, SetPutAndProcessAllCommands(put)); + // check that no DoCommand call was made. + Mock::VerifyAndClearExpectations(api_mock()); + Mock::VerifyAndClearExpectations(this); + + MakeService(5); + put = GetPut(); + + // Generates 2 commands. + header.size = 1; + header.command = 3; + buffer()[put++].value_header = header; + CommandBufferOffset put_post_fail = put; + header.size = 1; + header.command = 4; + buffer()[put++].value_header = header; + + // have the first command fail to parse. + AddDoCommandsExpect(error::kUnknownCommand, 2, 1); + EXPECT_CALL(*this, OnParseError()).Times(1); + EXPECT_EQ(error::kUnknownCommand, SetPutAndProcessAllCommands(put)); + // check that only one command was executed, and that get reflects that + // correctly. + EXPECT_EQ(put_post_fail, GetGet()); + Mock::VerifyAndClearExpectations(api_mock()); + Mock::VerifyAndClearExpectations(this); + // make the second one succeed, and check that the service doesn't try to + // recover. + EXPECT_CALL(*this, OnParseError()).Times(0); + EXPECT_EQ(error::kUnknownCommand, SetPutAndProcessAllCommands(put)); + EXPECT_EQ(put_post_fail, GetGet()); + Mock::VerifyAndClearExpectations(api_mock()); + Mock::VerifyAndClearExpectations(this); + + // Try to flush out-of-bounds, should fail. + MakeService(kNumEntries); + AdvancePut(2); + EXPECT_EQ(2, GetPut()); + + EXPECT_CALL(*this, OnParseError()).Times(1); + command_buffer_service()->Flush(kNumEntries + 1); + CommandBuffer::State state1 = command_buffer_service()->GetState(); + EXPECT_EQ(2, GetPut()); + EXPECT_EQ(error::kOutOfBounds, state1.error); + Mock::VerifyAndClearExpectations(this); + + MakeService(kNumEntries); + AdvancePut(2); + EXPECT_EQ(2, GetPut()); + + EXPECT_CALL(*this, OnParseError()).Times(1); + command_buffer_service()->Flush(-1); + CommandBuffer::State state2 = command_buffer_service()->GetState(); + EXPECT_EQ(2, GetPut()); + EXPECT_EQ(error::kOutOfBounds, state2.error); + Mock::VerifyAndClearExpectations(this); } -TEST_F(CommandBufferServiceTest, DefaultTokenIsZero) { - EXPECT_EQ(0, GetToken()); +TEST_F(CommandBufferServiceTest, SetBuffer) { + MakeService(3); + AdvancePut(2); + // We should have advanced 2 entries. + EXPECT_EQ(2, GetGet()); + + CommandBuffer::State state1 = command_buffer_service()->GetState(); + int32_t id = SetNewGetBuffer(3 * sizeof(CommandBufferEntry)); + CommandBuffer::State state2 = command_buffer_service()->GetState(); + // The put and get should have reset to 0. + EXPECT_EQ(0, GetGet()); + EXPECT_EQ(0, GetPut()); + EXPECT_EQ(error::kNoError, state2.error); + EXPECT_EQ(state1.token, state2.token); + EXPECT_EQ(state1.set_get_buffer_count + 1, state2.set_get_buffer_count); + + AdvancePut(2); + // We should have advanced 2 entries. + EXPECT_EQ(2, GetGet()); + + // Destroy current get buffer, should reset. + command_buffer_service()->DestroyTransferBuffer(id); + CommandBuffer::State state3 = command_buffer_service()->GetState(); + EXPECT_EQ(0, GetGet()); + EXPECT_EQ(0, GetPut()); + EXPECT_EQ(error::kNoError, state3.error); + // Should not update the set_get_buffer_count however, since SetGetBuffer was + // not called. + EXPECT_EQ(state2.set_get_buffer_count, state3.set_get_buffer_count); + + // Trying to execute commands should fail however. + EXPECT_CALL(*this, OnParseError()).Times(1); + command_buffer_service()->Flush(2); + CommandBuffer::State state4 = command_buffer_service()->GetState(); + EXPECT_EQ(0, GetPut()); + EXPECT_EQ(error::kOutOfBounds, state4.error); + Mock::VerifyAndClearExpectations(this); } -TEST_F(CommandBufferServiceTest, CanSetToken) { - command_buffer_->SetToken(7); - EXPECT_EQ(7, GetToken()); +TEST_F(CommandBufferServiceTest, InvalidSetBuffer) { + MakeService(3); + CommandBuffer::State state1 = command_buffer_service()->GetState(); + + // Set an invalid transfer buffer, should succeed. + command_buffer_service()->SetGetBuffer(0); + CommandBuffer::State state2 = command_buffer_service()->GetState(); + EXPECT_EQ(0, GetGet()); + EXPECT_EQ(0, GetPut()); + EXPECT_EQ(error::kNoError, state2.error); + EXPECT_EQ(state1.token, state2.token); + EXPECT_EQ(state1.set_get_buffer_count + 1, state2.set_get_buffer_count); + + // Trying to execute commands should fail however. + EXPECT_CALL(*this, OnParseError()).Times(1); + command_buffer_service()->Flush(2); + CommandBuffer::State state3 = command_buffer_service()->GetState(); + EXPECT_EQ(0, GetPut()); + EXPECT_EQ(error::kOutOfBounds, state3.error); + Mock::VerifyAndClearExpectations(this); } -TEST_F(CommandBufferServiceTest, DefaultParseErrorIsNoError) { - EXPECT_EQ(0, GetError()); +TEST_F(CommandBufferServiceTest, Token) { + MakeService(3); + command_buffer_service()->SetToken(7); + EXPECT_EQ(7, command_buffer_service()->GetState().token); } TEST_F(CommandBufferServiceTest, CanSetParseError) { - command_buffer_->SetParseError(error::kInvalidSize); - EXPECT_EQ(1, GetError()); + MakeService(3); + + EXPECT_CALL(*this, OnParseError()).Times(1); + command_buffer_service()->SetParseError(error::kInvalidSize); + EXPECT_EQ(error::kInvalidSize, command_buffer_service()->GetState().error); + Mock::VerifyAndClearExpectations(this); } + +TEST_F(CommandBufferServiceTest, CommandsProcessed) { + MakeService(3); + command_buffer_service()->SetCommandProcessedCallback(base::Bind( + &CommandBufferServiceTest::OnCommandProcessed, base::Unretained(this))); + AddDoCommandsExpect(error::kNoError, 2, 1); + AddDoCommandsExpect(error::kNoError, 1, 1); + EXPECT_CALL(*this, OnCommandProcessed()).Times(2); + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(2)); +} + +class CommandBufferServicePauseExecutionTest : public CommandBufferServiceTest { + public: + // Will pause the command buffer execution after 2 runs. + error::Error DoCommands(unsigned int num_commands, + const volatile void* buffer, + int num_entries, + int* entries_processed) { + ++calls_; + if (calls_ == 2) + pause_ = true; + *entries_processed = 1; + return error::kNoError; + } + + bool PauseExecution() { return pause_; } + + protected: + int calls_ = 0; + bool pause_ = false; +}; + +TEST_F(CommandBufferServicePauseExecutionTest, PauseExecution) { + MakeService(5); + command_buffer_service()->SetPauseExecutionCallback( + base::Bind(&CommandBufferServicePauseExecutionTest::PauseExecution, + base::Unretained(this))); + EXPECT_CALL(*api_mock(), DoCommands(_, _, _, _)) + .WillRepeatedly( + Invoke(this, &CommandBufferServicePauseExecutionTest::DoCommands)); + // Command buffer processing should stop after 2 commands. + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(4)); + EXPECT_EQ(2, GetGet()); + EXPECT_EQ(4, GetPut()); + EXPECT_EQ(2, calls_); + EXPECT_TRUE(pause_); + + // Processing shouldn't do anything while paused. + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(4)); + EXPECT_EQ(2, GetGet()); + EXPECT_EQ(4, GetPut()); + EXPECT_EQ(2, calls_); + EXPECT_TRUE(pause_); + + // Processing should continue after resume. + pause_ = false; + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(4)); + EXPECT_EQ(4, GetGet()); + EXPECT_EQ(4, GetPut()); + EXPECT_EQ(4, calls_); + EXPECT_FALSE(pause_); +} + +class CommandBufferServiceUnscheduleExecutionTest + : public CommandBufferServiceTest { + public: + enum { kUnscheduleAfterCalls = 2 }; + + // Will unschedule the command buffer execution after 2 runs. + error::Error DoCommands(unsigned int num_commands, + const volatile void* buffer, + int num_entries, + int* entries_processed) { + ++calls_; + if (calls_ == kUnscheduleAfterCalls) { + command_buffer_service()->SetScheduled(false); + *entries_processed = 0; + return error::kDeferCommandUntilLater; + } + *entries_processed = 1; + return error::kNoError; + } + + protected: + int calls_ = 0; +}; + +TEST_F(CommandBufferServiceUnscheduleExecutionTest, Unschedule) { + MakeService(5); + EXPECT_CALL(*api_mock(), DoCommands(_, _, _, _)) + .WillRepeatedly(Invoke( + this, &CommandBufferServiceUnscheduleExecutionTest::DoCommands)); + // Command buffer processing should stop after 2 commands. + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(4)); + EXPECT_EQ(1, GetGet()); + EXPECT_EQ(4, GetPut()); + EXPECT_EQ(kUnscheduleAfterCalls, calls_); + EXPECT_FALSE(command_buffer_service()->scheduled()); + + // Processing should continue after rescheduling. + command_buffer_service()->SetScheduled(true); + EXPECT_EQ(error::kNoError, SetPutAndProcessAllCommands(4)); + EXPECT_EQ(4, GetGet()); + EXPECT_EQ(4, GetPut()); + EXPECT_EQ(5, calls_); + EXPECT_TRUE(command_buffer_service()->scheduled()); +} + } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/command_executor.cc b/chromium/gpu/command_buffer/service/command_executor.cc deleted file mode 100644 index e0bc504584b..00000000000 --- a/chromium/gpu/command_buffer/service/command_executor.cc +++ /dev/null @@ -1,188 +0,0 @@ -// 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 "gpu/command_buffer/service/command_executor.h" - -#include <stdint.h> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/compiler_specific.h" -#include "base/message_loop/message_loop.h" -#include "base/time/time.h" -#include "base/trace_event/trace_event.h" -#include "gpu/command_buffer/service/logger.h" -#include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_fence.h" -#include "ui/gl/gl_switches.h" - -using ::base::SharedMemory; - -namespace gpu { - -CommandExecutor::CommandExecutor(CommandBufferServiceBase* command_buffer, - AsyncAPIInterface* handler, - gles2::GLES2Decoder* decoder) - : command_buffer_(command_buffer), handler_(handler), decoder_(decoder) {} - -CommandExecutor::~CommandExecutor() {} - -void CommandExecutor::PutChanged() { - TRACE_EVENT1("gpu", "CommandExecutor:PutChanged", "decoder", - decoder_ ? decoder_->GetLogger()->GetLogPrefix() : "None"); - - CommandBuffer::State state = command_buffer_->GetLastState(); - - // If there is no parser, exit. - if (!parser_.get()) { - DCHECK_EQ(state.get_offset, command_buffer_->GetPutOffset()); - return; - } - - parser_->set_put(command_buffer_->GetPutOffset()); - if (state.error != error::kNoError) - return; - - base::TimeTicks begin_time(base::TimeTicks::Now()); - error::Error error = error::kNoError; - if (decoder_) - decoder_->BeginDecoding(); - while (!parser_->IsEmpty()) { - if (PauseExecution()) - break; - - DCHECK(scheduled()); - - error = parser_->ProcessCommands(CommandParser::kParseCommandsSlice); - - if (error == error::kDeferCommandUntilLater) { - DCHECK(!scheduled()); - break; - } - - // TODO(piman): various classes duplicate various pieces of state, leading - // to needlessly complex update logic. It should be possible to simply - // share the state across all of them. - command_buffer_->SetGetOffset(static_cast<int32_t>(parser_->get())); - - if (error::IsError(error)) { - command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); - command_buffer_->SetParseError(error); - break; - } - - if (!command_processed_callback_.is_null()) - command_processed_callback_.Run(); - - if (!scheduled()) - break; - } - - if (decoder_) { - if (!error::IsError(error) && decoder_->WasContextLost()) { - command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); - command_buffer_->SetParseError(error::kLostContext); - } - decoder_->EndDecoding(); - decoder_->AddProcessingCommandsTime(base::TimeTicks::Now() - begin_time); - } -} - -void CommandExecutor::SetScheduled(bool scheduled) { - TRACE_EVENT2("gpu", "CommandExecutor:SetScheduled", "this", this, "scheduled", - scheduled); - scheduled_ = scheduled; -} - -bool CommandExecutor::HasPendingQueries() const { - return (decoder_ && decoder_->HasPendingQueries()); -} - -void CommandExecutor::ProcessPendingQueries() { - if (!decoder_) - return; - decoder_->ProcessPendingQueries(false); -} - -scoped_refptr<Buffer> CommandExecutor::GetSharedMemoryBuffer(int32_t shm_id) { - return command_buffer_->GetTransferBuffer(shm_id); -} - -void CommandExecutor::set_token(int32_t token) { - command_buffer_->SetToken(token); -} - -bool CommandExecutor::SetGetBuffer(int32_t transfer_buffer_id) { - scoped_refptr<Buffer> ring_buffer = - command_buffer_->GetTransferBuffer(transfer_buffer_id); - if (!ring_buffer.get()) { - return false; - } - - if (!parser_.get()) { - parser_.reset(new CommandParser(handler_)); - } - - parser_->SetBuffer(ring_buffer->memory(), ring_buffer->size(), 0, - ring_buffer->size()); - - SetGetOffset(0); - return true; -} - -bool CommandExecutor::SetGetOffset(int32_t offset) { - if (parser_->set_get(offset)) { - command_buffer_->SetGetOffset(static_cast<int32_t>(parser_->get())); - return true; - } - return false; -} - -int32_t CommandExecutor::GetGetOffset() { - return parser_->get(); -} - -void CommandExecutor::SetCommandProcessedCallback( - const base::Closure& callback) { - command_processed_callback_ = callback; -} - -void CommandExecutor::SetPauseExecutionCallback( - const PauseExecutionCallback& callback) { - pause_execution_callback_ = callback; -} - -bool CommandExecutor::PauseExecution() { - if (pause_execution_callback_.is_null()) - return false; - - bool pause = pause_execution_callback_.Run(); - if (paused_ != pause) { - TRACE_COUNTER_ID1("gpu", "CommandExecutor::Paused", this, pause); - paused_ = pause; - } - return pause; -} - -bool CommandExecutor::HasMoreIdleWork() const { - return (decoder_ && decoder_->HasMoreIdleWork()); -} - -void CommandExecutor::PerformIdleWork() { - if (!decoder_) - return; - decoder_->PerformIdleWork(); -} - -bool CommandExecutor::HasPollingWork() const { - return (decoder_ && decoder_->HasPollingWork()); -} - -void CommandExecutor::PerformPollingWork() { - if (!decoder_) - return; - decoder_->PerformPollingWork(); -} - -} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/command_executor.h b/chromium/gpu/command_buffer/service/command_executor.h deleted file mode 100644 index 6189c4b99a6..00000000000 --- a/chromium/gpu/command_buffer/service/command_executor.h +++ /dev/null @@ -1,116 +0,0 @@ -// 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_SERVICE_COMMAND_EXECUTOR_H_ -#define GPU_COMMAND_BUFFER_SERVICE_COMMAND_EXECUTOR_H_ - -#include <stdint.h> - -#include <memory> -#include <queue> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/shared_memory.h" -#include "base/memory/weak_ptr.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" -#include "gpu/command_buffer/service/cmd_parser.h" -#include "gpu/command_buffer/service/command_buffer_service.h" -#include "gpu/command_buffer/service/gles2_cmd_decoder.h" -#include "gpu/gpu_export.h" - -namespace gpu { - -// This class schedules commands that have been flushed. They are received via -// a command buffer and forwarded to a command parser. TODO(apatrick): This -// class should not know about the decoder. Do not add additional dependencies -// on it. -class GPU_EXPORT CommandExecutor - : NON_EXPORTED_BASE(public CommandBufferEngine), - public base::SupportsWeakPtr<CommandExecutor> { - public: - CommandExecutor(CommandBufferServiceBase* command_buffer, - AsyncAPIInterface* handler, - gles2::GLES2Decoder* decoder); - - ~CommandExecutor() override; - - void PutChanged(); - - // Sets whether commands should be processed by this scheduler. Setting to - // false unschedules. Setting to true reschedules. - void SetScheduled(bool scheduled); - - bool scheduled() const { return scheduled_; } - - // Returns whether the scheduler needs to be polled again in the future to - // process pending queries. - bool HasPendingQueries() const; - - // Process pending queries and return. HasPendingQueries() can be used to - // determine if there's more pending queries after this has been called. - void ProcessPendingQueries(); - - // Implementation of CommandBufferEngine. - scoped_refptr<Buffer> GetSharedMemoryBuffer(int32_t shm_id) override; - void set_token(int32_t token) override; - bool SetGetBuffer(int32_t transfer_buffer_id) override; - bool SetGetOffset(int32_t offset) override; - int32_t GetGetOffset() override; - - void SetCommandProcessedCallback(const base::Closure& callback); - - using PauseExecutionCallback = base::Callback<bool(void)>; - void SetPauseExecutionCallback(const PauseExecutionCallback& callback); - - // Returns whether the scheduler needs to be polled again in the future to - // process idle work. - bool HasMoreIdleWork() const; - - // Perform some idle work and return. HasMoreIdleWork() can be used to - // determine if there's more idle work do be done after this has been called. - void PerformIdleWork(); - - // Whether there is state that needs to be regularly polled. - bool HasPollingWork() const; - void PerformPollingWork(); - - CommandParser* parser() const { return parser_.get(); } - - private: - bool PauseExecution(); - - // The CommandExecutor holds a weak reference to the CommandBuffer. The - // CommandBuffer owns the CommandExecutor and holds a strong reference to it - // through the ProcessCommands callback. - CommandBufferServiceBase* command_buffer_; - - // The parser uses this to execute commands. - AsyncAPIInterface* handler_; - - // Does not own decoder. TODO(apatrick): The CommandExecutor shouldn't need a - // pointer to the decoder, it is only used to initialize the CommandParser, - // which could be an argument to the constructor, and to determine the - // reason for context lost. - gles2::GLES2Decoder* decoder_; - - // TODO(apatrick): The CommandExecutor currently creates and owns the parser. - // This should be an argument to the constructor. - std::unique_ptr<CommandParser> parser_; - - // Whether the scheduler is currently able to process more commands. - bool scheduled_ = true; - - base::Closure command_processed_callback_; - - // If this callback returns true, exit PutChanged early. - PauseExecutionCallback pause_execution_callback_; - bool paused_ = false; - - DISALLOW_COPY_AND_ASSIGN(CommandExecutor); -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_SERVICE_COMMAND_EXECUTOR_H_ diff --git a/chromium/gpu/command_buffer/service/command_executor_unittest.cc b/chromium/gpu/command_buffer/service/command_executor_unittest.cc deleted file mode 100644 index 34610ed0439..00000000000 --- a/chromium/gpu/command_buffer/service/command_executor_unittest.cc +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (c) 2011 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/command_executor.h" - -#include <stddef.h> -#include <stdint.h> - -#include <memory> - -#include "base/run_loop.h" -#include "base/test/scoped_task_environment.h" -#include "gpu/command_buffer/common/command_buffer_mock.h" -#include "gpu/command_buffer/service/gles2_cmd_decoder.h" -#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" -#include "gpu/command_buffer/service/mocks.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::_; -using testing::DoAll; -using testing::Invoke; -using testing::NiceMock; -using testing::Return; -using testing::SetArgumentPointee; -using testing::StrictMock; - -namespace gpu { - -const size_t kRingBufferSize = 1024; - -class CommandExecutorTest : public testing::Test { - protected: - static const int32_t kTransferBufferId = 123; - - void SetUp() override { - std::unique_ptr<base::SharedMemory> shared_memory(new ::base::SharedMemory); - shared_memory->CreateAndMapAnonymous(kRingBufferSize); - buffer_ = static_cast<int32_t*>(shared_memory->memory()); - shared_memory_buffer_ = - MakeBufferFromSharedMemory(std::move(shared_memory), kRingBufferSize); - memset(buffer_, 0, kRingBufferSize); - - command_buffer_.reset(new MockCommandBuffer); - - CommandBuffer::State default_state; - ON_CALL(*command_buffer_.get(), GetLastState()) - .WillByDefault(Return(default_state)); - ON_CALL(*command_buffer_.get(), GetPutOffset()).WillByDefault(Return(0)); - - decoder_.reset(new gles2::MockGLES2Decoder()); - // Install FakeDoCommands handler so we can use individual DoCommand() - // expectations. - EXPECT_CALL(*decoder_, DoCommands(_, _, _, _)) - .WillRepeatedly( - Invoke(decoder_.get(), &gles2::MockGLES2Decoder::FakeDoCommands)); - - executor_.reset(new gpu::CommandExecutor(command_buffer_.get(), - decoder_.get(), decoder_.get())); - EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId)) - .WillOnce(Return(shared_memory_buffer_)); - EXPECT_CALL(*command_buffer_, SetGetOffset(0)); - EXPECT_TRUE(executor_->SetGetBuffer(kTransferBufferId)); - } - - void TearDown() override { - // Ensure that any unexpected tasks posted by the GPU scheduler are executed - // in order to fail the test. - base::RunLoop().RunUntilIdle(); - } - - error::Error GetError() { return command_buffer_->GetLastState().error; } - - std::unique_ptr<MockCommandBuffer> command_buffer_; - scoped_refptr<Buffer> shared_memory_buffer_; - int32_t* buffer_; - std::unique_ptr<gles2::MockGLES2Decoder> decoder_; - std::unique_ptr<CommandExecutor> executor_; - base::test::ScopedTaskEnvironment scoped_task_environment_; -}; - -TEST_F(CommandExecutorTest, ExecutorDoesNothingIfRingBufferIsEmpty) { - CommandBuffer::State state; - - EXPECT_CALL(*command_buffer_, GetLastState()).WillRepeatedly(Return(state)); - - EXPECT_CALL(*command_buffer_, SetParseError(_)).Times(0); - - executor_->PutChanged(); -} - -TEST_F(CommandExecutorTest, GetSetBuffer) { - CommandBuffer::State state; - - // Set the get offset to something not 0. - EXPECT_CALL(*command_buffer_, SetGetOffset(2)); - executor_->SetGetOffset(2); - EXPECT_EQ(2, executor_->GetGetOffset()); - - // Set the buffer. - EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId)) - .WillOnce(Return(shared_memory_buffer_)); - EXPECT_CALL(*command_buffer_, SetGetOffset(0)); - EXPECT_TRUE(executor_->SetGetBuffer(kTransferBufferId)); - - // Check the get offset was reset. - EXPECT_EQ(0, executor_->GetGetOffset()); -} - -TEST_F(CommandExecutorTest, ProcessesOneCommand) { - CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); - header[0].command = 7; - header[0].size = 2; - buffer_[1] = 123; - - CommandBuffer::State state; - - EXPECT_CALL(*command_buffer_, GetLastState()).WillRepeatedly(Return(state)); - EXPECT_CALL(*command_buffer_, GetPutOffset()).WillRepeatedly(Return(2)); - EXPECT_CALL(*command_buffer_, SetGetOffset(2)); - - EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0])) - .WillOnce(Return(error::kNoError)); - - EXPECT_CALL(*command_buffer_, SetParseError(_)).Times(0); - - executor_->PutChanged(); -} - -TEST_F(CommandExecutorTest, ProcessesTwoCommands) { - CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); - header[0].command = 7; - header[0].size = 2; - buffer_[1] = 123; - header[2].command = 8; - header[2].size = 1; - - CommandBuffer::State state; - - EXPECT_CALL(*command_buffer_, GetLastState()).WillRepeatedly(Return(state)); - EXPECT_CALL(*command_buffer_, GetPutOffset()).WillRepeatedly(Return(3)); - - EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0])) - .WillOnce(Return(error::kNoError)); - - EXPECT_CALL(*decoder_, DoCommand(8, 0, &buffer_[2])) - .WillOnce(Return(error::kNoError)); - EXPECT_CALL(*command_buffer_, SetGetOffset(3)); - - executor_->PutChanged(); -} - -TEST_F(CommandExecutorTest, SetsErrorCodeOnCommandBuffer) { - CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); - header[0].command = 7; - header[0].size = 1; - - CommandBuffer::State state; - - EXPECT_CALL(*command_buffer_, GetLastState()).WillRepeatedly(Return(state)); - EXPECT_CALL(*command_buffer_, GetPutOffset()).WillRepeatedly(Return(1)); - - EXPECT_CALL(*decoder_, DoCommand(7, 0, &buffer_[0])) - .WillOnce(Return(error::kUnknownCommand)); - EXPECT_CALL(*command_buffer_, SetGetOffset(1)); - - EXPECT_CALL(*command_buffer_, SetContextLostReason(_)); - EXPECT_CALL(*decoder_, GetContextLostReason()) - .WillOnce(Return(error::kUnknown)); - EXPECT_CALL(*command_buffer_, SetParseError(error::kUnknownCommand)); - - executor_->PutChanged(); -} - -TEST_F(CommandExecutorTest, ProcessCommandsDoesNothingAfterError) { - CommandBuffer::State state; - state.error = error::kGenericError; - - EXPECT_CALL(*command_buffer_, GetLastState()).WillRepeatedly(Return(state)); - - executor_->PutChanged(); -} - -TEST_F(CommandExecutorTest, CanGetAddressOfSharedMemory) { - EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) - .WillOnce(Return(shared_memory_buffer_)); - - EXPECT_EQ(&buffer_[0], executor_->GetSharedMemoryBuffer(7)->memory()); -} - -ACTION_P2(SetPointee, address, value) { - *address = value; -} - -TEST_F(CommandExecutorTest, CanGetSizeOfSharedMemory) { - EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) - .WillOnce(Return(shared_memory_buffer_)); - - EXPECT_EQ(kRingBufferSize, executor_->GetSharedMemoryBuffer(7)->size()); -} - -TEST_F(CommandExecutorTest, SetTokenForwardsToCommandBuffer) { - EXPECT_CALL(*command_buffer_, SetToken(7)); - executor_->set_token(7); -} - -} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/common_decoder.cc b/chromium/gpu/command_buffer/service/common_decoder.cc index a561056e354..ae6920f7af8 100644 --- a/chromium/gpu/command_buffer/service/common_decoder.cc +++ b/chromium/gpu/command_buffer/service/common_decoder.cc @@ -10,7 +10,7 @@ #include <algorithm> #include "base/numerics/safe_math.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" +#include "gpu/command_buffer/service/command_buffer_service.h" namespace gpu { namespace { @@ -127,17 +127,19 @@ bool CommonDecoder::Bucket::GetAsStrings( } CommonDecoder::CommonDecoder() - : engine_(NULL), max_bucket_size_(kDefaultMaxBucketSize) {} + : command_buffer_service_(nullptr), + max_bucket_size_(kDefaultMaxBucketSize) {} CommonDecoder::~CommonDecoder() {} void* CommonDecoder::GetAddressAndCheckSize(unsigned int shm_id, unsigned int data_offset, unsigned int data_size) { - CHECK(engine_); - scoped_refptr<gpu::Buffer> buffer = engine_->GetSharedMemoryBuffer(shm_id); + CHECK(command_buffer_service_); + scoped_refptr<gpu::Buffer> buffer = + command_buffer_service_->GetTransferBuffer(shm_id); if (!buffer.get()) - return NULL; + return nullptr; return buffer->GetDataAddress(data_offset, data_size); } @@ -145,17 +147,19 @@ void* CommonDecoder::GetAddressAndSize(unsigned int shm_id, unsigned int data_offset, unsigned int minimum_size, unsigned int* data_size) { - CHECK(engine_); - scoped_refptr<gpu::Buffer> buffer = engine_->GetSharedMemoryBuffer(shm_id); + CHECK(command_buffer_service_); + scoped_refptr<gpu::Buffer> buffer = + command_buffer_service_->GetTransferBuffer(shm_id); if (!buffer.get() || buffer->GetRemainingSize(data_offset) < minimum_size) - return NULL; + return nullptr; return buffer->GetDataAddressAndSize(data_offset, data_size); } unsigned int CommonDecoder::GetSharedMemorySize(unsigned int shm_id, unsigned int offset) { - CHECK(engine_); - scoped_refptr<gpu::Buffer> buffer = engine_->GetSharedMemoryBuffer(shm_id); + CHECK(command_buffer_service_); + scoped_refptr<gpu::Buffer> buffer = + command_buffer_service_->GetTransferBuffer(shm_id); if (!buffer.get()) return 0; return buffer->GetRemainingSize(offset); @@ -163,7 +167,7 @@ unsigned int CommonDecoder::GetSharedMemorySize(unsigned int shm_id, scoped_refptr<gpu::Buffer> CommonDecoder::GetSharedMemoryBuffer( unsigned int shm_id) { - return engine_->GetSharedMemoryBuffer(shm_id); + return command_buffer_service_->GetTransferBuffer(shm_id); } const char* CommonDecoder::GetCommonCommandName( @@ -233,7 +237,7 @@ error::Error CommonDecoder::HandleSetToken(uint32_t immediate_data_size, const volatile void* cmd_data) { const volatile cmd::SetToken& args = *static_cast<const volatile cmd::SetToken*>(cmd_data); - engine_->set_token(args.token); + command_buffer_service_->SetToken(args.token); return error::kNoError; } diff --git a/chromium/gpu/command_buffer/service/common_decoder.h b/chromium/gpu/command_buffer/service/common_decoder.h index 3c23d539b67..ebf06327e9f 100644 --- a/chromium/gpu/command_buffer/service/common_decoder.h +++ b/chromium/gpu/command_buffer/service/common_decoder.h @@ -14,7 +14,8 @@ #include "base/macros.h" #include "gpu/command_buffer/common/buffer.h" -#include "gpu/command_buffer/service/cmd_parser.h" +#include "gpu/command_buffer/common/cmd_buffer_common.h" +#include "gpu/command_buffer/service/async_api_interface.h" #include "gpu/gpu_export.h" // Forwardly declare a few GL types to avoid including GL header files. @@ -23,11 +24,11 @@ typedef int GLint; namespace gpu { -class CommandBufferEngine; +class CommandBufferServiceBase; // This class is a helper base class for implementing the common parts of the // o3d/gl2 command buffer decoder. -class GPU_EXPORT CommonDecoder : NON_EXPORTED_BASE(public AsyncAPIInterface) { +class GPU_EXPORT CommonDecoder { public: typedef error::Error Error; @@ -109,14 +110,17 @@ class GPU_EXPORT CommonDecoder : NON_EXPORTED_BASE(public AsyncAPIInterface) { }; CommonDecoder(); - ~CommonDecoder() override; + ~CommonDecoder(); // Sets the engine, to get shared memory buffers from, and to set the token // to. - void set_engine(CommandBufferEngine* engine) { - engine_ = engine; + void set_command_buffer_service( + CommandBufferServiceBase* command_buffer_service) { + command_buffer_service_ = command_buffer_service; + } + CommandBufferServiceBase* command_buffer_service() const { + return command_buffer_service_; } - CommandBufferEngine* engine() const { return engine_; } // Sets the maximum size for buckets. void set_max_bucket_size(size_t max_bucket_size) { @@ -196,7 +200,7 @@ class GPU_EXPORT CommonDecoder : NON_EXPORTED_BASE(public AsyncAPIInterface) { #undef COMMON_COMMAND_BUFFER_CMD_OP - CommandBufferEngine* engine_; + CommandBufferServiceBase* command_buffer_service_; size_t max_bucket_size_; typedef std::map<uint32_t, std::unique_ptr<Bucket>> BucketMap; diff --git a/chromium/gpu/command_buffer/service/common_decoder_unittest.cc b/chromium/gpu/command_buffer/service/common_decoder_unittest.cc index caaca07aeee..dd7971201f6 100644 --- a/chromium/gpu/command_buffer/service/common_decoder_unittest.cc +++ b/chromium/gpu/command_buffer/service/common_decoder_unittest.cc @@ -7,8 +7,9 @@ #include <memory> -#include "gpu/command_buffer/service/cmd_buffer_engine.h" +#include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/service/common_decoder.h" +#include "gpu/command_buffer/service/mocks.h" #include "testing/gtest/include/gtest/gtest.h" namespace gpu { @@ -55,15 +56,9 @@ TEST(CommonDecoderBucket, SetData) { class TestCommonDecoder : public CommonDecoder { public: - // Overridden from AsyncAPIInterface - const char* GetCommandName(unsigned int command_id) const override { - return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); - } - - // Overridden from AsyncAPIInterface error::Error DoCommand(unsigned int command, unsigned int arg_count, - const volatile void* cmd_data) override { + const volatile void* cmd_data) { return DoCommonCommand(command, arg_count, cmd_data); } @@ -72,115 +67,47 @@ class TestCommonDecoder : public CommonDecoder { } }; -class MockCommandBufferEngine : public CommandBufferEngine { - public: - static const int32_t kStartValidShmId = 1; - static const int32_t kValidShmId = 2; - static const int32_t kInvalidShmId = 3; +class CommonDecoderTest : public testing::Test { + protected: static const size_t kBufferSize = 1024; - static const int32_t kValidOffset = kBufferSize / 2; - static const int32_t kInvalidOffset = kBufferSize; - - MockCommandBufferEngine() - : CommandBufferEngine(), - token_(), - get_offset_(0) { - std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); - shared_memory->CreateAndMapAnonymous(kBufferSize); - buffer_ = MakeBufferFromSharedMemory(std::move(shared_memory), kBufferSize); - } - - // Overridden from CommandBufferEngine. - scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32_t shm_id) override { - if (IsValidSharedMemoryId(shm_id)) - return buffer_; - return NULL; - } - - template <typename T> - T GetSharedMemoryAs(uint32_t offset) { - DCHECK_LT(offset, kBufferSize); - int8_t* buffer_memory = static_cast<int8_t*>(buffer_->memory()); - return reinterpret_cast<T>(&buffer_memory[offset]); - } - - int32_t GetSharedMemoryOffset(const void* memory) { - int8_t* buffer_memory = static_cast<int8_t*>(buffer_->memory()); - ptrdiff_t offset = static_cast<const int8_t*>(memory) - &buffer_memory[0]; - DCHECK_GE(offset, 0); - DCHECK_LT(static_cast<size_t>(offset), kBufferSize); - return static_cast<int32_t>(offset); - } - - // Overridden from CommandBufferEngine. - void set_token(int32_t token) override { token_ = token; } - - int32_t token() const { return token_; } - - // Overridden from CommandBufferEngine. - bool SetGetBuffer(int32_t transfer_buffer_id) override { - NOTREACHED(); - return false; - } + static const uint32_t kInvalidShmId = UINT32_MAX; - // Overridden from CommandBufferEngine. - bool SetGetOffset(int32_t offset) override { - if (static_cast<size_t>(offset) < kBufferSize) { - get_offset_ = offset; - return true; - } - return false; + void SetUp() override { + command_buffer_service_.CreateTransferBufferHelper(kBufferSize, + &valid_shm_id_); + decoder_.set_command_buffer_service(&command_buffer_service_); } - // Overridden from CommandBufferEngine. - int32_t GetGetOffset() override { return get_offset_; } - - private: - bool IsValidSharedMemoryId(int32_t shm_id) { - return shm_id == kValidShmId || shm_id == kStartValidShmId; - } - - scoped_refptr<gpu::Buffer> buffer_; - int32_t token_; - int32_t get_offset_; -}; - -const int32_t MockCommandBufferEngine::kStartValidShmId; -const int32_t MockCommandBufferEngine::kValidShmId; -const int32_t MockCommandBufferEngine::kInvalidShmId; -const size_t MockCommandBufferEngine::kBufferSize; -const int32_t MockCommandBufferEngine::kValidOffset; -const int32_t MockCommandBufferEngine::kInvalidOffset; - -class CommonDecoderTest : public testing::Test { - protected: - void SetUp() override { decoder_.set_engine(&engine_); } - void TearDown() override {} template <typename T> error::Error ExecuteCmd(const T& cmd) { static_assert(T::kArgFlags == cmd::kFixed, "T::kArgFlags should equal cmd::kFixed"); - return decoder_.DoCommands( - 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd)), 0); + return decoder_.DoCommand(cmd.header.command, cmd.header.size - 1, &cmd); } template <typename T> error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) { static_assert(T::kArgFlags == cmd::kAtLeastN, "T::kArgFlags should equal cmd::kAtLeastN"); - return decoder_.DoCommands( - 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd) + data_size), 0); + return decoder_.DoCommand(cmd.header.command, cmd.header.size - 1, &cmd); + } + + template <typename T> + T GetSharedMemoryAs(size_t offset) { + void* memory = + command_buffer_service_.GetTransferBuffer(valid_shm_id_)->memory(); + return reinterpret_cast<T>(static_cast<uint8_t*>(memory) + offset); } - MockCommandBufferEngine engine_; + FakeCommandBufferServiceBase command_buffer_service_; TestCommonDecoder decoder_; + int32_t valid_shm_id_ = 0; }; -TEST_F(CommonDecoderTest, Initialize) { - EXPECT_EQ(0, engine_.GetGetOffset()); -} +const size_t CommonDecoderTest::kBufferSize; +const uint32_t CommonDecoderTest::kInvalidShmId; TEST_F(CommonDecoderTest, DoCommonCommandInvalidCommand) { EXPECT_EQ(error::kUnknownCommand, decoder_.DoCommand(999999, 0, NULL)); @@ -203,10 +130,10 @@ TEST_F(CommonDecoderTest, HandleNoop) { TEST_F(CommonDecoderTest, SetToken) { cmd::SetToken cmd; const int32_t kTokenId = 123; - EXPECT_EQ(0, engine_.token()); + command_buffer_service_.SetToken(0); cmd.Init(kTokenId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(kTokenId, engine_.token()); + EXPECT_EQ(kTokenId, command_buffer_service_.GetState().token); } TEST_F(CommonDecoderTest, SetBucketSize) { @@ -253,10 +180,10 @@ TEST_F(CommonDecoderTest, SetBucketData) { // Check we can set it. const uint32_t kSomeOffsetInSharedMemory = 50; - void* memory = engine_.GetSharedMemoryAs<void*>(kSomeOffsetInSharedMemory); + void* memory = GetSharedMemoryAs<void*>(kSomeOffsetInSharedMemory); memcpy(memory, kData, sizeof(kData)); - cmd.Init(kBucketId, 0, sizeof(kData), - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + cmd.Init(kBucketId, 0, sizeof(kData), valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData))); @@ -264,8 +191,8 @@ TEST_F(CommonDecoderTest, SetBucketData) { static const char kData2[] = "ABCEDFG"; const uint32_t kSomeOffsetInBucket = 5; memcpy(memory, kData2, sizeof(kData2)); - cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2), - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2), valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)), kData2, sizeof(kData2))); @@ -277,18 +204,18 @@ TEST_F(CommonDecoderTest, SetBucketData) { bucket_data[kSomeOffsetInBucket + sizeof(kData2)]); // Check that it fails if the bucket_id is invalid - cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2), - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2), valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // Check that it fails if the offset is out of range. - cmd.Init(kBucketId, bucket->size(), 1, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + cmd.Init(kBucketId, bucket->size(), 1, valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // Check that it fails if the size is out of range. - cmd.Init(kBucketId, 0, bucket->size() + 1, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + cmd.Init(kBucketId, 0, bucket->size() + 1, valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } @@ -344,9 +271,10 @@ TEST_F(CommonDecoderTest, SetBucketDataImmediate) { ExecuteImmediateCmd(cmd, sizeof(kData2))); // Check that it fails if the size is out of range. + size_cmd.Init(kBucketId, sizeof(kData2)); + EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd)); cmd.Init(kBucketId, 0, bucket->size() + 1); - EXPECT_NE(error::kNoError, - ExecuteImmediateCmd(cmd, sizeof(kData2))); + EXPECT_NE(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(kData))); } TEST_F(CommonDecoderTest, GetBucketStart) { @@ -365,33 +293,26 @@ TEST_F(CommonDecoderTest, GetBucketStart) { size_cmd.Init(kBucketId, sizeof(kData)); EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd)); const uint32_t kSomeOffsetInSharedMemory = 50; - uint8_t* start = - engine_.GetSharedMemoryAs<uint8_t*>(kSomeOffsetInSharedMemory); + uint8_t* start = GetSharedMemoryAs<uint8_t*>(kSomeOffsetInSharedMemory); memcpy(start, kData, sizeof(kData)); - set_cmd.Init(kBucketId, 0, sizeof(kData), - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + set_cmd.Init(kBucketId, 0, sizeof(kData), valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_EQ(error::kNoError, ExecuteCmd(set_cmd)); // Check that the size is correct with no data buffer. - uint32_t* memory = - engine_.GetSharedMemoryAs<uint32_t*>(kSomeOffsetInSharedMemory); + uint32_t* memory = GetSharedMemoryAs<uint32_t*>(kSomeOffsetInSharedMemory); *memory = 0x0; - cmd.Init(kBucketId, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, - 0, 0, 0); + cmd.Init(kBucketId, valid_shm_id_, kSomeOffsetInSharedMemory, 0, 0, 0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(kBucketSize, *memory); // Check that the data is copied with data buffer. const uint32_t kDataOffsetInSharedMemory = 54; - uint8_t* data = - engine_.GetSharedMemoryAs<uint8_t*>(kDataOffsetInSharedMemory); + uint8_t* data = GetSharedMemoryAs<uint8_t*>(kDataOffsetInSharedMemory); *memory = 0x0; memset(data, 0, sizeof(kData)); - cmd.Init(kBucketId, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, - kBucketSize, MockCommandBufferEngine::kValidShmId, - kDataOffsetInSharedMemory); + cmd.Init(kBucketId, valid_shm_id_, kSomeOffsetInSharedMemory, kBucketSize, + valid_shm_id_, kDataOffsetInSharedMemory); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(kBucketSize, *memory); EXPECT_EQ(0, memcmp(data, kData, kBucketSize)); @@ -400,54 +321,39 @@ TEST_F(CommonDecoderTest, GetBucketStart) { *memory = 0x0; memset(data, 0, sizeof(kData)); const uint32_t kPieceSize = kBucketSize / 2; - cmd.Init(kBucketId, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, - kPieceSize, MockCommandBufferEngine::kValidShmId, - kDataOffsetInSharedMemory); + cmd.Init(kBucketId, valid_shm_id_, kSomeOffsetInSharedMemory, kPieceSize, + valid_shm_id_, kDataOffsetInSharedMemory); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(kBucketSize, *memory); EXPECT_EQ(0, memcmp(data, kData, kPieceSize)); EXPECT_EQ(0, memcmp(data + kPieceSize, zero, sizeof(kData) - kPieceSize)); // Check that it fails if the result_id is invalid - cmd.Init(kInvalidBucketId, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, - 0, 0, 0); + cmd.Init(kInvalidBucketId, valid_shm_id_, kSomeOffsetInSharedMemory, 0, 0, 0); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // Check that it fails if the data_id is invalid - cmd.Init(kBucketId, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, - 1, MockCommandBufferEngine::kInvalidShmId, 0); + cmd.Init(kBucketId, valid_shm_id_, kSomeOffsetInSharedMemory, 1, + CommonDecoderTest::kInvalidShmId, 0); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // Check that it fails if the data_size is invalid - cmd.Init(kBucketId, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, - 1, 0, 0); + cmd.Init(kBucketId, valid_shm_id_, kSomeOffsetInSharedMemory, 1, 0, 0); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(kBucketId, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, - MockCommandBufferEngine::kBufferSize + 1, - MockCommandBufferEngine::kValidShmId, 0); + cmd.Init(kBucketId, valid_shm_id_, kSomeOffsetInSharedMemory, + CommonDecoderTest::kBufferSize + 1, valid_shm_id_, 0); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // Check that it fails if the data_offset is invalid - cmd.Init(kBucketId, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, - 0, 0, 1); + cmd.Init(kBucketId, valid_shm_id_, kSomeOffsetInSharedMemory, 0, 0, 1); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(kBucketId, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, - MockCommandBufferEngine::kBufferSize, - MockCommandBufferEngine::kValidShmId, 1); + cmd.Init(kBucketId, valid_shm_id_, kSomeOffsetInSharedMemory, + CommonDecoderTest::kBufferSize, valid_shm_id_, 1); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // Check that it fails if the result size is not set to zero *memory = 0x1; - cmd.Init(kBucketId, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, - 0, 0, 0); + cmd.Init(kBucketId, valid_shm_id_, kSomeOffsetInSharedMemory, 0, 0, 0); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } @@ -465,17 +371,16 @@ TEST_F(CommonDecoderTest, GetBucketData) { size_cmd.Init(kBucketId, sizeof(kData)); EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd)); const uint32_t kSomeOffsetInSharedMemory = 50; - uint8_t* memory = - engine_.GetSharedMemoryAs<uint8_t*>(kSomeOffsetInSharedMemory); + uint8_t* memory = GetSharedMemoryAs<uint8_t*>(kSomeOffsetInSharedMemory); memcpy(memory, kData, sizeof(kData)); - set_cmd.Init(kBucketId, 0, sizeof(kData), - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + set_cmd.Init(kBucketId, 0, sizeof(kData), valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_EQ(error::kNoError, ExecuteCmd(set_cmd)); // Check we can get the whole thing. memset(memory, 0, sizeof(kData)); - cmd.Init(kBucketId, 0, sizeof(kData), - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + cmd.Init(kBucketId, 0, sizeof(kData), valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0, memcmp(memory, kData, sizeof(kData))); @@ -485,8 +390,8 @@ TEST_F(CommonDecoderTest, GetBucketData) { const uint8_t kSentinel = 0xff; memset(memory, 0, sizeof(kData)); memory[-1] = kSentinel; - cmd.Init(kBucketId, kSomeOffsetInBucket, kLengthOfPiece, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + cmd.Init(kBucketId, kSomeOffsetInBucket, kLengthOfPiece, valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0, memcmp(memory, kData + kSomeOffsetInBucket, kLengthOfPiece)); EXPECT_EQ(0, memcmp(memory + kLengthOfPiece, zero, @@ -494,18 +399,18 @@ TEST_F(CommonDecoderTest, GetBucketData) { EXPECT_EQ(kSentinel, memory[-1]); // Check that it fails if the bucket_id is invalid - cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData), - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData), valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // Check that it fails if the offset is invalid - cmd.Init(kBucketId, sizeof(kData) + 1, 1, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + cmd.Init(kBucketId, sizeof(kData) + 1, 1, valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); // Check that it fails if the size is invalid - cmd.Init(kBucketId, 0, sizeof(kData) + 1, - MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); + cmd.Init(kBucketId, 0, sizeof(kData) + 1, valid_shm_id_, + kSomeOffsetInSharedMemory); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } diff --git a/chromium/gpu/command_buffer/service/context_group.cc b/chromium/gpu/command_buffer/service/context_group.cc index de793240f9b..df450df2cc3 100644 --- a/chromium/gpu/command_buffer/service/context_group.cc +++ b/chromium/gpu/command_buffer/service/context_group.cc @@ -11,6 +11,7 @@ #include <string> #include "base/command_line.h" +#include "base/memory/ptr_util.h" #include "gpu/command_buffer/service/buffer_manager.h" #include "gpu/command_buffer/service/framebuffer_manager.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h" @@ -21,6 +22,7 @@ #include "gpu/command_buffer/service/progress_reporter.h" #include "gpu/command_buffer/service/renderbuffer_manager.h" #include "gpu/command_buffer/service/sampler_manager.h" +#include "gpu/command_buffer/service/service_discardable_manager.h" #include "gpu/command_buffer/service/shader_manager.h" #include "gpu/command_buffer/service/texture_manager.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" @@ -69,7 +71,8 @@ ContextGroup::ContextGroup( bool bind_generates_resource, gpu::ImageFactory* image_factory, ProgressReporter* progress_reporter, - const GpuFeatureInfo& gpu_feature_info) + const GpuFeatureInfo& gpu_feature_info, + ServiceDiscardableManager* discardable_manager) : gpu_preferences_(gpu_preferences), mailbox_manager_(mailbox_manager), memory_tracker_(memory_tracker), @@ -109,13 +112,14 @@ ContextGroup::ContextGroup( image_factory_(image_factory), passthrough_resources_(new PassthroughResources), progress_reporter_(progress_reporter), - gpu_feature_info_(gpu_feature_info) { - { - DCHECK(feature_info_); - if (!mailbox_manager_.get()) - mailbox_manager_ = new MailboxManagerImpl; - transfer_buffer_manager_ = new TransferBufferManager(memory_tracker_.get()); - } + gpu_feature_info_(gpu_feature_info), + discardable_manager_(discardable_manager) { + DCHECK(discardable_manager); + DCHECK(feature_info_); + if (!mailbox_manager_.get()) + mailbox_manager_ = new MailboxManagerImpl; + transfer_buffer_manager_ = + base::MakeUnique<TransferBufferManager>(memory_tracker_.get()); } bool ContextGroup::Initialize(GLES2Decoder* decoder, @@ -135,7 +139,7 @@ bool ContextGroup::Initialize(GLES2Decoder* decoder, return false; } // If we've already initialized the group just add the context. - decoders_.push_back(base::AsWeakPtr<GLES2Decoder>(decoder)); + decoders_.push_back(decoder->AsWeakPtr()); return true; } @@ -148,8 +152,6 @@ bool ContextGroup::Initialize(GLES2Decoder* decoder, return false; } - transfer_buffer_manager_->Initialize(); - const GLint kMinRenderbufferSize = 512; // GL says 1 pixel! GLint max_renderbuffer_size = 0; if (!QueryGLFeature( @@ -219,9 +221,6 @@ bool ContextGroup::Initialize(GLES2Decoder* decoder, buffer_manager_.reset( new BufferManager(memory_tracker_.get(), feature_info_.get())); - framebuffer_manager_.reset( - new FramebufferManager(max_draw_buffers_, max_color_attachments_, - framebuffer_completeness_cache_)); renderbuffer_manager_.reset(new RenderbufferManager( memory_tracker_.get(), max_renderbuffer_size, max_samples, feature_info_.get())); @@ -316,8 +315,7 @@ bool ContextGroup::Initialize(GLES2Decoder* decoder, memory_tracker_.get(), feature_info_.get(), max_texture_size, max_cube_map_texture_size, max_rectangle_texture_size, max_3d_texture_size, max_array_texture_layers, bind_generates_resource_, - progress_reporter_)); - texture_manager_->set_framebuffer_manager(framebuffer_manager_.get()); + progress_reporter_, discardable_manager_)); const GLint kMinTextureImageUnits = 8; const GLint kMinVertexTextureImageUnits = 0; @@ -456,7 +454,7 @@ bool ContextGroup::Initialize(GLES2Decoder* decoder, return false; } - decoders_.push_back(base::AsWeakPtr<GLES2Decoder>(decoder)); + decoders_.push_back(decoder->AsWeakPtr()); return true; } @@ -510,14 +508,6 @@ void ContextGroup::Destroy(GLES2Decoder* decoder, bool have_context) { ReportProgress(); } - if (framebuffer_manager_ != NULL) { - framebuffer_manager_->Destroy(have_context); - if (texture_manager_) - texture_manager_->set_framebuffer_manager(NULL); - framebuffer_manager_.reset(); - ReportProgress(); - } - if (renderbuffer_manager_ != NULL) { renderbuffer_manager_->Destroy(have_context); renderbuffer_manager_.reset(); diff --git a/chromium/gpu/command_buffer/service/context_group.h b/chromium/gpu/command_buffer/service/context_group.h index c2ebbfb2900..bc223031d94 100644 --- a/chromium/gpu/command_buffer/service/context_group.h +++ b/chromium/gpu/command_buffer/service/context_group.h @@ -29,13 +29,13 @@ namespace gpu { class ImageFactory; struct GpuPreferences; class TransferBufferManager; +class ServiceDiscardableManager; namespace gles2 { class ProgramCache; class BufferManager; class GLES2Decoder; -class FramebufferManager; class MailboxManager; class RenderbufferManager; class PathManager; @@ -67,7 +67,8 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { bool bind_generates_resource, gpu::ImageFactory* image_factory, ProgressReporter* progress_reporter, - const GpuFeatureInfo& gpu_feature_info); + const GpuFeatureInfo& gpu_feature_info, + ServiceDiscardableManager* discardable_manager); // This should only be called by GLES2Decoder. This must be paired with a // call to destroy if it succeeds. @@ -166,10 +167,6 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { return buffer_manager_.get(); } - FramebufferManager* framebuffer_manager() const { - return framebuffer_manager_.get(); - } - RenderbufferManager* renderbuffer_manager() const { return renderbuffer_manager_.get(); } @@ -204,6 +201,10 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { return sampler_manager_.get(); } + ServiceDiscardableManager* discardable_manager() const { + return discardable_manager_; + } + uint32_t GetMemRepresented() const; // Loses all the context associated with this group. @@ -251,7 +252,7 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { scoped_refptr<MemoryTracker> memory_tracker_; scoped_refptr<ShaderTranslatorCache> shader_translator_cache_; scoped_refptr<FramebufferCompletenessCache> framebuffer_completeness_cache_; - scoped_refptr<TransferBufferManager> transfer_buffer_manager_; + std::unique_ptr<TransferBufferManager> transfer_buffer_manager_; bool enforce_gl_minimums_; bool bind_generates_resource_; @@ -280,8 +281,6 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { std::unique_ptr<BufferManager> buffer_manager_; - std::unique_ptr<FramebufferManager> framebuffer_manager_; - std::unique_ptr<RenderbufferManager> renderbuffer_manager_; std::unique_ptr<TextureManager> texture_manager_; @@ -312,6 +311,8 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { GpuFeatureInfo gpu_feature_info_; + ServiceDiscardableManager* discardable_manager_; + DISALLOW_COPY_AND_ASSIGN(ContextGroup); }; diff --git a/chromium/gpu/command_buffer/service/context_group_unittest.cc b/chromium/gpu/command_buffer/service/context_group_unittest.cc index 2bdcdfa3881..1cb3a3ceae4 100644 --- a/chromium/gpu/command_buffer/service/context_group_unittest.cc +++ b/chromium/gpu/command_buffer/service/context_group_unittest.cc @@ -11,6 +11,7 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/gpu_service_test.h" #include "gpu/command_buffer/service/mailbox_manager.h" +#include "gpu/command_buffer/service/service_discardable_manager.h" #include "gpu/command_buffer/service/test_helper.h" #include "gpu/command_buffer/service/texture_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,7 +26,7 @@ using ::testing::Not; using ::testing::Pointee; using ::testing::Return; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::StrEq; namespace gpu { @@ -42,12 +43,14 @@ class ContextGroupTest : public GpuServiceTest { GpuServiceTest::SetUp(); decoder_.reset(new MockGLES2Decoder()); scoped_refptr<FeatureInfo> feature_info = new FeatureInfo; - group_ = scoped_refptr<ContextGroup>(new ContextGroup( - gpu_preferences_, NULL, NULL, NULL, NULL, feature_info, - kBindGeneratesResource, nullptr, nullptr, GpuFeatureInfo())); + group_ = scoped_refptr<ContextGroup>( + new ContextGroup(gpu_preferences_, NULL, NULL, NULL, NULL, feature_info, + kBindGeneratesResource, nullptr, nullptr, + GpuFeatureInfo(), &discardable_manager_)); } GpuPreferences gpu_preferences_; + ServiceDiscardableManager discardable_manager_; std::unique_ptr<MockGLES2Decoder> decoder_; scoped_refptr<ContextGroup> group_; }; @@ -62,7 +65,6 @@ TEST_F(ContextGroupTest, Basic) { EXPECT_EQ(0u, group_->max_varying_vectors()); EXPECT_EQ(0u, group_->max_vertex_uniform_vectors()); EXPECT_TRUE(group_->buffer_manager() == NULL); - EXPECT_TRUE(group_->framebuffer_manager() == NULL); EXPECT_TRUE(group_->renderbuffer_manager() == NULL); EXPECT_TRUE(group_->texture_manager() == NULL); EXPECT_TRUE(group_->program_manager() == NULL); @@ -90,7 +92,6 @@ TEST_F(ContextGroupTest, InitializeNoExtensions) { EXPECT_EQ(static_cast<uint32_t>(TestHelper::kMaxVertexUniformVectors), group_->max_vertex_uniform_vectors()); EXPECT_TRUE(group_->buffer_manager() != NULL); - EXPECT_TRUE(group_->framebuffer_manager() != NULL); EXPECT_TRUE(group_->renderbuffer_manager() != NULL); EXPECT_TRUE(group_->texture_manager() != NULL); EXPECT_TRUE(group_->program_manager() != NULL); @@ -98,7 +99,6 @@ TEST_F(ContextGroupTest, InitializeNoExtensions) { group_->Destroy(decoder_.get(), false); EXPECT_TRUE(group_->buffer_manager() == NULL); - EXPECT_TRUE(group_->framebuffer_manager() == NULL); EXPECT_TRUE(group_->renderbuffer_manager() == NULL); EXPECT_TRUE(group_->texture_manager() == NULL); EXPECT_TRUE(group_->program_manager() == NULL); @@ -122,7 +122,6 @@ TEST_F(ContextGroupTest, MultipleContexts) { DisallowedFeatures())); EXPECT_TRUE(group_->buffer_manager() != NULL); - EXPECT_TRUE(group_->framebuffer_manager() != NULL); EXPECT_TRUE(group_->renderbuffer_manager() != NULL); EXPECT_TRUE(group_->texture_manager() != NULL); EXPECT_TRUE(group_->program_manager() != NULL); @@ -131,7 +130,6 @@ TEST_F(ContextGroupTest, MultipleContexts) { group_->Destroy(decoder_.get(), false); EXPECT_TRUE(group_->buffer_manager() != NULL); - EXPECT_TRUE(group_->framebuffer_manager() != NULL); EXPECT_TRUE(group_->renderbuffer_manager() != NULL); EXPECT_TRUE(group_->texture_manager() != NULL); EXPECT_TRUE(group_->program_manager() != NULL); @@ -140,7 +138,6 @@ TEST_F(ContextGroupTest, MultipleContexts) { group_->Destroy(decoder2_.get(), false); EXPECT_TRUE(group_->buffer_manager() == NULL); - EXPECT_TRUE(group_->framebuffer_manager() == NULL); EXPECT_TRUE(group_->renderbuffer_manager() == NULL); EXPECT_TRUE(group_->texture_manager() == NULL); EXPECT_TRUE(group_->program_manager() == NULL); diff --git a/chromium/gpu/command_buffer/service/context_state.cc b/chromium/gpu/command_buffer/service/context_state.cc index 5aa24fbacd0..3c71d38b25e 100644 --- a/chromium/gpu/command_buffer/service/context_state.cc +++ b/chromium/gpu/command_buffer/service/context_state.cc @@ -281,6 +281,23 @@ void ContextState::RestoreTextureUnitBindings( } } +void ContextState::RestoreSamplerBinding(GLuint unit, + const ContextState* prev_state) const { + if (!feature_info_->IsES3Capable()) + return; + const scoped_refptr<Sampler>& cur_sampler = sampler_units[unit]; + GLuint cur_id = cur_sampler ? cur_sampler->service_id() : 0; + GLuint prev_id = 0; + if (prev_state) { + const scoped_refptr<Sampler>& prev_sampler = + prev_state->sampler_units[unit]; + prev_id = prev_sampler ? prev_sampler->service_id() : 0; + } + if (!prev_state || cur_id != prev_id) { + glBindSampler(unit, cur_id); + } +} + void ContextState::PushTextureDecompressionUnpackState() const { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); @@ -369,11 +386,12 @@ void ContextState::RestoreActiveTexture() const { glActiveTexture(GL_TEXTURE0 + active_texture_unit); } -void ContextState::RestoreAllTextureUnitBindings( +void ContextState::RestoreAllTextureUnitAndSamplerBindings( const ContextState* prev_state) const { // Restore Texture state. for (size_t ii = 0; ii < texture_units.size(); ++ii) { RestoreTextureUnitBindings(ii, prev_state); + RestoreSamplerBinding(ii, prev_state); } RestoreActiveTexture(); } @@ -496,12 +514,16 @@ void ContextState::RestoreGlobalState(const ContextState* prev_state) const { } void ContextState::RestoreState(const ContextState* prev_state) { - RestoreAllTextureUnitBindings(prev_state); + RestoreAllTextureUnitAndSamplerBindings(prev_state); RestoreVertexAttribs(); + // RestoreIndexedUniformBufferBindings must be called before + // RestoreBufferBindings. This is because setting the indexed uniform buffer + // bindings via glBindBuffer{Base,Range} also sets the general uniform buffer + // bindings (glBindBuffer), but not vice versa. + RestoreIndexedUniformBufferBindings(prev_state); RestoreBufferBindings(); RestoreRenderbufferBindings(); RestoreProgramSettings(prev_state, true); - RestoreIndexedUniformBufferBindings(prev_state); RestoreGlobalState(prev_state); // FRAMEBUFFER_SRGB will be restored lazily at render time. diff --git a/chromium/gpu/command_buffer/service/context_state.h b/chromium/gpu/command_buffer/service/context_state.h index 056dd4f6ce9..676f1b8843a 100644 --- a/chromium/gpu/command_buffer/service/context_state.h +++ b/chromium/gpu/command_buffer/service/context_state.h @@ -211,7 +211,8 @@ struct GPU_EXPORT ContextState { void InitState(const ContextState* prev_state) const; void RestoreActiveTexture() const; - void RestoreAllTextureUnitBindings(const ContextState* prev_state) const; + void RestoreAllTextureUnitAndSamplerBindings( + const ContextState* prev_state) const; void RestoreActiveTextureUnitBinding(unsigned int target) const; void RestoreVertexAttribValues() const; void RestoreVertexAttribArrays( @@ -225,6 +226,7 @@ struct GPU_EXPORT ContextState { void RestoreIndexedUniformBufferBindings(const ContextState* prev_state); void RestoreTextureUnitBindings( GLuint unit, const ContextState* prev_state) const; + void RestoreSamplerBinding(GLuint unit, const ContextState* prev_state) const; void PushTextureDecompressionUnpackState() const; void RestoreUnpackState() const; diff --git a/chromium/gpu/command_buffer/service/feature_info.cc b/chromium/gpu/command_buffer/service/feature_info.cc index 32e72c69f32..29ee8e9853a 100644 --- a/chromium/gpu/command_buffer/service/feature_info.cc +++ b/chromium/gpu/command_buffer/service/feature_info.cc @@ -1293,6 +1293,19 @@ void FeatureInfo::InitializeFeatures() { } UMA_HISTOGRAM_BOOLEAN("GPU.TextureRG", feature_flags_.ext_texture_rg); + if (gl_version_info_->is_desktop_core_profile || + extensions.Contains("GL_EXT_texture_norm16")) { + feature_flags_.ext_texture_norm16 = true; + AddExtensionString("GL_EXT_texture_norm16"); + + // Note: EXT_texture_norm16 is not exposed through WebGL API so we validate + // only the combinations used internally. + validators_.texture_format.AddValue(GL_RED_EXT); + validators_.texture_internal_format.AddValue(GL_R16_EXT); + validators_.texture_internal_format.AddValue(GL_RED_EXT); + validators_.texture_unsized_internal_format.AddValue(GL_RED_EXT); + } + bool has_opengl_dual_source_blending = gl_version_info_->IsAtLeastGL(3, 3) || (gl_version_info_->IsAtLeastGL(3, 2) && @@ -1401,7 +1414,7 @@ void FeatureInfo::InitializeFloatAndHalfFloatFeatures( enable_texture_float_linear = true; } - if (enable_ext_color_buffer_float || gl_version_info_->is_angle) { + if (enable_ext_color_buffer_float) { may_enable_chromium_color_buffer_float = true; } } @@ -1438,7 +1451,25 @@ void FeatureInfo::InitializeFloatAndHalfFloatFeatures( } } - if (may_enable_chromium_color_buffer_float) { + bool had_native_chromium_color_buffer_float_ext = false; + if (extensions.Contains("GL_CHROMIUM_color_buffer_float_rgb")) { + had_native_chromium_color_buffer_float_ext = true; + feature_flags_.chromium_color_buffer_float_rgb = true; + if (!disallowed_features_.chromium_color_buffer_float_rgb) { + EnableCHROMIUMColorBufferFloatRGB(); + } + } + + if (extensions.Contains("GL_CHROMIUM_color_buffer_float_rgba")) { + had_native_chromium_color_buffer_float_ext = true; + feature_flags_.chromium_color_buffer_float_rgba = true; + if (!disallowed_features_.chromium_color_buffer_float_rgba) { + EnableCHROMIUMColorBufferFloatRGBA(); + } + } + + if (may_enable_chromium_color_buffer_float && + !had_native_chromium_color_buffer_float_ext) { static_assert(GL_RGBA32F_ARB == GL_RGBA32F && GL_RGBA32F_EXT == GL_RGBA32F && GL_RGB32F_ARB == GL_RGB32F && GL_RGB32F_EXT == GL_RGB32F, @@ -1493,8 +1524,10 @@ void FeatureInfo::InitializeFloatAndHalfFloatFeatures( } enable_ext_color_buffer_float = full_float_support; } - // Likewise for EXT_color_buffer_half_float on ES2 contexts. - if (IsWebGL1OrES2Context() && !enable_ext_color_buffer_half_float) { + // Likewise for EXT_color_buffer_half_float on ES2 contexts. On desktop, + // require at least GL 3.0, to ensure that all formats are defined. + if (IsWebGL1OrES2Context() && !enable_ext_color_buffer_half_float && + (gl_version_info_->is_es || gl_version_info_->IsAtLeastGL(3, 0))) { bool full_half_float_support = true; GLenum internal_formats[] = { GL_R16F, GL_RG16F, GL_RGBA16F, diff --git a/chromium/gpu/command_buffer/service/feature_info.h b/chromium/gpu/command_buffer/service/feature_info.h index 36e9f38585e..05be04fa875 100644 --- a/chromium/gpu/command_buffer/service/feature_info.h +++ b/chromium/gpu/command_buffer/service/feature_info.h @@ -86,6 +86,7 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { bool blend_equation_advanced = false; bool blend_equation_advanced_coherent = false; bool ext_texture_rg = false; + bool ext_texture_norm16 = false; bool chromium_image_ycbcr_420v = false; bool chromium_image_ycbcr_422 = false; bool emulate_primitive_restart_fixed_index = false; diff --git a/chromium/gpu/command_buffer/service/feature_info_unittest.cc b/chromium/gpu/command_buffer/service/feature_info_unittest.cc index e454bcc0bbf..d98963182d0 100644 --- a/chromium/gpu/command_buffer/service/feature_info_unittest.cc +++ b/chromium/gpu/command_buffer/service/feature_info_unittest.cc @@ -31,7 +31,7 @@ using ::testing::Not; using ::testing::Pointee; using ::testing::Return; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::StrEq; namespace gpu { @@ -1664,6 +1664,15 @@ TEST_P(FeatureInfoTest, InitializeARB_texture_rgNoFloat) { EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid(GL_RG8_EXT)); } +TEST_P(FeatureInfoTest, InitializeEXT_texture_norm16) { + SetupInitExpectations("GL_EXT_texture_norm16"); + EXPECT_TRUE(info_->feature_flags().ext_texture_norm16); + + EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_RED_EXT)); + EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(GL_R16_EXT)); + EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(GL_RED_EXT)); +} + TEST_P(FeatureInfoTest, InitializeCHROMIUM_ycbcr_422_imageTrue) { SetupInitExpectations("GL_APPLE_ycbcr_422"); EXPECT_TRUE(info_->feature_flags().chromium_image_ycbcr_422); diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager.cc b/chromium/gpu/command_buffer/service/framebuffer_manager.cc index 55ed2e1a1f8..637c6b70e53 100644 --- a/chromium/gpu/command_buffer/service/framebuffer_manager.cc +++ b/chromium/gpu/command_buffer/service/framebuffer_manager.cc @@ -243,6 +243,9 @@ class TextureAttachment } bool IsLayerValid() const override { + if (!Is3D()) { + return true; + } Texture* texture = texture_ref_->texture(); DCHECK(texture); GLsizei width, height, depth; diff --git a/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc index 162af344abc..513a2194c64 100644 --- a/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/framebuffer_manager_unittest.cc @@ -11,6 +11,7 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/gpu_service_test.h" #include "gpu/command_buffer/service/renderbuffer_manager.h" +#include "gpu/command_buffer/service/service_discardable_manager.h" #include "gpu/command_buffer/service/test_helper.h" #include "gpu/command_buffer/service/texture_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -44,7 +45,7 @@ class FramebufferManagerTest : public GpuServiceTest { texture_manager_.reset(new TextureManager( nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubemapSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr)); + kUseDefaultTextures, nullptr, &discardable_manager_)); renderbuffer_manager_.reset(new RenderbufferManager(nullptr, kMaxRenderbufferSize, kMaxSamples, @@ -59,6 +60,7 @@ class FramebufferManagerTest : public GpuServiceTest { protected: FramebufferManager manager_; scoped_refptr<FeatureInfo> feature_info_; + ServiceDiscardableManager discardable_manager_; std::unique_ptr<TextureManager> texture_manager_; std::unique_ptr<RenderbufferManager> renderbuffer_manager_; }; @@ -121,7 +123,7 @@ class FramebufferInfoTestBase : public GpuServiceTest { texture_manager_.reset(new TextureManager( nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubemapSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr)); + kUseDefaultTextures, nullptr, &discardable_manager_)); renderbuffer_manager_.reset(new RenderbufferManager(nullptr, kMaxRenderbufferSize, kMaxSamples, @@ -158,6 +160,7 @@ class FramebufferInfoTestBase : public GpuServiceTest { FramebufferManager manager_; Framebuffer* framebuffer_; scoped_refptr<FeatureInfo> feature_info_; + ServiceDiscardableManager discardable_manager_; std::unique_ptr<TextureManager> texture_manager_; std::unique_ptr<RenderbufferManager> renderbuffer_manager_; std::unique_ptr<MockErrorState> error_state_; @@ -1646,7 +1649,43 @@ TEST_F(FramebufferInfoES3Test, ReadBuffer) { EXPECT_TRUE(framebuffer_->GetReadBufferAttachment()); } -} // namespace gles2 -} // namespace gpu +TEST_F(FramebufferInfoES3Test, AttachNonLevel0Texture) { + const GLuint kTextureClientId = 33; + const GLuint kTextureServiceId = 333; + const GLint kBorder = 0; + const GLenum kType = GL_UNSIGNED_BYTE; + const GLsizei kWidth = 16; + const GLsizei kHeight = 32; + const GLint kLevel = 2; + const GLenum kInternalFormat = GL_RGBA8; + const GLenum kFormat = GL_RGBA; + const GLenum kTarget = GL_TEXTURE_2D; + const GLsizei kSamples = 0; + + texture_manager_->CreateTexture(kTextureClientId, kTextureServiceId); + scoped_refptr<TextureRef> texture( + texture_manager_->GetTexture(kTextureClientId)); + ASSERT_TRUE(texture.get()); + + texture_manager_->SetTarget(texture.get(), kTarget); + texture_manager_->SetLevelInfo(texture.get(), kTarget, kLevel, + kInternalFormat, kWidth, kHeight, 0, kBorder, + kFormat, kType, gfx::Rect()); + framebuffer_->AttachTexture(GL_COLOR_ATTACHMENT0, texture.get(), kTarget, + kLevel, kSamples); + EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), + framebuffer_->IsPossiblyComplete(feature_info_.get())); + EXPECT_CALL(*gl_, TexParameteri(kTarget, GL_TEXTURE_BASE_LEVEL, kLevel)) + .Times(1) + .RetiresOnSaturation(); + texture_manager_->SetParameteri("FramebufferInfoTest.AttachNonLevel0Texturer", + error_state_.get(), texture.get(), + GL_TEXTURE_BASE_LEVEL, kLevel); + EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), + framebuffer_->IsPossiblyComplete(feature_info_.get())); +} + +} // namespace gles2 +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gl_state_restorer_impl.cc b/chromium/gpu/command_buffer/service/gl_state_restorer_impl.cc index fe761453af6..f6509031c4e 100644 --- a/chromium/gpu/command_buffer/service/gl_state_restorer_impl.cc +++ b/chromium/gpu/command_buffer/service/gl_state_restorer_impl.cc @@ -31,9 +31,9 @@ void GLStateRestorerImpl::RestoreState(const gl::GLStateRestorer* prev_state) { restorer_impl ? restorer_impl->GetContextState() : NULL); } -void GLStateRestorerImpl::RestoreAllTextureUnitBindings() { +void GLStateRestorerImpl::RestoreAllTextureUnitAndSamplerBindings() { DCHECK(decoder_.get()); - decoder_->RestoreAllTextureUnitBindings(NULL); + decoder_->RestoreAllTextureUnitAndSamplerBindings(NULL); } void GLStateRestorerImpl::RestoreActiveTexture() { diff --git a/chromium/gpu/command_buffer/service/gl_state_restorer_impl.h b/chromium/gpu/command_buffer/service/gl_state_restorer_impl.h index 0827aa5032a..e1a786f5aea 100644 --- a/chromium/gpu/command_buffer/service/gl_state_restorer_impl.h +++ b/chromium/gpu/command_buffer/service/gl_state_restorer_impl.h @@ -27,7 +27,7 @@ class GPU_EXPORT GLStateRestorerImpl : public gl::GLStateRestorer { bool IsInitialized() override; void RestoreState(const gl::GLStateRestorer* prev_state) override; - void RestoreAllTextureUnitBindings() override; + void RestoreAllTextureUnitAndSamplerBindings() override; void RestoreActiveTexture() override; void RestoreActiveTextureUnitBinding(unsigned int target) override; void RestoreAllExternalTextureBindingsIfNeeded() override; diff --git a/chromium/gpu/command_buffer/service/gl_utils.cc b/chromium/gpu/command_buffer/service/gl_utils.cc index cef929f0b6d..231fda460b6 100644 --- a/chromium/gpu/command_buffer/service/gl_utils.cc +++ b/chromium/gpu/command_buffer/service/gl_utils.cc @@ -4,6 +4,8 @@ #include "gpu/command_buffer/service/gl_utils.h" +#include <unordered_set> + #include "base/metrics/histogram.h" #include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/service/feature_info.h" diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc index c9e6bdbc538..08642bebe4a 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc @@ -74,6 +74,7 @@ enum { D_FORMAT_RGBA16F, D_FORMAT_RGBA32F, D_FORMAT_R11F_G11F_B10F, + D_FORMAT_RGB10_A2, NUM_D_FORMAT }; @@ -143,6 +144,7 @@ ShaderId GetFragmentShaderId(bool premultiply_alpha, sourceFormatIndex = S_FORMAT_LUMINANCE_ALPHA; break; case GL_RED: + case GL_R16_EXT: sourceFormatIndex = S_FORMAT_RED; break; case GL_RGB: @@ -269,6 +271,9 @@ ShaderId GetFragmentShaderId(bool premultiply_alpha, case GL_R11F_G11F_B10F: destFormatIndex = D_FORMAT_R11F_G11F_B10F; break; + case GL_RGB10_A2: + destFormatIndex = D_FORMAT_RGB10_A2; + break; default: NOTREACHED(); break; @@ -361,42 +366,22 @@ std::string GetFragmentShaderSource(const gl::GLVersionInfo& gl_version_info, // Preamble for texture precision. source += kShaderPrecisionPreamble; - if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(dest_format)) { - source += "#define TextureType ivec4\n"; - source += "#define ZERO 0\n"; - source += "#define MAX_COLOR 255\n"; - if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) - source += "#define InnerScaleValue 1\n"; - else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) - source += "#define InnerScaleValue 1u\n"; - else - source += "#define InnerScaleValue 255.0\n"; - source += "#define OuterScaleValue 1\n"; - } else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(dest_format)) { + // According to the spec, |dest_format| can be unsigend interger format, float + // format or unsigned normalized fixed-point format. |source_format| can only + // be unsigned normalized fixed-point format. + if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(dest_format)) { source += "#define TextureType uvec4\n"; source += "#define ZERO 0u\n"; source += "#define MAX_COLOR 255u\n"; - if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) - source += "#define InnerScaleValue 1\n"; - else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) - source += "#define InnerScaleValue 1u\n"; - else - source += "#define InnerScaleValue 255.0\n"; + source += "#define InnerScaleValue 255.0\n"; source += "#define OuterScaleValue 1u\n"; } else { + DCHECK(!gpu::gles2::GLES2Util::IsIntegerFormat(dest_format)); source += "#define TextureType vec4\n"; source += "#define ZERO 0.0\n"; source += "#define MAX_COLOR 1.0\n"; - if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) { - source += "#define InnerScaleValue 1\n"; - source += "#define OuterScaleValue (1.0 / 255.0)\n"; - } else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) { - source += "#define InnerScaleValue 1u\n"; - source += "#define OuterScaleValue (1.0 / 255.0)\n"; - } else { - source += "#define InnerScaleValue 1.0\n"; - source += "#define OuterScaleValue 1.0\n"; - } + source += "#define InnerScaleValue 1.0\n"; + source += "#define OuterScaleValue 1.0\n"; } if (gl_version_info.is_es2 || gl_version_info.IsLowerThanGL(3, 2) || target == GL_TEXTURE_EXTERNAL_OES) { diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc index 0d0dbe6ca73..7c982457667 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -33,6 +33,7 @@ #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/sync_token.h" #include "gpu/command_buffer/service/buffer_manager.h" +#include "gpu/command_buffer/service/command_buffer_service.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/error_state.h" @@ -60,6 +61,7 @@ #include "gpu/command_buffer/service/query_manager.h" #include "gpu/command_buffer/service/renderbuffer_manager.h" #include "gpu/command_buffer/service/sampler_manager.h" +#include "gpu/command_buffer/service/service_discardable_manager.h" #include "gpu/command_buffer/service/shader_manager.h" #include "gpu/command_buffer/service/shader_translator.h" #include "gpu/command_buffer/service/texture_manager.h" @@ -490,10 +492,8 @@ void GLES2Decoder::BeginDecoding() {} void GLES2Decoder::EndDecoding() {} -error::Error GLES2Decoder::DoCommand(unsigned int command, - unsigned int arg_count, - const volatile void* cmd_data) { - return DoCommands(1, cmd_data, arg_count + 1, 0); +base::StringPiece GLES2Decoder::GetLogPrefix() { + return GetLogger()->GetLogPrefix(); } // This class implements GLES2Decoder so we don't have to expose all the GLES2 @@ -514,10 +514,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { int num_entries, int* entries_processed); - // Overridden from AsyncAPIInterface. - const char* GetCommandName(unsigned int command_id) const override; - // Overridden from GLES2Decoder. + base::WeakPtr<GLES2Decoder> AsWeakPtr() override; bool Initialize(const scoped_refptr<gl::GLSurface>& surface, const scoped_refptr<gl::GLContext>& context, bool offscreen, @@ -540,9 +538,9 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { void RestoreState(const ContextState* prev_state) override; void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); } - void RestoreAllTextureUnitBindings( + void RestoreAllTextureUnitAndSamplerBindings( const ContextState* prev_state) const override { - state_.RestoreAllTextureUnitBindings(prev_state); + state_.RestoreAllTextureUnitAndSamplerBindings(prev_state); } void RestoreActiveTextureUnitBinding(unsigned int target) const override { state_.RestoreActiveTextureUnitBinding(target); @@ -569,6 +567,9 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { void RestoreAllAttributes() const override; QueryManager* GetQueryManager() override { return query_manager_.get(); } + FramebufferManager* GetFramebufferManager() override { + return framebuffer_manager_.get(); + } TransformFeedbackManager* GetTransformFeedbackManager() override { return transform_feedback_manager_.get(); } @@ -615,11 +616,6 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { bool GetServiceTextureId(uint32_t client_texture_id, uint32_t* service_texture_id) override; - uint32_t GetTextureUploadCount() override; - base::TimeDelta GetTotalTextureUploadTime() override; - base::TimeDelta GetTotalProcessingCommandsTime() override; - void AddProcessingCommandsTime(base::TimeDelta) override; - // Restores the current state to the user's settings. void RestoreCurrentFramebufferBindings(); @@ -633,8 +629,6 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { bool BoundFramebufferHasDepthAttachment(); bool BoundFramebufferHasStencilAttachment(); - error::ContextLostReason GetContextLostReason() override; - // Overriden from ErrorStateClient. void OnContextLostError() override; void OnOutOfMemoryError() override; @@ -682,6 +676,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { kBindBufferRange }; + const char* GetCommandName(unsigned int command_id) const; + // Initialize or re-initialize the shader translator. bool InitializeShaderTranslator(); @@ -728,7 +724,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { } FramebufferManager* framebuffer_manager() { - return group_->framebuffer_manager(); + return framebuffer_manager_.get(); } ProgramManager* program_manager() { @@ -1041,6 +1037,14 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { void DoBindTexImage2DCHROMIUM( GLenum target, GLint image_id); + void DoBindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint image_id); + // Common implementation of DoBindTexImage2DCHROMIUM entry points. + void BindTexImage2DCHROMIUMImpl(const char* function_name, + GLenum target, + GLenum internalformat, + GLint image_id); void DoReleaseTexImage2DCHROMIUM( GLenum target, GLint image_id); @@ -2210,6 +2214,10 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { bool InitializeCopyTexImageBlitter(const char* function_name); bool InitializeCopyTextureCHROMIUM(const char* function_name); bool InitializeSRGBConverter(const char* function_name); + + void UnbindTexture(TextureRef* texture_ref, + bool supports_separate_framebuffer_binds); + // Generate a member function prototype for each command in an automated and // typesafe way. #define GLES2_CMD_OP(name) \ @@ -2319,6 +2327,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { // Whether the client requested an offscreen buffer with an alpha channel. bool offscreen_buffer_should_have_alpha_; + std::unique_ptr<FramebufferManager> framebuffer_manager_; + std::unique_ptr<QueryManager> query_manager_; std::unique_ptr<VertexArrayManager> vertex_array_manager_; @@ -2369,7 +2379,6 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { int commands_to_process_; bool has_robustness_extension_; - error::ContextLostReason context_lost_reason_; bool context_was_lost_; bool reset_by_robustness_extension_; bool supports_post_sub_buffer_; @@ -2415,9 +2424,6 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { // Cached value for the number of stencil bits for the default framebuffer. GLint num_stencil_bits_; - // Command buffer stats. - base::TimeDelta total_processing_commands_time_; - // States related to each manager. DecoderTextureState texture_state_; DecoderFramebufferState framebuffer_state_; @@ -2488,6 +2494,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { std::unique_ptr<DCLayerSharedState> dc_layer_shared_state_; + base::WeakPtrFactory<GLES2DecoderImpl> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); }; @@ -3079,7 +3087,6 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) feature_info_(group_->feature_info()), frame_number_(0), has_robustness_extension_(false), - context_lost_reason_(error::kUnknown), context_was_lost_(false), reset_by_robustness_extension_(false), supports_post_sub_buffer_(false), @@ -3107,13 +3114,18 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) validation_fbo_multisample_(0), validation_fbo_(0), texture_manager_service_id_generation_(0), - force_shader_name_hashing_for_test(false) { + force_shader_name_hashing_for_test(false), + weak_ptr_factory_(this) { DCHECK(group); } GLES2DecoderImpl::~GLES2DecoderImpl() { } +base::WeakPtr<GLES2Decoder> GLES2DecoderImpl::AsWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); +} + bool GLES2DecoderImpl::Initialize( const scoped_refptr<gl::GLSurface>& surface, const scoped_refptr<gl::GLContext>& context, @@ -3250,6 +3262,11 @@ bool GLES2DecoderImpl::Initialize( // vertex_attrib_manager is set to default_vertex_attrib_manager by this call DoBindVertexArrayOES(0); + framebuffer_manager_.reset(new FramebufferManager( + group_->max_draw_buffers(), group_->max_color_attachments(), + group_->framebuffer_completeness_cache())); + group_->texture_manager()->AddFramebufferManager(framebuffer_manager_.get()); + query_manager_.reset(new QueryManager(this, feature_info_.get())); image_manager_.reset(new ImageManager); @@ -3787,6 +3804,7 @@ Capabilities GLES2DecoderImpl::GetCapabilities() { caps.blend_equation_advanced_coherent = feature_info_->feature_flags().blend_equation_advanced_coherent; caps.texture_rg = feature_info_->feature_flags().ext_texture_rg; + caps.texture_norm16 = feature_info_->feature_flags().ext_texture_norm16; caps.texture_half_float_linear = feature_info_->feature_flags().enable_texture_half_float_linear; caps.color_buffer_half_float_rgba = @@ -4193,29 +4211,7 @@ void GLES2DecoderImpl::DeleteTexturesHelper(GLsizei n, GLuint client_id = client_ids[ii]; TextureRef* texture_ref = GetTexture(client_id); if (texture_ref) { - Texture* texture = texture_ref->texture(); - if (texture->IsAttachedToFramebuffer()) { - framebuffer_state_.clear_state_dirty = true; - } - // Unbind texture_ref from texture_ref units. - state_.UnbindTexture(texture_ref); - - // Unbind from current framebuffers. - if (supports_separate_framebuffer_binds) { - if (framebuffer_state_.bound_read_framebuffer.get()) { - framebuffer_state_.bound_read_framebuffer - ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref); - } - if (framebuffer_state_.bound_draw_framebuffer.get()) { - framebuffer_state_.bound_draw_framebuffer - ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref); - } - } else { - if (framebuffer_state_.bound_draw_framebuffer.get()) { - framebuffer_state_.bound_draw_framebuffer - ->UnbindTexture(GL_FRAMEBUFFER, texture_ref); - } - } + UnbindTexture(texture_ref, supports_separate_framebuffer_binds); RemoveTexture(client_id); } } @@ -4310,7 +4306,7 @@ bool GLES2DecoderImpl::MakeCurrent() { void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() { ProcessPendingReadPixels(false); - if (engine() && query_manager_.get()) + if (command_buffer_service() && query_manager_.get()) query_manager_->ProcessPendingTransferQueries(); } @@ -4727,22 +4723,6 @@ bool GLES2DecoderImpl::GetServiceTextureId(uint32_t client_texture_id, return false; } -uint32_t GLES2DecoderImpl::GetTextureUploadCount() { - return texture_state_.texture_upload_count; -} - -base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() { - return texture_state_.total_texture_upload_time; -} - -base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() { - return total_processing_commands_time_; -} - -void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) { - total_processing_commands_time_ += time; -} - void GLES2DecoderImpl::Destroy(bool have_context) { if (!initialized()) return; @@ -4871,6 +4851,14 @@ void GLES2DecoderImpl::Destroy(bool have_context) { srgb_converter_.reset(); clear_framebuffer_blit_.reset(); + if (framebuffer_manager_.get()) { + framebuffer_manager_->Destroy(have_context); + if (group_->texture_manager()) + group_->texture_manager()->RemoveFramebufferManager( + framebuffer_manager_.get()); + framebuffer_manager_.reset(); + } + if (query_manager_.get()) { query_manager_->Destroy(have_context); query_manager_.reset(); @@ -5231,6 +5219,7 @@ error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands, const volatile void* buffer, int num_entries, int* entries_processed) { + DCHECK(entries_processed); commands_to_process_ = num_commands; error::Error result = error::kNoError; const volatile CommandBufferEntry* cmd_data = @@ -5311,8 +5300,7 @@ error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands, } } - if (entries_processed) - *entries_processed = process_pos; + *entries_processed = process_pos; if (error::IsError(result)) { LOG(ERROR) << "Error: " << result << " for Command " @@ -8370,6 +8358,33 @@ bool GLES2DecoderImpl::InitializeSRGBConverter( return true; } +void GLES2DecoderImpl::UnbindTexture(TextureRef* texture_ref, + bool supports_separate_framebuffer_binds) { + Texture* texture = texture_ref->texture(); + if (texture->IsAttachedToFramebuffer()) { + framebuffer_state_.clear_state_dirty = true; + } + // Unbind texture_ref from texture_ref units. + state_.UnbindTexture(texture_ref); + + // Unbind from current framebuffers. + if (supports_separate_framebuffer_binds) { + if (framebuffer_state_.bound_read_framebuffer.get()) { + framebuffer_state_.bound_read_framebuffer->UnbindTexture( + GL_READ_FRAMEBUFFER_EXT, texture_ref); + } + if (framebuffer_state_.bound_draw_framebuffer.get()) { + framebuffer_state_.bound_draw_framebuffer->UnbindTexture( + GL_DRAW_FRAMEBUFFER_EXT, texture_ref); + } + } else { + if (framebuffer_state_.bound_draw_framebuffer.get()) { + framebuffer_state_.bound_draw_framebuffer->UnbindTexture(GL_FRAMEBUFFER, + texture_ref); + } + } +} + void GLES2DecoderImpl::EnsureRenderbufferBound() { if (!state_.bound_renderbuffer_valid) { state_.bound_renderbuffer_valid = true; @@ -11707,8 +11722,8 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size, glReadPixels(x, y, width, height, format, type, 0); pending_readpixel_fences_.push(FenceCallback()); WaitForReadPixels(base::Bind( - &GLES2DecoderImpl::FinishReadPixels, base::AsWeakPtr(this), width, - height, format, type, pixels_shm_id, pixels_shm_offset, + &GLES2DecoderImpl::FinishReadPixels, weak_ptr_factory_.GetWeakPtr(), + width, height, format, type, pixels_shm_id, pixels_shm_offset, result_shm_id, result_shm_offset, state_.pack_alignment, read_format, buffer)); glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); @@ -11920,7 +11935,7 @@ error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( surface_->PostSubBufferAsync( c.x, c.y, c.width, c.height, base::Bind(&GLES2DecoderImpl::FinishAsyncSwapBuffers, - base::AsWeakPtr(this))); + weak_ptr_factory_.GetWeakPtr())); } else { FinishSwapBuffers(surface_->PostSubBuffer(c.x, c.y, c.width, c.height)); } @@ -12103,38 +12118,62 @@ error::Error GLES2DecoderImpl::HandleScheduleDCLayerCHROMIUM( return error::kNoError; } - gl::GLImage* image = nullptr; - GLuint contents_texture_id = c.contents_texture_id; - if (contents_texture_id) { - TextureRef* ref = texture_manager()->GetTexture(contents_texture_id); - if (!ref) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM", - "unknown texture"); - return error::kNoError; - } - Texture::ImageState image_state; - image = ref->texture()->GetLevelImage(ref->texture()->target(), 0, - &image_state); - if (!image) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM", - "unsupported texture format"); - return error::kNoError; - } + GLsizei num_textures = c.num_textures; + if (num_textures < 0 || num_textures > 4) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glScheduleDCLayerCHROMIUM", + "number of textures greater than maximum of 4"); + return error::kNoError; } - const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset, - 8 * sizeof(GLfloat)); - if (!mem) { + size_t textures_size = num_textures * sizeof(GLuint); + + base::CheckedNumeric<uint32_t> data_size = textures_size; + const uint32_t kRectDataSize = 8 * sizeof(GLfloat); + data_size += kRectDataSize; + if (!data_size.IsValid()) + return error::kOutOfBounds; + const void* data = + GetAddressAndCheckSize(c.shm_id, c.shm_offset, data_size.ValueOrDie()); + if (!data) { return error::kOutOfBounds; } + const GLfloat* mem = reinterpret_cast<const GLfloat*>(data); + gfx::RectF contents_rect(mem[0], mem[1], mem[2], mem[3]); gfx::RectF bounds_rect(mem[4], mem[5], mem[6], mem[7]); + const volatile GLuint* texture_ids = reinterpret_cast<const volatile GLuint*>( + static_cast<const volatile char*>(data) + kRectDataSize); + + std::vector<scoped_refptr<gl::GLImage>> images; + for (int i = 0; i < num_textures; ++i) { + GLuint contents_texture_id = texture_ids[i]; + scoped_refptr<gl::GLImage> image; + if (contents_texture_id) { + TextureRef* ref = texture_manager()->GetTexture(contents_texture_id); + if (!ref) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM", + "unknown texture"); + return error::kNoError; + } + Texture::ImageState image_state; + image = ref->texture()->GetLevelImage(ref->texture()->target(), 0, + &image_state); + if (!image) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM", + "unsupported texture format"); + return error::kNoError; + } + } + images.push_back(image); + } + ui::DCRendererLayerParams params = ui::DCRendererLayerParams( dc_layer_shared_state_->is_clipped, dc_layer_shared_state_->clip_rect, - dc_layer_shared_state_->z_order, dc_layer_shared_state_->transform, image, - contents_rect, gfx::ToEnclosingRect(bounds_rect), c.background_color, - c.edge_aa_mask, dc_layer_shared_state_->opacity, filter); + dc_layer_shared_state_->z_order, dc_layer_shared_state_->transform, + images, contents_rect, gfx::ToEnclosingRect(bounds_rect), + c.background_color, c.edge_aa_mask, dc_layer_shared_state_->opacity, + filter); if (!surface_->ScheduleDCLayer(params)) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glScheduleDCLayerCHROMIUM", "failed to schedule DCLayer"); @@ -14360,6 +14399,32 @@ void GLES2DecoderImpl::DoCopyTexImage2D( const gfx::Rect dst(0, 0, size.width(), size.height()); src.Intersect(dst); + GLenum final_internal_format = TextureManager::AdjustTexInternalFormat( + feature_info_.get(), internal_format); + if (workarounds().force_int_or_srgb_cube_texture_complete && + texture->target() == GL_TEXTURE_CUBE_MAP && + (GLES2Util::IsIntegerFormat(final_internal_format) || + GLES2Util::GetColorEncodingFromInternalFormat(final_internal_format) == + GL_SRGB)) { + TextureManager::DoTexImageArguments args = { + target, + level, + final_internal_format, + width, + height, + 1, + border, + format, + type, + nullptr, + pixels_size, + 0, + TextureManager::DoTexImageArguments::kTexImage2D}; + texture_manager()->WorkaroundCopyTexImageCubeMap( + &texture_state_, &state_, &framebuffer_state_, texture_ref, func_name, + args); + } + if (src.x() != x || src.y() != y || src.width() != width || src.height() != height) { { @@ -14369,9 +14434,8 @@ void GLES2DecoderImpl::DoCopyTexImage2D( std::unique_ptr<char[]> zero(new char[pixels_size]); memset(zero.get(), 0, pixels_size); - glTexImage2D(target, level, TextureManager::AdjustTexInternalFormat( - feature_info_.get(), internal_format), - width, height, border, format, type, zero.get()); + glTexImage2D(target, level, final_internal_format, width, height, border, + format, type, zero.get()); } if (!src.IsEmpty()) { @@ -14390,8 +14454,6 @@ void GLES2DecoderImpl::DoCopyTexImage2D( } } } else { - GLenum final_internal_format = TextureManager::AdjustTexInternalFormat( - feature_info_.get(), internal_format); if (workarounds().init_two_cube_map_levels_before_copyteximage && texture->target() == GL_TEXTURE_CUBE_MAP && target != GL_TEXTURE_CUBE_MAP_POSITIVE_X) { @@ -15542,8 +15604,9 @@ void GLES2DecoderImpl::DoSwapBuffers() { ++pending_swaps_; TRACE_EVENT_ASYNC_BEGIN0("gpu", "AsyncSwapBuffers", async_swap_id); - surface_->SwapBuffersAsync(base::Bind( - &GLES2DecoderImpl::FinishAsyncSwapBuffers, base::AsWeakPtr(this))); + surface_->SwapBuffersAsync( + base::Bind(&GLES2DecoderImpl::FinishAsyncSwapBuffers, + weak_ptr_factory_.GetWeakPtr())); } else { FinishSwapBuffers(surface_->SwapBuffers()); } @@ -15589,7 +15652,7 @@ void GLES2DecoderImpl::DoCommitOverlayPlanes() { ClearScheduleDCLayerState(); if (supports_async_swap_) { surface_->CommitOverlayPlanesAsync(base::Bind( - &GLES2DecoderImpl::FinishSwapBuffers, base::AsWeakPtr(this))); + &GLES2DecoderImpl::FinishSwapBuffers, weak_ptr_factory_.GetWeakPtr())); } else { FinishSwapBuffers(surface_->CommitOverlayPlanes()); } @@ -15873,10 +15936,6 @@ error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVaryingsCHROMIUM( return error::kNoError; } -error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() { - return context_lost_reason_; -} - error::ContextLostReason GLES2DecoderImpl::GetContextLostReasonFromResetStatus( GLenum reset_status) const { switch (reset_status) { @@ -15910,7 +15969,7 @@ void GLES2DecoderImpl::MarkContextLost(error::ContextLostReason reason) { return; // Don't make GL calls in here, the context might not be current. - context_lost_reason_ = reason; + command_buffer_service()->SetContextLostReason(reason); current_decoder_error_ = error::kLostContext; context_was_lost_ = true; @@ -15998,6 +16057,9 @@ error::Error GLES2DecoderImpl::HandleInsertFenceSyncCHROMIUM( const uint64_t release_count = c.release_count(); if (!fence_sync_release_callback_.is_null()) fence_sync_release_callback_.Run(release_count); + // Exit inner command processing loop so that we check the scheduling state + // and yield if necessary as we may have unblocked a higher priority context. + ExitCommandProcessingEarly(); return error::kNoError; } @@ -16540,6 +16602,7 @@ bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUMInternalFormats( case GL_RGB5_A1: case GL_RGBA4: case GL_RGBA8UI: + case GL_RGB10_A2: valid_dest_format = feature_info_->IsWebGL2OrES3Context(); break; case GL_RGB9_E5: @@ -16567,6 +16630,7 @@ bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUMInternalFormats( break; } + // TODO(aleksandar.stojiljkovic): Use sized internal formats: crbug.com/628064 bool valid_source_format = source_internal_format == GL_RED || source_internal_format == GL_ALPHA || source_internal_format == GL_RGB || source_internal_format == GL_RGBA || @@ -16576,7 +16640,8 @@ bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUMInternalFormats( source_internal_format == GL_BGRA_EXT || source_internal_format == GL_BGRA8_EXT || source_internal_format == GL_RGB_YCBCR_420V_CHROMIUM || - source_internal_format == GL_RGB_YCBCR_422_CHROMIUM; + source_internal_format == GL_RGB_YCBCR_422_CHROMIUM || + source_internal_format == GL_R16_EXT; if (!valid_source_format) { std::string msg = "invalid source internal format " + GLES2Util::GetStringEnum(source_internal_format); @@ -17741,10 +17806,26 @@ void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM( GLenum target, GLint image_id) { TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM"); + BindTexImage2DCHROMIUMImpl("glBindTexImage2DCHROMIUM", target, 0, image_id); +} + +void GLES2DecoderImpl::DoBindTexImage2DWithInternalformatCHROMIUM( + GLenum target, + GLenum internalformat, + GLint image_id) { + TRACE_EVENT0("gpu", + "GLES2DecoderImpl::DoBindTexImage2DWithInternalformatCHROMIUM"); + + BindTexImage2DCHROMIUMImpl("glBindTexImage2DWithInternalformatCHROMIUM", + target, internalformat, image_id); +} + +void GLES2DecoderImpl::BindTexImage2DCHROMIUMImpl(const char* function_name, + GLenum target, + GLenum internalformat, + GLint image_id) { if (target == GL_TEXTURE_CUBE_MAP) { - LOCAL_SET_GL_ERROR( - GL_INVALID_ENUM, - "glBindTexImage2DCHROMIUM", "invalid target"); + LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, function_name, "invalid target"); return; } @@ -17753,17 +17834,14 @@ void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM( TextureRef* texture_ref = texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target); if (!texture_ref) { - LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glBindTexImage2DCHROMIUM", "no texture bound"); + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "no texture bound"); return; } gl::GLImage* image = image_manager()->LookupImage(image_id); if (!image) { - LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glBindTexImage2DCHROMIUM", "no image found with the given ID"); + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, + "no image found with the given ID"); return; } @@ -17775,15 +17853,22 @@ void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM( // Note: We fallback to using CopyTexImage() before the texture is used // when BindTexImage() fails. - if (image->BindTexImage(target)) - image_state = Texture::BOUND; + if (internalformat) { + if (image->BindTexImageWithInternalformat(target, internalformat)) + image_state = Texture::BOUND; + } else { + if (image->BindTexImage(target)) + image_state = Texture::BOUND; + } } gfx::Size size = image->GetSize(); - GLenum internalformat = image->GetInternalFormat(); - texture_manager()->SetLevelInfo( - texture_ref, target, 0, internalformat, size.width(), size.height(), 1, 0, - internalformat, GL_UNSIGNED_BYTE, gfx::Rect(size)); + GLenum texture_internalformat = + internalformat ? internalformat : image->GetInternalFormat(); + texture_manager()->SetLevelInfo(texture_ref, target, 0, + texture_internalformat, size.width(), + size.height(), 1, 0, texture_internalformat, + GL_UNSIGNED_BYTE, gfx::Rect(size)); texture_manager()->SetLevelImage(texture_ref, target, 0, image, image_state); } @@ -19581,6 +19666,63 @@ void GLES2DecoderImpl::RestoreAllExternalTextureBindingsIfNeeded() { texture_manager()->GetServiceIdGeneration(); } +error::Error GLES2DecoderImpl::HandleInitializeDiscardableTextureCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::InitializeDiscardableTextureCHROMIUM& c = + *static_cast< + const volatile gles2::cmds::InitializeDiscardableTextureCHROMIUM*>( + cmd_data); + TextureRef* texture = texture_manager()->GetTexture(c.texture_id); + if (!texture) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, + "glInitializeDiscardableTextureCHROMIUM", + "Invalid texture ID"); + return error::kNoError; + } + size_t size = texture->texture()->estimated_size(); + ServiceDiscardableHandle handle(GetSharedMemoryBuffer(c.shm_id), c.shm_offset, + c.shm_id); + GetContextGroup()->discardable_manager()->InsertLockedTexture( + c.texture_id, size, group_->texture_manager(), std::move(handle)); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleUnlockDiscardableTextureCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::UnlockDiscardableTextureCHROMIUM& c = + *static_cast< + const volatile gles2::cmds::UnlockDiscardableTextureCHROMIUM*>( + cmd_data); + ServiceDiscardableManager* discardable_manager = + GetContextGroup()->discardable_manager(); + TextureRef* texture_to_unbind; + if (!discardable_manager->UnlockTexture( + c.texture_id, group_->texture_manager(), &texture_to_unbind)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glUnlockDiscardableTextureCHROMIUM", + "Texture ID not initialized"); + } + if (texture_to_unbind) + UnbindTexture(texture_to_unbind, SupportsSeparateFramebufferBinds()); + + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleLockDiscardableTextureCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::LockDiscardableTextureCHROMIUM& c = + *static_cast<const volatile gles2::cmds::LockDiscardableTextureCHROMIUM*>( + cmd_data); + if (!GetContextGroup()->discardable_manager()->LockTexture( + c.texture_id, group_->texture_manager())) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glLockDiscardableTextureCHROMIUM", + "Texture ID not initialized"); + } + return error::kNoError; +} + // 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/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h index 8de703fa1dc..f0b1b822998 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -43,6 +43,7 @@ namespace gles2 { class ContextGroup; class ErrorState; class FeatureInfo; +class FramebufferManager; class GLES2Util; class ImageManager; class Logger; @@ -81,8 +82,8 @@ typedef base::Callback<void(const std::string& key, // This class implements the AsyncAPIInterface interface, decoding GLES2 // commands and calling GL. -class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, - public CommonDecoder { +class GPU_EXPORT GLES2Decoder : public CommonDecoder, + NON_EXPORTED_BASE(public AsyncAPIInterface) { public: typedef error::Error Error; typedef base::Callback<void(uint64_t release)> FenceSyncReleaseCallback; @@ -125,6 +126,8 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, log_commands_ = log_commands; } + virtual base::WeakPtr<GLES2Decoder> AsWeakPtr() = 0; + // Initializes the graphics context. Can create an offscreen // decoder with a frame buffer that can be referenced from the parent. // Takes ownership of GLContext. @@ -178,7 +181,7 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, // Restore States. virtual void RestoreActiveTexture() const = 0; - virtual void RestoreAllTextureUnitBindings( + virtual void RestoreAllTextureUnitAndSamplerBindings( const ContextState* prev_state) const = 0; virtual void RestoreActiveTextureUnitBinding(unsigned int target) const = 0; virtual void RestoreBufferBinding(unsigned int target) = 0; @@ -204,6 +207,9 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, // Gets the QueryManager for this context. virtual QueryManager* GetQueryManager() = 0; + // Gets the FramebufferManager for this context. + virtual FramebufferManager* GetFramebufferManager() = 0; + // Gets the TransformFeedbackManager for this context. virtual TransformFeedbackManager* GetTransformFeedbackManager() = 0; @@ -236,9 +242,6 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, virtual bool GetServiceTextureId(uint32_t client_texture_id, uint32_t* service_texture_id); - // Provides detail about a lost context if one occurred. - virtual error::ContextLostReason GetContextLostReason() = 0; - // Clears a level sub area of a 2D texture. // Returns false if a GL error should be generated. virtual bool ClearLevel(Texture* texture, @@ -296,10 +299,6 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, const NoParamCallback& callback) = 0; virtual void WaitForReadPixels(base::Closure callback) = 0; - virtual uint32_t GetTextureUploadCount() = 0; - virtual base::TimeDelta GetTotalTextureUploadTime() = 0; - virtual base::TimeDelta GetTotalProcessingCommandsTime() = 0; - virtual void AddProcessingCommandsTime(base::TimeDelta) = 0; // Returns true if the context was lost either by GL_ARB_robustness, forced // context loss or command buffer parse error. @@ -313,8 +312,8 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, virtual Logger* GetLogger() = 0; - virtual void BeginDecoding(); - virtual void EndDecoding(); + void BeginDecoding() override; + void EndDecoding() override; virtual const ContextState* GetContextState() = 0; virtual scoped_refptr<ShaderTranslatorInterface> GetTranslator( @@ -323,13 +322,7 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, protected: GLES2Decoder(); - // Decode a command, and call the corresponding GL functions. - // NOTE: DoCommand() is slower than calling DoCommands() on larger batches - // of commands at once, and is now only used for tests that need to track - // individual commands. - error::Error DoCommand(unsigned int command, - unsigned int arg_count, - const volatile void* cmd_data) override; + base::StringPiece GetLogPrefix() override; private: bool initialized_; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index fa2f5799cae..25237e25b8c 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -4778,6 +4778,24 @@ error::Error GLES2DecoderImpl::HandleBindTexImage2DCHROMIUM( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleBindTexImage2DWithInternalformatCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM& c = + *static_cast<const volatile gles2::cmds:: + BindTexImage2DWithInternalformatCHROMIUM*>(cmd_data); + GLenum target = static_cast<GLenum>(c.target); + GLenum internalformat = static_cast<GLenum>(c.internalformat); + GLint imageId = static_cast<GLint>(c.imageId); + if (!validators_->texture_bind_target.IsValid(target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM( + "glBindTexImage2DWithInternalformatCHROMIUM", target, "target"); + return error::kNoError; + } + DoBindTexImage2DWithInternalformatCHROMIUM(target, internalformat, imageId); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleReleaseTexImage2DCHROMIUM( uint32_t immediate_data_size, const volatile void* cmd_data) { diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.cc index d7da998daf9..f447b2bed2e 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.cc @@ -9,22 +9,15 @@ namespace gpu { namespace gles2 { -MockGLES2Decoder::MockGLES2Decoder() - : GLES2Decoder() { - ON_CALL(*this, GetCommandName(testing::_)) - .WillByDefault(testing::Return("")); +MockGLES2Decoder::MockGLES2Decoder() : GLES2Decoder(), weak_ptr_factory_(this) { ON_CALL(*this, MakeCurrent()) .WillByDefault(testing::Return(true)); } MockGLES2Decoder::~MockGLES2Decoder() {} -error::Error MockGLES2Decoder::FakeDoCommands(unsigned int num_commands, - const volatile void* buffer, - int num_entries, - int* entries_processed) { - return AsyncAPIInterface::DoCommands( - num_commands, buffer, num_entries, entries_processed); +base::WeakPtr<GLES2Decoder> MockGLES2Decoder::AsWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); } } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index c251ae5d710..aa4940f7ef7 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -39,10 +39,7 @@ class MockGLES2Decoder : public GLES2Decoder { MockGLES2Decoder(); virtual ~MockGLES2Decoder(); - error::Error FakeDoCommands(unsigned int num_commands, - const volatile void* buffer, - int num_entries, - int* entries_processed); + base::WeakPtr<GLES2Decoder> AsWeakPtr() override; MOCK_METHOD5(Initialize, bool(const scoped_refptr<gl::GLSurface>& surface, @@ -77,8 +74,8 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_METHOD0(PerformPollingWork, void()); MOCK_METHOD1(RestoreState, void(const ContextState* prev_state)); MOCK_CONST_METHOD0(RestoreActiveTexture, void()); - MOCK_CONST_METHOD1( - RestoreAllTextureUnitBindings, void(const ContextState* state)); + MOCK_CONST_METHOD1(RestoreAllTextureUnitAndSamplerBindings, + void(const ContextState* state)); MOCK_CONST_METHOD1( RestoreActiveTextureUnitBinding, void(unsigned int target)); MOCK_METHOD0(RestoreAllExternalTextureBindingsIfNeeded, void()); @@ -94,6 +91,7 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_CONST_METHOD0(ClearAllAttributes, void()); MOCK_CONST_METHOD0(RestoreAllAttributes, void()); MOCK_METHOD0(GetQueryManager, gpu::gles2::QueryManager*()); + MOCK_METHOD0(GetFramebufferManager, gpu::gles2::FramebufferManager*()); MOCK_METHOD0( GetTransformFeedbackManager, gpu::gles2::TransformFeedbackManager*()); MOCK_METHOD0(GetVertexArrayManager, gpu::gles2::VertexArrayManager*()); @@ -103,10 +101,6 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_METHOD1(SetIgnoreCachedStateForTest, void(bool ignore)); MOCK_METHOD1(SetForceShaderNameHashingForTest, void(bool force)); MOCK_METHOD1(SetAllowExit, void(bool allow)); - MOCK_METHOD3(DoCommand, - error::Error(unsigned int command, - unsigned int arg_count, - const volatile void* cmd_data)); MOCK_METHOD4(DoCommands, error::Error(unsigned int num_commands, const volatile void* buffer, @@ -114,8 +108,6 @@ class MockGLES2Decoder : public GLES2Decoder { int* entries_processed)); MOCK_METHOD2(GetServiceTextureId, bool(uint32_t client_texture_id, uint32_t* service_texture_id)); - MOCK_METHOD0(GetContextLostReason, error::ContextLostReason()); - MOCK_CONST_METHOD1(GetCommandName, const char*(unsigned int command_id)); MOCK_METHOD9(ClearLevel, bool(Texture* texture, unsigned target, @@ -159,14 +151,13 @@ class MockGLES2Decoder : public GLES2Decoder { void(const NoParamCallback& callback)); MOCK_METHOD1(WaitForReadPixels, void(base::Closure callback)); - MOCK_METHOD0(GetTextureUploadCount, uint32_t()); - MOCK_METHOD0(GetTotalTextureUploadTime, base::TimeDelta()); - MOCK_METHOD0(GetTotalProcessingCommandsTime, base::TimeDelta()); - MOCK_METHOD1(AddProcessingCommandsTime, void(base::TimeDelta)); MOCK_CONST_METHOD0(WasContextLost, bool()); MOCK_CONST_METHOD0(WasContextLostByRobustnessExtension, bool()); MOCK_METHOD1(MarkContextLost, void(gpu::error::ContextLostReason reason)); + private: + base::WeakPtrFactory<MockGLES2Decoder> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(MockGLES2Decoder); }; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index eac5a98899c..7170b470fbb 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc @@ -78,7 +78,8 @@ GLES2DecoderPassthroughImpl::GLES2DecoderPassthroughImpl(ContextGroup* group) context_(), offscreen_(false), group_(group), - feature_info_(new FeatureInfo) { + feature_info_(new FeatureInfo), + weak_ptr_factory_(this) { DCHECK(group); } @@ -145,12 +146,8 @@ GLES2Decoder::Error GLES2DecoderPassthroughImpl::DoCommands( return result; } -const char* GLES2DecoderPassthroughImpl::GetCommandName( - unsigned int command_id) const { - if (command_id >= kFirstGLES2Command && command_id < kNumCommands) { - return gles2::GetCommandName(static_cast<CommandId>(command_id)); - } - return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); +base::WeakPtr<GLES2Decoder> GLES2DecoderPassthroughImpl::AsWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); } bool GLES2DecoderPassthroughImpl::Initialize( @@ -359,6 +356,7 @@ gpu::Capabilities GLES2DecoderPassthroughImpl::GetCapabilities() { caps.blend_equation_advanced_coherent = feature_info_->feature_flags().blend_equation_advanced_coherent; caps.texture_rg = feature_info_->feature_flags().ext_texture_rg; + caps.texture_norm16 = feature_info_->feature_flags().ext_texture_norm16; caps.texture_half_float_linear = feature_info_->feature_flags().enable_texture_half_float_linear; caps.image_ycbcr_422 = @@ -371,14 +369,13 @@ gpu::Capabilities GLES2DecoderPassthroughImpl::GetCapabilities() { feature_info_->feature_flags().ext_render_buffer_format_bgra8888; caps.occlusion_query_boolean = feature_info_->feature_flags().occlusion_query_boolean; + caps.timer_queries = feature_info_->feature_flags().ext_disjoint_timer_query; + caps.post_sub_buffer = surface_->SupportsPostSubBuffer(); + caps.surfaceless = !offscreen_ && surface_->IsSurfaceless(); + caps.flips_vertically = !offscreen_ && surface_->FlipsVertically(); // TODO: - // caps.timer_queries - // caps.post_sub_buffer // caps.commit_overlay_planes - // caps.surfaceless - // caps.is_offscreen - // caps.flips_vertically return caps; } @@ -389,7 +386,7 @@ void GLES2DecoderPassthroughImpl::RestoreState(const ContextState* prev_state) { void GLES2DecoderPassthroughImpl::RestoreActiveTexture() const {} -void GLES2DecoderPassthroughImpl::RestoreAllTextureUnitBindings( +void GLES2DecoderPassthroughImpl::RestoreAllTextureUnitAndSamplerBindings( const ContextState* prev_state) const {} void GLES2DecoderPassthroughImpl::RestoreActiveTextureUnitBinding( @@ -455,6 +452,11 @@ gpu::gles2::QueryManager* GLES2DecoderPassthroughImpl::GetQueryManager() { return nullptr; } +gpu::gles2::FramebufferManager* +GLES2DecoderPassthroughImpl::GetFramebufferManager() { + return nullptr; +} + gpu::gles2::TransformFeedbackManager* GLES2DecoderPassthroughImpl::GetTransformFeedbackManager() { return nullptr; @@ -497,11 +499,6 @@ bool GLES2DecoderPassthroughImpl::GetServiceTextureId( service_texture_id); } -gpu::error::ContextLostReason -GLES2DecoderPassthroughImpl::GetContextLostReason() { - return error::kUnknown; -} - bool GLES2DecoderPassthroughImpl::ClearLevel(Texture* texture, unsigned target, int level, @@ -547,20 +544,6 @@ void GLES2DecoderPassthroughImpl::SetShaderCacheCallback( void GLES2DecoderPassthroughImpl::WaitForReadPixels(base::Closure callback) {} -uint32_t GLES2DecoderPassthroughImpl::GetTextureUploadCount() { - return 0; -} - -base::TimeDelta GLES2DecoderPassthroughImpl::GetTotalTextureUploadTime() { - return base::TimeDelta(); -} - -base::TimeDelta GLES2DecoderPassthroughImpl::GetTotalProcessingCommandsTime() { - return base::TimeDelta(); -} - -void GLES2DecoderPassthroughImpl::AddProcessingCommandsTime(base::TimeDelta) {} - bool GLES2DecoderPassthroughImpl::WasContextLost() const { return false; } @@ -777,7 +760,7 @@ bool GLES2DecoderPassthroughImpl::IsEmulatedQueryTarget(GLenum target) const { error::Error GLES2DecoderPassthroughImpl::ProcessQueries(bool did_finish) { while (!pending_queries_.empty()) { const PendingQuery& query = pending_queries_.front(); - GLint result_available = GL_FALSE; + GLuint result_available = GL_FALSE; GLuint64 result = 0; switch (query.target) { case GL_COMMANDS_ISSUED_CHROMIUM: @@ -808,11 +791,18 @@ error::Error GLES2DecoderPassthroughImpl::ProcessQueries(bool did_finish) { if (did_finish) { result_available = GL_TRUE; } else { - glGetQueryObjectiv(query.service_id, GL_QUERY_RESULT_AVAILABLE, - &result_available); + glGetQueryObjectuiv(query.service_id, GL_QUERY_RESULT_AVAILABLE, + &result_available); } if (result_available == GL_TRUE) { - glGetQueryObjectui64v(query.service_id, GL_QUERY_RESULT, &result); + if (feature_info_->feature_flags().ext_disjoint_timer_query) { + glGetQueryObjectui64v(query.service_id, GL_QUERY_RESULT, &result); + } else { + GLuint temp_result = 0; + glGetQueryObjectuiv(query.service_id, GL_QUERY_RESULT, + &temp_result); + result = temp_result; + } } break; } @@ -885,6 +875,34 @@ void GLES2DecoderPassthroughImpl::UpdateTextureBinding(GLenum target, } } +error::Error GLES2DecoderPassthroughImpl::BindTexImage2DCHROMIUMImpl( + GLenum target, + GLenum internalformat, + GLint imageId) { + if (target != GL_TEXTURE_2D) { + InsertError(GL_INVALID_ENUM, "Invalid target"); + return error::kNoError; + } + + gl::GLImage* image = image_manager_->LookupImage(imageId); + if (image == nullptr) { + InsertError(GL_INVALID_OPERATION, "No image found with the given ID"); + return error::kNoError; + } + + if (internalformat) { + if (!image->BindTexImageWithInternalformat(target, internalformat)) { + image->CopyTexImage(target); + } + } else { + if (!image->BindTexImage(target)) { + image->CopyTexImage(target); + } + } + + return error::kNoError; +} + #define GLES2_CMD_OP(name) \ { \ &GLES2DecoderPassthroughImpl::Handle##name, cmds::name::kArgFlags, \ diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h index 0985a2c3b9e..354cce7fde1 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h @@ -77,7 +77,7 @@ class GLES2DecoderPassthroughImpl : public GLES2Decoder { int num_entries, int* entries_processed) override; - const char* GetCommandName(unsigned int command_id) const override; + base::WeakPtr<GLES2Decoder> AsWeakPtr() override; bool Initialize(const scoped_refptr<gl::GLSurface>& surface, const scoped_refptr<gl::GLContext>& context, @@ -123,7 +123,7 @@ class GLES2DecoderPassthroughImpl : public GLES2Decoder { // Restore States. void RestoreActiveTexture() const override; - void RestoreAllTextureUnitBindings( + void RestoreAllTextureUnitAndSamplerBindings( const ContextState* prev_state) const override; void RestoreActiveTextureUnitBinding(unsigned int target) const override; void RestoreBufferBinding(unsigned int target) override; @@ -158,6 +158,9 @@ class GLES2DecoderPassthroughImpl : public GLES2Decoder { // Gets the QueryManager for this context. QueryManager* GetQueryManager() override; + // Gets the FramebufferManager for this context. + FramebufferManager* GetFramebufferManager() override; + // Gets the TransformFeedbackManager for this context. TransformFeedbackManager* GetTransformFeedbackManager() override; @@ -186,8 +189,6 @@ class GLES2DecoderPassthroughImpl : public GLES2Decoder { uint32_t* service_texture_id) override; // Provides detail about a lost context if one occurred. - error::ContextLostReason GetContextLostReason() override; - // Clears a level sub area of a texture // Returns false if a GL error should be generated. bool ClearLevel(Texture* texture, @@ -230,14 +231,6 @@ class GLES2DecoderPassthroughImpl : public GLES2Decoder { void WaitForReadPixels(base::Closure callback) override; - uint32_t GetTextureUploadCount() override; - - base::TimeDelta GetTotalTextureUploadTime() override; - - base::TimeDelta GetTotalProcessingCommandsTime() override; - - void AddProcessingCommandsTime(base::TimeDelta) override; - // Returns true if the context was lost either by GL_ARB_robustness, forced // context loss or command buffer parse error. bool WasContextLost() const override; @@ -303,6 +296,10 @@ class GLES2DecoderPassthroughImpl : public GLES2Decoder { void UpdateTextureBinding(GLenum target, GLuint client_id, GLuint service_id); + error::Error BindTexImage2DCHROMIUMImpl(GLenum target, + GLenum internalformat, + GLint image_id); + int commands_to_process_; DebugMarkerManager debug_marker_manager_; @@ -399,6 +396,8 @@ class GLES2DecoderPassthroughImpl : public GLES2Decoder { // Cache of scratch memory std::vector<uint8_t> scratch_memory_; + base::WeakPtrFactory<GLES2DecoderPassthroughImpl> weak_ptr_factory_; + // Include the prototypes of all the doer functions from a separate header to // keep this file clean. #include "gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h" diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h index 60282e148d8..71e0ab6a7d8 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h @@ -473,7 +473,7 @@ error::Error DoTexImage2D(GLenum target, GLint border, GLenum format, GLenum type, - GLsizei imagesize, + GLsizei image_size, const void* pixels); error::Error DoTexImage3D(GLenum target, GLint level, @@ -484,7 +484,7 @@ error::Error DoTexImage3D(GLenum target, GLint border, GLenum format, GLenum type, - GLsizei imagesize, + GLsizei image_size, const void* pixels); error::Error DoTexParameterf(GLenum target, GLenum pname, GLfloat param); error::Error DoTexParameterfv(GLenum target, @@ -508,7 +508,7 @@ error::Error DoTexSubImage2D(GLenum target, GLsizei height, GLenum format, GLenum type, - GLsizei imagesize, + GLsizei image_size, const void* pixels); error::Error DoTexSubImage3D(GLenum target, GLint level, @@ -520,7 +520,7 @@ error::Error DoTexSubImage3D(GLenum target, GLsizei depth, GLenum format, GLenum type, - GLsizei imagesize, + GLsizei image_size, const void* pixels); error::Error DoTransformFeedbackVaryings(GLuint program, GLsizei count, @@ -796,6 +796,9 @@ error::Error DoBindUniformLocationCHROMIUM(GLuint program, GLint location, const char* name); error::Error DoBindTexImage2DCHROMIUM(GLenum target, GLint imageId); +error::Error DoBindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId); error::Error DoReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId); error::Error DoTraceBeginCHROMIUM(const char* category_name, const char* trace_name); @@ -840,11 +843,13 @@ error::Error DoScheduleDCLayerSharedStateCHROMIUM(GLfloat opacity, const GLfloat* clip_rect, GLint z_order, const GLfloat* transform); -error::Error DoScheduleDCLayerCHROMIUM(GLuint contents_texture_id, - const GLfloat* contents_rect, - GLuint background_color, - GLuint edge_aa_mask, - const GLfloat* bounds_rect); +error::Error DoScheduleDCLayerCHROMIUM( + GLsizei num_textures, + const volatile GLuint* contents_texture_ids, + const GLfloat* contents_rect, + GLuint background_color, + GLuint edge_aa_mask, + const GLfloat* bounds_rect); error::Error DoCommitOverlayPlanesCHROMIUM(); error::Error DoSwapInterval(GLint interval); error::Error DoFlushDriverCachesCHROMIUM(); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index 43ec395c203..57cfae74696 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc @@ -193,6 +193,62 @@ void AppendStringToBuffer(std::vector<uint8_t>* data, memcpy(data->data() + old_size.ValueOrDie(), str, len); } +// In order to minimize the amount of data copied, the command buffer client +// unpack pixels before sending the glTex[Sub]Image[2|3]D calls. The only +// parameter it doesn't handle is the alignment. Resetting the unpack state is +// not needed when uploading from a PBO and for compressed formats which the +// client sends untouched. This class handles resetting and restoring the unpack +// state. +// TODO(cwallez@chromium.org) it would be nicer to handle the resetting / +// restoring on the client side. +class ScopedUnpackStateButAlignmentReset { + public: + ScopedUnpackStateButAlignmentReset(bool enable, bool is_3d) { + if (!enable) { + return; + } + + glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels_); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows_); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length_); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + + if (is_3d) { + glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &skip_images_); + glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); + glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &image_height_); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); + } + } + + ~ScopedUnpackStateButAlignmentReset() { + if (skip_pixels_ != 0) { + glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels_); + } + if (skip_rows_ != 0) { + glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows_); + } + if (skip_images_ != 0) { + glPixelStorei(GL_UNPACK_SKIP_IMAGES, skip_images_); + } + if (row_length_ != 0) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length_); + } + if (image_height_ != 0) { + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, image_height_); + } + } + + private: + GLint skip_pixels_ = 0; + GLint skip_rows_ = 0; + GLint skip_images_ = 0; + GLint row_length_ = 0; + GLint image_height_ = 0; +}; + } // anonymous namespace // Implementations of commands @@ -469,10 +525,9 @@ error::Error GLES2DecoderPassthroughImpl::DoCompressedTexImage2D( GLsizei image_size, GLsizei data_size, const void* data) { - // TODO(cwallez@chromium.org): Use data_size with the robust version of the - // entry point - glCompressedTexImage2D(target, level, internalformat, width, height, border, - image_size, data); + glCompressedTexImage2DRobustANGLE(target, level, internalformat, width, + height, border, image_size, data_size, + data); return error::kNoError; } @@ -487,10 +542,9 @@ error::Error GLES2DecoderPassthroughImpl::DoCompressedTexSubImage2D( GLsizei image_size, GLsizei data_size, const void* data) { - // TODO(cwallez@chromium.org): Use data_size with the robust version of the - // entry point - glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, - format, image_size, data); + glCompressedTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, + height, format, image_size, data_size, + data); return error::kNoError; } @@ -505,10 +559,9 @@ error::Error GLES2DecoderPassthroughImpl::DoCompressedTexImage3D( GLsizei image_size, GLsizei data_size, const void* data) { - // TODO(cwallez@chromium.org): Use data_size with the robust version of the - // entry point - glCompressedTexImage3D(target, level, internalformat, width, height, depth, - border, image_size, data); + glCompressedTexImage3DRobustANGLE(target, level, internalformat, width, + height, depth, border, image_size, + data_size, data); return error::kNoError; } @@ -525,10 +578,9 @@ error::Error GLES2DecoderPassthroughImpl::DoCompressedTexSubImage3D( GLsizei image_size, GLsizei data_size, const void* data) { - // TODO(cwallez@chromium.org): Use data_size with the robust version of the - // entry point - glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, - height, depth, format, image_size, data); + glCompressedTexSubImage3DRobustANGLE(target, level, xoffset, yoffset, zoffset, + width, height, depth, format, image_size, + data_size, data); return error::kNoError; } @@ -1849,10 +1901,12 @@ error::Error GLES2DecoderPassthroughImpl::DoTexImage2D(GLenum target, GLint border, GLenum format, GLenum type, - GLsizei imagesize, + GLsizei image_size, const void* pixels) { + ScopedUnpackStateButAlignmentReset reset_unpack( + image_size != 0 && feature_info_->gl_version_info().is_es3, false); glTexImage2DRobustANGLE(target, level, internalformat, width, height, border, - format, type, imagesize, pixels); + format, type, image_size, pixels); return error::kNoError; } @@ -1865,10 +1919,12 @@ error::Error GLES2DecoderPassthroughImpl::DoTexImage3D(GLenum target, GLint border, GLenum format, GLenum type, - GLsizei imagesize, + GLsizei image_size, const void* pixels) { + ScopedUnpackStateButAlignmentReset reset_unpack( + image_size != 0 && feature_info_->gl_version_info().is_es3, true); glTexImage3DRobustANGLE(target, level, internalformat, width, height, depth, - border, format, type, imagesize, pixels); + border, format, type, image_size, pixels); return error::kNoError; } @@ -1926,10 +1982,12 @@ error::Error GLES2DecoderPassthroughImpl::DoTexSubImage2D(GLenum target, GLsizei height, GLenum format, GLenum type, - GLsizei imagesize, + GLsizei image_size, const void* pixels) { + ScopedUnpackStateButAlignmentReset reset_unpack( + image_size != 0 && feature_info_->gl_version_info().is_es3, false); glTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, - format, type, imagesize, pixels); + format, type, image_size, pixels); return error::kNoError; } @@ -1943,10 +2001,12 @@ error::Error GLES2DecoderPassthroughImpl::DoTexSubImage3D(GLenum target, GLsizei depth, GLenum format, GLenum type, - GLsizei imagesize, + GLsizei image_size, const void* pixels) { + ScopedUnpackStateButAlignmentReset reset_unpack( + image_size != 0 && feature_info_->gl_version_info().is_es3, true); glTexSubImage3DRobustANGLE(target, level, xoffset, yoffset, zoffset, width, - height, depth, format, type, imagesize, pixels); + height, depth, format, type, image_size, pixels); return error::kNoError; } @@ -3262,6 +3322,17 @@ error::Error GLES2DecoderPassthroughImpl::DoPostSubBufferCHROMIUM( GLint y, GLint width, GLint height) { + if (!surface_->SupportsPostSubBuffer()) { + InsertError(GL_INVALID_OPERATION, + "glPostSubBufferCHROMIUM is not supported for this surface."); + return error::kNoError; + } + + gfx::SwapResult result = surface_->PostSubBuffer(x, y, width, height); + if (result == gfx::SwapResult::SWAP_FAILED) { + LOG(ERROR) << "Context lost because PostSubBuffer failed."; + } + // TODO(geofflang): force the context loss? return error::kNoError; } @@ -3489,22 +3560,15 @@ error::Error GLES2DecoderPassthroughImpl::DoBindUniformLocationCHROMIUM( error::Error GLES2DecoderPassthroughImpl::DoBindTexImage2DCHROMIUM( GLenum target, GLint imageId) { - if (target != GL_TEXTURE_2D) { - InsertError(GL_INVALID_ENUM, "Invalid target"); - return error::kNoError; - } - - gl::GLImage* image = image_manager_->LookupImage(imageId); - if (image == nullptr) { - InsertError(GL_INVALID_OPERATION, "No image found with the given ID"); - return error::kNoError; - } - - if (!image->BindTexImage(target)) { - image->CopyTexImage(target); - } + return BindTexImage2DCHROMIUMImpl(target, 0, imageId); +} - return error::kNoError; +error::Error +GLES2DecoderPassthroughImpl::DoBindTexImage2DWithInternalformatCHROMIUM( + GLenum target, + GLenum internalformat, + GLint imageId) { + return BindTexImage2DCHROMIUMImpl(target, internalformat, imageId); } error::Error GLES2DecoderPassthroughImpl::DoReleaseTexImage2DCHROMIUM( @@ -3664,7 +3728,8 @@ error::Error GLES2DecoderPassthroughImpl::DoScheduleDCLayerSharedStateCHROMIUM( } error::Error GLES2DecoderPassthroughImpl::DoScheduleDCLayerCHROMIUM( - GLuint contents_texture_id, + GLsizei num_textures, + const volatile GLuint* contents_texture_ids, const GLfloat* contents_rect, GLuint background_color, GLuint edge_aa_mask, diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc index 50e2cbfde3a..c18ea3dde93 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc @@ -1811,19 +1811,26 @@ error::Error GLES2DecoderPassthroughImpl::HandleScheduleDCLayerCHROMIUM( const volatile gles2::cmds::ScheduleDCLayerCHROMIUM& c = *static_cast<const volatile gles2::cmds::ScheduleDCLayerCHROMIUM*>( cmd_data); - const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset, - 8 * sizeof(GLfloat)); + unsigned int size; + const GLfloat* mem = GetSharedMemoryAndSizeAs<const GLfloat*>( + c.shm_id, c.shm_offset, 8 * sizeof(GLfloat), &size); if (!mem) { return error::kOutOfBounds; } - GLuint contents_texture_id = static_cast<GLint>(c.contents_texture_id); + const GLsizei num_textures = c.num_textures; + if (num_textures < 0 || (size - 8 * sizeof(GLfloat)) / sizeof(GLuint) < + static_cast<GLuint>(num_textures)) { + return error::kOutOfBounds; + } + const volatile GLuint* contents_texture_ids = + reinterpret_cast<const volatile GLuint*>(mem + 8); const GLfloat* contents_rect = mem; GLuint background_color = static_cast<GLuint>(c.background_color); GLuint edge_aa_mask = static_cast<GLuint>(c.edge_aa_mask); const GLfloat* bounds_rect = mem + 4; - error::Error error = - DoScheduleDCLayerCHROMIUM(contents_texture_id, contents_rect, - background_color, edge_aa_mask, bounds_rect); + error::Error error = DoScheduleDCLayerCHROMIUM( + num_textures, contents_texture_ids, contents_rect, background_color, + edge_aa_mask, bounds_rect); if (error != error::kNoError) { return error; } @@ -2721,5 +2728,25 @@ error::Error GLES2DecoderPassthroughImpl::HandleCompressedTexSubImage3D( data_size, data); } +error::Error +GLES2DecoderPassthroughImpl::HandleInitializeDiscardableTextureCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + return error::kNoError; +} + +error::Error +GLES2DecoderPassthroughImpl::HandleUnlockDiscardableTextureCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + return error::kNoError; +} + +error::Error GLES2DecoderPassthroughImpl::HandleLockDiscardableTextureCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + return error::kNoError; +} + } // namespace gles2 } // namespace gpu diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc index 9c6f95f3e27..629a24d9a88 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc @@ -4024,6 +4024,24 @@ error::Error GLES2DecoderPassthroughImpl::HandleBindTexImage2DCHROMIUM( return error::kNoError; } +error::Error +GLES2DecoderPassthroughImpl::HandleBindTexImage2DWithInternalformatCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM& c = + *static_cast<const volatile gles2::cmds:: + BindTexImage2DWithInternalformatCHROMIUM*>(cmd_data); + GLenum target = static_cast<GLenum>(c.target); + GLenum internalformat = static_cast<GLenum>(c.internalformat); + GLint imageId = static_cast<GLint>(c.imageId); + error::Error error = DoBindTexImage2DWithInternalformatCHROMIUM( + target, internalformat, imageId); + if (error != error::kNoError) { + return error; + } + return error::kNoError; +} + error::Error GLES2DecoderPassthroughImpl::HandleReleaseTexImage2DCHROMIUM( uint32_t immediate_data_size, const volatile void* cmd_data) { diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 1be498166d5..8114c7e6f93 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -11,7 +11,6 @@ #include "base/strings/string_number_conversions.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/gl_surface_mock.h" @@ -152,62 +151,38 @@ TEST_P(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) { *result = 0; GetMaxValueInBufferCHROMIUM cmd; - cmd.Init(client_element_buffer_id_, - kValidIndexRangeCount, - GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(client_element_buffer_id_, kValidIndexRangeCount, GL_UNSIGNED_SHORT, + kValidIndexRangeStart * 2, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(7u, *result); EXPECT_EQ(GL_NO_ERROR, GetGLError()); - cmd.Init(client_element_buffer_id_, - kValidIndexRangeCount + 1, - GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2, - kSharedMemoryId, + cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1, + GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(100u, *result); EXPECT_EQ(GL_NO_ERROR, GetGLError()); - cmd.Init(kInvalidClientId, - kValidIndexRangeCount, - GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(kInvalidClientId, kValidIndexRangeCount, GL_UNSIGNED_SHORT, + kValidIndexRangeStart * 2, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - cmd.Init(client_element_buffer_id_, - kOutOfRangeIndexRangeEnd, - GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2, - kSharedMemoryId, + cmd.Init(client_element_buffer_id_, kOutOfRangeIndexRangeEnd, + GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - cmd.Init(client_element_buffer_id_, - kValidIndexRangeCount + 1, - GL_UNSIGNED_SHORT, - kOutOfRangeIndexRangeEnd * 2, - kSharedMemoryId, + cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1, + GL_UNSIGNED_SHORT, kOutOfRangeIndexRangeEnd * 2, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - cmd.Init(client_element_buffer_id_, - kValidIndexRangeCount + 1, - GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2, - kSharedMemoryId, + cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1, + GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(client_buffer_id_, - kValidIndexRangeCount + 1, - GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(client_buffer_id_, kValidIndexRangeCount + 1, GL_UNSIGNED_SHORT, + kValidIndexRangeStart * 2, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); cmd.Init(client_element_buffer_id_, @@ -217,11 +192,8 @@ TEST_P(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) { kInvalidSharedMemoryId, kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(client_element_buffer_id_, - kValidIndexRangeCount + 1, - GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2, - kSharedMemoryId, + cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1, + GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2, shared_memory_id_, kInvalidSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } @@ -508,8 +480,8 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) { BeginQueryEXT begin_cmd; // Test id = 0 fails. - begin_cmd.Init( - GL_ANY_SAMPLES_PASSED_EXT, 0, kSharedMemoryId, kSharedMemoryOffset); + begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 0, shared_memory_id_, + kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); @@ -530,16 +502,12 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) { EXPECT_TRUE(query == NULL); // BeginQueryEXT should fail if id is not generated from GenQueriesEXT. - begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, - kInvalidClientId, - kSharedMemoryId, + begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, kInvalidClientId, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, - kNewClientId, - kSharedMemoryId, + begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, kNewClientId, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -760,18 +728,12 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) { TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) { for (size_t i = 0; i < arraysize(kQueryTypes); ++i) { // Out-of-bounds. - CheckBeginEndQueryBadMemoryFails(this, - kNewClientId, - kNewServiceId, - kQueryTypes[i], - kSharedMemoryId, + CheckBeginEndQueryBadMemoryFails(this, kNewClientId, kNewServiceId, + kQueryTypes[i], shared_memory_id_, kInvalidSharedMemoryOffset); // Overflow. - CheckBeginEndQueryBadMemoryFails(this, - kNewClientId, - kNewServiceId, - kQueryTypes[i], - kSharedMemoryId, + CheckBeginEndQueryBadMemoryFails(this, kNewClientId, kNewServiceId, + kQueryTypes[i], shared_memory_id_, 0xfffffffcu); } } @@ -800,16 +762,14 @@ TEST_P(GLES2DecoderManualInitTest, QueryReuseTest) { EXPECT_EQ( error::kNoError, ExecuteQueryCounterCmd(this, gl, &gpu_timing_queries, query_type.type, - kNewClientId, kNewServiceId, kSharedMemoryId, + kNewClientId, kNewServiceId, shared_memory_id_, kSharedMemoryOffset, 1)); } else { - EXPECT_EQ(error::kNoError, ExecuteBeginQueryCmd(this, gl, - &gpu_timing_queries, - query_type.type, - kNewClientId, - kNewServiceId, - kSharedMemoryId, - kSharedMemoryOffset)); + EXPECT_EQ( + error::kNoError, + ExecuteBeginQueryCmd(this, gl, &gpu_timing_queries, query_type.type, + kNewClientId, kNewServiceId, shared_memory_id_, + kSharedMemoryOffset)); EXPECT_EQ(error::kNoError, ExecuteEndQueryCmd(this, gl, query_type.type, 1)); } @@ -821,16 +781,14 @@ TEST_P(GLES2DecoderManualInitTest, QueryReuseTest) { EXPECT_EQ( error::kNoError, ExecuteQueryCounterCmd(this, gl, &gpu_timing_queries, query_type.type, - kNewClientId, kNewServiceId, kSharedMemoryId, + kNewClientId, kNewServiceId, shared_memory_id_, kSharedMemoryOffset, 2)); } else { - EXPECT_EQ(error::kNoError, ExecuteBeginQueryCmd(this, gl, - &gpu_timing_queries, - query_type.type, - kNewClientId, - kNewServiceId, - kSharedMemoryId, - kSharedMemoryOffset)); + EXPECT_EQ( + error::kNoError, + ExecuteBeginQueryCmd(this, gl, &gpu_timing_queries, query_type.type, + kNewClientId, kNewServiceId, shared_memory_id_, + kSharedMemoryOffset)); EXPECT_EQ(error::kNoError, ExecuteEndQueryCmd(this, gl, query_type.type, 2)); } @@ -849,9 +807,7 @@ TEST_P(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) { GenHelper<GenQueriesEXTImmediate>(kNewClientId); // Test valid parameters work. - begin_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, - kNewClientId, - kSharedMemoryId, + begin_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, kNewClientId, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -876,9 +832,7 @@ TEST_P(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) { GenHelper<GenQueriesEXTImmediate>(kNewClientId); // Test valid parameters work. - begin_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, - kNewClientId, - kSharedMemoryId, + begin_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, kNewClientId, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -914,13 +868,13 @@ TEST_P(GLES2DecoderTest, SetDisjointValueSync) { cmd.Init(kInvalidSharedMemoryId, 0u); EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(kSharedMemoryId, kSharedBufferSize); + cmd.Init(shared_memory_id_, kSharedBufferSize); EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); - cmd.Init(kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); } @@ -936,10 +890,8 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) { GenHelper<GenQueriesEXTImmediate>(kNewClientId); BeginQueryEXT begin_cmd; - begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, - kNewClientId, - kSharedMemoryId, - kSharedMemoryOffset); + begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, kNewClientId, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -1012,37 +964,27 @@ TEST_P(GLES2DecoderManualInitTest, BeginInvalidTargetQueryFails) { GenHelper<GenQueriesEXTImmediate>(kNewClientId); BeginQueryEXT begin_cmd; - begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, - kNewClientId, - kSharedMemoryId, - kSharedMemoryOffset); + begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, kNewClientId, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - begin_cmd.Init(GL_ANY_SAMPLES_PASSED, - kNewClientId, - kSharedMemoryId, + begin_cmd.Init(GL_ANY_SAMPLES_PASSED, kNewClientId, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - begin_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, - kNewClientId, - kSharedMemoryId, - kSharedMemoryOffset); + begin_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, kNewClientId, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - begin_cmd.Init(GL_TIME_ELAPSED, - kNewClientId, - kSharedMemoryId, + begin_cmd.Init(GL_TIME_ELAPSED, kNewClientId, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - begin_cmd.Init(0xdeadbeef, - kNewClientId, - kSharedMemoryId, + begin_cmd.Init(0xdeadbeef, kNewClientId, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); @@ -1069,11 +1011,8 @@ TEST_P(GLES2DecoderManualInitTest, QueryCounterEXTTimeStamp) { .Times(1) .RetiresOnSaturation(); QueryCounterEXT query_counter_cmd; - query_counter_cmd.Init(kNewClientId, - GL_TIMESTAMP, - kSharedMemoryId, - kSharedMemoryOffset, - 1); + query_counter_cmd.Init(kNewClientId, GL_TIMESTAMP, shared_memory_id_, + kSharedMemoryOffset, 1); EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -1096,19 +1035,13 @@ TEST_P(GLES2DecoderManualInitTest, InvalidTargetQueryCounterFails) { GenHelper<GenQueriesEXTImmediate>(kNewClientId); QueryCounterEXT query_counter_cmd; - query_counter_cmd.Init(kNewClientId, - GL_TIMESTAMP, - kSharedMemoryId, - kSharedMemoryOffset, - 1); + query_counter_cmd.Init(kNewClientId, GL_TIMESTAMP, shared_memory_id_, + kSharedMemoryOffset, 1); EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - query_counter_cmd.Init(kNewClientId, - 0xdeadbeef, - kSharedMemoryId, - kSharedMemoryOffset, - 1); + query_counter_cmd.Init(kNewClientId, 0xdeadbeef, shared_memory_id_, + kSharedMemoryOffset, 1); EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -1200,30 +1133,14 @@ TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) { EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128)) .WillOnce(Return(true)) .RetiresOnSaturation(); - DoTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - 8, - 4, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(128u, memory_tracker->GetPoolSize()); EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64)) .WillOnce(Return(true)) .RetiresOnSaturation(); - DoTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - 4, - 4, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(64u, memory_tracker->GetPoolSize()); EXPECT_EQ(GL_NO_ERROR, GetGLError()); // Check we get out of memory and no call to glTexImage2D if Ensure fails. @@ -1231,15 +1148,8 @@ TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) { .WillOnce(Return(false)) .RetiresOnSaturation(); TexImage2D cmd; - cmd.Init(GL_TEXTURE_2D, - 0, - GL_RGBA, - 4, - 4, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); EXPECT_EQ(64u, memory_tracker->GetPoolSize()); @@ -1486,9 +1396,7 @@ class GLES2DecoderDoCommandsTest : public GLES2DecoderTest { TEST_P(GLES3DecoderTest, BeginInvalidTargetQueryFails) { BeginQueryEXT begin_cmd; - begin_cmd.Init(0xdeadbeef, - kNewClientId, - kSharedMemoryId, + begin_cmd.Init(0xdeadbeef, kNewClientId, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h index 974e976687c..b4a5f0d90b6 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h @@ -8,7 +8,6 @@ #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/buffer_manager.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/framebuffer_manager.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc index 2e660b8d640..7a0d658d79a 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc @@ -8,7 +8,6 @@ #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/program_manager.h" #include "gpu/command_buffer/service/test_helper.h" @@ -23,7 +22,7 @@ using ::testing::MatcherCast; using ::testing::Pointee; using ::testing::Return; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::StrEq; namespace gpu { @@ -54,9 +53,8 @@ template <> void GLES2DecoderTestBase::SpecializedSetup<cmds::GenerateMipmap, 0>( bool valid) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - DoTexImage2D( - GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, - kSharedMemoryId, kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); if (valid) { EXPECT_CALL(*gl_, GetError()) .WillOnce(Return(GL_NO_ERROR)) @@ -112,9 +110,8 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::CopyTexSubImage2D, 0>( bool valid) { if (valid) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - DoTexImage2D( - GL_TEXTURE_2D, 2, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, - kSharedMemoryId, kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 16, 16, 0, GL_RGBA, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset); } }; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h index 3cc0df74c42..23e41af93d3 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h @@ -33,7 +33,7 @@ TEST_P(GLES2DecoderTest1, BindBufferValidArgs) { TEST_P(GLES2DecoderTest1, BindBufferValidArgsNewId) { EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, kNewServiceId)); EXPECT_CALL(*gl_, GenBuffersARB(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); SpecializedSetup<cmds::BindBuffer, 0>(true); cmds::BindBuffer cmd; cmd.Init(GL_ARRAY_BUFFER, kNewClientId); @@ -63,7 +63,7 @@ TEST_P(GLES2DecoderTest1, BindFramebufferValidArgs) { TEST_P(GLES2DecoderTest1, BindFramebufferValidArgsNewId) { EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER, kNewServiceId)); EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); SpecializedSetup<cmds::BindFramebuffer, 0>(true); cmds::BindFramebuffer cmd; cmd.Init(GL_FRAMEBUFFER, kNewClientId); @@ -94,7 +94,7 @@ TEST_P(GLES2DecoderTest1, BindRenderbufferValidArgs) { TEST_P(GLES2DecoderTest1, BindRenderbufferValidArgsNewId) { EXPECT_CALL(*gl_, BindRenderbufferEXT(GL_RENDERBUFFER, kNewServiceId)); EXPECT_CALL(*gl_, GenRenderbuffersEXT(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); SpecializedSetup<cmds::BindRenderbuffer, 0>(true); cmds::BindRenderbuffer cmd; cmd.Init(GL_RENDERBUFFER, kNewClientId); @@ -656,7 +656,7 @@ TEST_P(GLES2DecoderTest1, FrontFaceValidArgs) { TEST_P(GLES2DecoderTest1, GenBuffersImmediateValidArgs) { EXPECT_CALL(*gl_, GenBuffersARB(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); cmds::GenBuffersImmediate* cmd = GetImmediateAs<cmds::GenBuffersImmediate>(); GLuint temp = kNewClientId; SpecializedSetup<cmds::GenBuffersImmediate, 0>(true); @@ -719,7 +719,7 @@ TEST_P(GLES2DecoderTest1, GenerateMipmapInvalidArgs0_1) { TEST_P(GLES2DecoderTest1, GenFramebuffersImmediateValidArgs) { EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); cmds::GenFramebuffersImmediate* cmd = GetImmediateAs<cmds::GenFramebuffersImmediate>(); GLuint temp = kNewClientId; @@ -758,7 +758,7 @@ TEST_P(GLES2DecoderTest1, GenFramebuffersImmediateInvalidArgs) { TEST_P(GLES2DecoderTest1, GenRenderbuffersImmediateValidArgs) { EXPECT_CALL(*gl_, GenRenderbuffersEXT(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); cmds::GenRenderbuffersImmediate* cmd = GetImmediateAs<cmds::GenRenderbuffersImmediate>(); GLuint temp = kNewClientId; @@ -797,7 +797,7 @@ TEST_P(GLES2DecoderTest1, GenRenderbuffersImmediateInvalidArgs) { TEST_P(GLES3DecoderTest1, GenSamplersImmediateValidArgs) { EXPECT_CALL(*gl_, GenSamplers(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); cmds::GenSamplersImmediate* cmd = GetImmediateAs<cmds::GenSamplersImmediate>(); GLuint temp = kNewClientId; @@ -836,7 +836,7 @@ TEST_P(GLES3DecoderTest1, GenSamplersImmediateInvalidArgs) { TEST_P(GLES2DecoderTest1, GenTexturesImmediateValidArgs) { EXPECT_CALL(*gl_, GenTextures(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); cmds::GenTexturesImmediate* cmd = GetImmediateAs<cmds::GenTexturesImmediate>(); GLuint temp = kNewClientId; @@ -875,7 +875,7 @@ TEST_P(GLES2DecoderTest1, GenTexturesImmediateInvalidArgs) { TEST_P(GLES3DecoderTest1, GenTransformFeedbacksImmediateValidArgs) { EXPECT_CALL(*gl_, GenTransformFeedbacks(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); cmds::GenTransformFeedbacksImmediate* cmd = GetImmediateAs<cmds::GenTransformFeedbacksImmediate>(); GLuint temp = kNewClientId; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc index 157e9532d7a..11a3b697a41 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc @@ -9,7 +9,6 @@ #include "base/command_line.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" #include "gpu/command_buffer/service/program_manager.h" @@ -26,7 +25,7 @@ using ::testing::MatcherCast; using ::testing::Pointee; using ::testing::Return; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::StrEq; namespace gpu { @@ -614,25 +613,21 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::GetProgramInfoLog, 0>( .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) - .WillOnce(SetArgumentPointee<2>(1)); - EXPECT_CALL(*gl_, - GetProgramiv(kServiceProgramId, GL_INFO_LOG_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(strlen(log) + 1)) + .WillOnce(SetArgPointee<2>(1)); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_INFO_LOG_LENGTH, _)) + .WillOnce(SetArgPointee<2>(strlen(log) + 1)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetProgramInfoLog(kServiceProgramId, strlen(log) + 1, _, _)) - .WillOnce(DoAll( - SetArgumentPointee<2>(strlen(log)), - SetArrayArgument<3>(log, log + strlen(log) + 1))) + EXPECT_CALL(*gl_, GetProgramInfoLog(kServiceProgramId, strlen(log) + 1, _, _)) + .WillOnce(DoAll(SetArgPointee<2>(strlen(log)), + SetArrayArgument<3>(log, log + strlen(log) + 1))) .RetiresOnSaturation(); EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTES, _)) - .WillOnce(SetArgumentPointee<2>(0)); + .WillOnce(SetArgPointee<2>(0)); EXPECT_CALL( - *gl_, - GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(0)); + *gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) + .WillOnce(SetArgPointee<2>(0)); EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _)) - .WillOnce(SetArgumentPointee<2>(0)); + .WillOnce(SetArgPointee<2>(0)); Program* program = GetProgram(client_program_id_); ASSERT_TRUE(program != NULL); @@ -730,19 +725,17 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::LinkProgram, 0>( .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) - .WillOnce(SetArgumentPointee<2>(1)); - EXPECT_CALL(*gl_, - GetProgramiv(kServiceProgramId, GL_INFO_LOG_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(0)) + .WillOnce(SetArgPointee<2>(1)); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_INFO_LOG_LENGTH, _)) + .WillOnce(SetArgPointee<2>(0)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTES, _)) - .WillOnce(SetArgumentPointee<2>(0)); + .WillOnce(SetArgPointee<2>(0)); EXPECT_CALL( - *gl_, - GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(0)); + *gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) + .WillOnce(SetArgPointee<2>(0)); EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _)) - .WillOnce(SetArgumentPointee<2>(0)); + .WillOnce(SetArgPointee<2>(0)); cmds::AttachShader attach_cmd; attach_cmd.Init(client_program_id_, kClientVertexShaderId); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc index bdfa2a05987..5ffc9d3c692 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc @@ -9,7 +9,6 @@ #include "base/command_line.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" #include "gpu/command_buffer/service/program_manager.h" @@ -24,7 +23,7 @@ using ::testing::MatcherCast; using ::testing::Pointee; using ::testing::Return; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::StrEq; namespace gpu { @@ -124,9 +123,8 @@ void GLES2DecoderTestBase::SpecializedSetup<ValidateProgram, 0>( link_cmd.Init(client_program_id_); EXPECT_EQ(error::kNoError, ExecuteCmd(link_cmd)); - EXPECT_CALL(*gl_, - GetProgramiv(kServiceProgramId, GL_INFO_LOG_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(0)) + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_INFO_LOG_LENGTH, _)) + .WillOnce(SetArgPointee<2>(0)) .RetiresOnSaturation(); }; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc index 02987131e63..9094ab01b4f 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc @@ -10,7 +10,6 @@ #include "base/strings/string_number_conversions.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/gl_surface_mock.h" @@ -42,7 +41,7 @@ using ::testing::Pointee; using ::testing::Return; using ::testing::SaveArg; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::SetArgPointee; using ::testing::StrEq; using ::testing::StrictMock; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index 2187f4961f8..0cfbb104cf3 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -16,7 +16,6 @@ #include "base/strings/string_split.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/logger.h" #include "gpu/command_buffer/service/mailbox_manager.h" @@ -113,6 +112,10 @@ GLES2DecoderTestBase::GLES2DecoderTestBase() client_vertexarray_id_(124), client_transformfeedback_id_(126), client_sync_id_(127), + shared_memory_id_(0), + shared_memory_offset_(0), + shared_memory_address_(nullptr), + shared_memory_base_(nullptr), service_renderbuffer_id_(0), service_renderbuffer_valid_(false), ignore_cached_state_for_test_(GetParam()), @@ -198,7 +201,7 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( new ShaderTranslatorCache(gpu_preferences_), new FramebufferCompletenessCache, feature_info, normalized_init.bind_generates_resource, nullptr, - nullptr, GpuFeatureInfo())); + nullptr, GpuFeatureInfo(), &discardable_manager_)); bool use_default_textures = normalized_init.bind_generates_resource; InSequence sequence; @@ -229,11 +232,6 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( // will initialize itself. mock_decoder_.reset(new MockGLES2Decoder()); - // Install FakeDoCommands handler so we can use individual DoCommand() - // expectations. - EXPECT_CALL(*mock_decoder_, DoCommands(_, _, _, _)).WillRepeatedly( - Invoke(mock_decoder_.get(), &MockGLES2Decoder::FakeDoCommands)); - EXPECT_TRUE(group_->Initialize(mock_decoder_.get(), init.context_type, DisallowedFeatures())); @@ -459,14 +457,15 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( } #endif - engine_.reset(new StrictMock<MockCommandBufferEngine>()); + command_buffer_service_.reset(new FakeCommandBufferServiceBase()); scoped_refptr<gpu::Buffer> buffer = - engine_->GetSharedMemoryBuffer(kSharedMemoryId); + command_buffer_service_->CreateTransferBufferHelper(kSharedBufferSize, + &shared_memory_id_); shared_memory_offset_ = kSharedMemoryOffset; shared_memory_address_ = reinterpret_cast<int8_t*>(buffer->memory()) + shared_memory_offset_; - shared_memory_id_ = kSharedMemoryId; shared_memory_base_ = buffer->memory(); + ClearSharedMemory(); gles2::ContextCreationAttribHelper attribs; attribs.alpha_size = normalized_init.request_alpha ? 8 : 0; @@ -488,7 +487,7 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( .WillOnce(Return(GL_NO_ERROR)); } decoder_->MakeCurrent(); - decoder_->set_engine(engine_.get()); + decoder_->set_command_buffer_service(command_buffer_service_.get()); decoder_->BeginDecoding(); EXPECT_CALL(*gl_, GenBuffersARB(_, _)) @@ -542,6 +541,7 @@ void GLES2DecoderTestBase::ResetDecoder() { EXPECT_EQ(GL_NO_ERROR, GetGLError()); if (!decoder_->WasContextLost()) { EXPECT_CALL(*gl_, DeleteBuffersARB(1, _)).Times(2).RetiresOnSaturation(); + EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, _)).Times(AnyNumber()); if (group_->feature_info()->feature_flags().native_vertex_array_object) { EXPECT_CALL(*gl_, DeleteVertexArraysOES(1, Pointee(kServiceVertexArrayId))) @@ -566,7 +566,7 @@ void GLES2DecoderTestBase::ResetDecoder() { decoder_->Destroy(!decoder_->WasContextLost()); decoder_.reset(); group_->Destroy(mock_decoder_.get(), false); - engine_.reset(); + command_buffer_service_.reset(); ::gl::MockGLInterface::SetGLInterface(NULL); gl_.reset(); gl::init::ShutdownGL(); @@ -724,7 +724,7 @@ void GLES2DecoderTestBase::SetBucketData( if (data) { memcpy(shared_memory_address_, data, data_size); cmd::SetBucketData cmd2; - cmd2.Init(bucket_id, 0, data_size, kSharedMemoryId, kSharedMemoryOffset); + cmd2.Init(bucket_id, 0, data_size, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); ClearSharedMemory(); } @@ -765,7 +765,7 @@ void GLES2DecoderTestBase::SetBucketAsCStrings(uint32_t bucket_id, offset += 1; } cmd::SetBucketData cmd2; - cmd2.Init(bucket_id, 0, total_size, kSharedMemoryId, kSharedMemoryOffset); + cmd2.Init(bucket_id, 0, total_size, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); ClearSharedMemory(); } @@ -1597,7 +1597,6 @@ const GLuint GLES2DecoderTestBase::kServiceTransformFeedbackId; const GLuint GLES2DecoderTestBase::kServiceDefaultTransformFeedbackId; const GLuint GLES2DecoderTestBase::kServiceSyncId; -const int32_t GLES2DecoderTestBase::kSharedMemoryId; const size_t GLES2DecoderTestBase::kSharedBufferSize; const uint32_t GLES2DecoderTestBase::kSharedMemoryOffset; const int32_t GLES2DecoderTestBase::kInvalidSharedMemoryId; @@ -1904,8 +1903,7 @@ void GLES2DecoderTestBase::SetupShader( TestHelper::SetShaderStates(gl_.get(), GetShader(vertex_shader_client_id), true, nullptr, nullptr, &shader_language_version_, - nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr); + nullptr, nullptr, nullptr, nullptr, nullptr); OutputVariableList frag_output_variable_list; frag_output_variable_list.push_back(TestHelper::ConstructOutputVariable( @@ -1915,7 +1913,7 @@ void GLES2DecoderTestBase::SetupShader( TestHelper::SetShaderStates(gl_.get(), GetShader(fragment_shader_client_id), true, nullptr, nullptr, &shader_language_version_, nullptr, nullptr, nullptr, nullptr, - &frag_output_variable_list, nullptr); + &frag_output_variable_list); cmds::AttachShader attach_cmd; attach_cmd.Init(program_client_id, vertex_shader_client_id); @@ -2051,7 +2049,11 @@ void GLES2DecoderTestBase::SetupIndexBuffer() { void GLES2DecoderTestBase::SetupTexture() { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, - kSharedMemoryId, kSharedMemoryOffset); + shared_memory_id_, kSharedMemoryOffset); +}; + +void GLES2DecoderTestBase::SetupSampler() { + DoBindSampler(0, client_sampler_id_, kServiceSamplerId); }; void GLES2DecoderTestBase::DeleteVertexBuffer() { @@ -2137,50 +2139,33 @@ void GLES2DecoderTestBase::SetupInitStateManualExpectationsForDoLineWidth( EXPECT_CALL(*gl_, LineWidth(width)).Times(1).RetiresOnSaturation(); } -GLES2DecoderWithShaderTestBase::MockCommandBufferEngine:: -MockCommandBufferEngine() { - std::unique_ptr<base::SharedMemory> shm(new base::SharedMemory()); - shm->CreateAndMapAnonymous(kSharedBufferSize); - valid_buffer_ = MakeBufferFromSharedMemory(std::move(shm), kSharedBufferSize); - - ClearSharedMemory(); -} - -GLES2DecoderWithShaderTestBase::MockCommandBufferEngine:: -~MockCommandBufferEngine() {} - -scoped_refptr<gpu::Buffer> -GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::GetSharedMemoryBuffer( - int32_t shm_id) { - return shm_id == kSharedMemoryId ? valid_buffer_ : invalid_buffer_; -} - -void GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::set_token( - int32_t token) { - DCHECK(false); +void GLES2DecoderWithShaderTestBase::SetUp() { + GLES2DecoderTestBase::SetUp(); + SetupDefaultProgram(); } -bool GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::SetGetBuffer( - int32_t /* transfer_buffer_id */) { - DCHECK(false); - return false; -} +void GLES2DecoderTestBase::DoInitializeDiscardableTextureCHROMIUM( + GLuint texture_id) { + scoped_refptr<gpu::Buffer> buffer = + command_buffer_service_->GetTransferBuffer(shared_memory_id_); + ClientDiscardableHandle handle(buffer, 0, shared_memory_id_); -bool GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::SetGetOffset( - int32_t offset) { - DCHECK(false); - return false; + cmds::InitializeDiscardableTextureCHROMIUM cmd; + cmd.Init(texture_id, shared_memory_id_, 0); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } -int32_t -GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::GetGetOffset() { - DCHECK(false); - return 0; +void GLES2DecoderTestBase::DoUnlockDiscardableTextureCHROMIUM( + GLuint texture_id) { + cmds::UnlockDiscardableTextureCHROMIUM cmd; + cmd.Init(texture_id); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } -void GLES2DecoderWithShaderTestBase::SetUp() { - GLES2DecoderTestBase::SetUp(); - SetupDefaultProgram(); +void GLES2DecoderTestBase::DoLockDiscardableTextureCHROMIUM(GLuint texture_id) { + cmds::LockDiscardableTextureCHROMIUM cmd; + cmd.Init(texture_id); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } // Include the auto-generated part of this file. We split this because it means diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 45789ca0e45..038545f304c 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -11,10 +11,10 @@ #include <memory> #include "base/message_loop/message_loop.h" +#include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/buffer_manager.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/framebuffer_manager.h" #include "gpu/command_buffer/service/gl_context_mock.h" @@ -25,6 +25,7 @@ #include "gpu/command_buffer/service/query_manager.h" #include "gpu/command_buffer/service/renderbuffer_manager.h" #include "gpu/command_buffer/service/sampler_manager.h" +#include "gpu/command_buffer/service/service_discardable_manager.h" #include "gpu/command_buffer/service/shader_manager.h" #include "gpu/command_buffer/service/test_helper.h" #include "gpu/command_buffer/service/texture_manager.h" @@ -71,7 +72,7 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { } void ClearSharedMemory() { - engine_->ClearSharedMemory(); + memset(shared_memory_base_, kInitialMemoryValue, kSharedBufferSize); } void SetUp() override; @@ -81,16 +82,20 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { error::Error ExecuteCmd(const T& cmd) { static_assert(T::kArgFlags == cmd::kFixed, "T::kArgFlags should equal cmd::kFixed"); - return decoder_->DoCommands( - 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd)), 0); + int entries_processed = 0; + return decoder_->DoCommands(1, (const void*)&cmd, + ComputeNumEntries(sizeof(cmd)), + &entries_processed); } template <typename T> error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) { static_assert(T::kArgFlags == cmd::kAtLeastN, "T::kArgFlags should equal cmd::kAtLeastN"); - return decoder_->DoCommands( - 1, (const void*)&cmd, ComputeNumEntries(sizeof(cmd) + data_size), 0); + int entries_processed = 0; + return decoder_->DoCommands(1, (const void*)&cmd, + ComputeNumEntries(sizeof(cmd) + data_size), + &entries_processed); } template <typename T> @@ -109,7 +114,7 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { } Framebuffer* GetFramebuffer(GLuint client_id) { - return group_->framebuffer_manager()->GetFramebuffer(client_id); + return decoder_->GetFramebufferManager()->GetFramebuffer(client_id); } Renderbuffer* GetRenderbuffer(GLuint client_id) { @@ -163,6 +168,10 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { return group_->framebuffer_completeness_cache(); } + FramebufferManager* GetFramebufferManager() { + return decoder_->GetFramebufferManager(); + } + ImageManager* GetImageManager() { return decoder_->GetImageManager(); } void DoCreateProgram(GLuint client_id, GLuint service_id); @@ -217,6 +226,10 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { group_->LoseContexts(reason); } + error::ContextLostReason GetContextLostReason() const { + return command_buffer_service_->GetState().context_lost_reason; + } + ::testing::StrictMock<::gl::MockGLInterface>* GetGLMock() const { return gl_.get(); } @@ -250,6 +263,9 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { void SetupSamplerExternalProgram(); void SetupTexture(); + // Sets up a sampler on texture unit 0 for certain ES3-specific tests. + void SetupSampler(); + // Note that the error is returned as GLint instead of GLenum. // This is because there is a mismatch in the types of GLenum and // the error values GL_NO_ERROR, GL_INVALID_ENUM, etc. GLenum is @@ -465,13 +481,18 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { void AddExpectationsForBindVertexArrayOES(); void AddExpectationsForRestoreAttribState(GLuint attrib); + void DoInitializeDiscardableTextureCHROMIUM(GLuint texture_id); + void DoUnlockDiscardableTextureCHROMIUM(GLuint texture_id); + void DoLockDiscardableTextureCHROMIUM(GLuint texture_id); + bool IsDiscardableTextureUnlocked(GLuint texture_id); + GLvoid* BufferOffset(unsigned i) { return static_cast<int8_t*>(NULL) + (i); } template <typename Command, typename Result> bool IsObjectHelper(GLuint client_id) { Result* result = static_cast<Result*>(shared_memory_address_); Command cmd; - cmd.Init(client_id, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_id, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); bool isObject = static_cast<bool>(*result); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -516,10 +537,10 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { static const GLuint kServiceDefaultTransformFeedbackId = 312; static const GLuint kServiceSyncId = 313; - static const int32_t kSharedMemoryId = 401; static const size_t kSharedBufferSize = 2048; static const uint32_t kSharedMemoryOffset = 132; - static const int32_t kInvalidSharedMemoryId = 402; + static const int32_t kInvalidSharedMemoryId = + FakeCommandBufferServiceBase::kTransferBufferBaseId - 1; static const uint32_t kInvalidSharedMemoryOffset = kSharedBufferSize + 1; static const uint32_t kInitialResult = 0xBDBDBDBDu; static const uint8_t kInitialMemoryValue = 0xBDu; @@ -654,7 +675,7 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { GLuint client_transformfeedback_id_; GLuint client_sync_id_; - uint32_t shared_memory_id_; + int32_t shared_memory_id_; uint32_t shared_memory_offset_; void* shared_memory_address_; void* shared_memory_base_; @@ -691,33 +712,6 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { int shader_language_version_; private: - class MockCommandBufferEngine : public CommandBufferEngine { - public: - MockCommandBufferEngine(); - - ~MockCommandBufferEngine() override; - - scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32_t shm_id) override; - - void ClearSharedMemory() { - memset(valid_buffer_->memory(), kInitialMemoryValue, kSharedBufferSize); - } - - void set_token(int32_t token) override; - - bool SetGetBuffer(int32_t /* transfer_buffer_id */) override; - - // Overridden from CommandBufferEngine. - bool SetGetOffset(int32_t offset) override; - - // Overridden from CommandBufferEngine. - int32_t GetGetOffset() override; - - private: - scoped_refptr<gpu::Buffer> valid_buffer_; - scoped_refptr<gpu::Buffer> invalid_buffer_; - }; - // MockGLStates is used to track GL states and emulate driver // behaviors on top of MockGLInterface. class MockGLStates { @@ -759,8 +753,9 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { void SetupInitStateManualExpectations(bool es3_capable); void SetupInitStateManualExpectationsForDoLineWidth(GLfloat width); - std::unique_ptr<::testing::StrictMock<MockCommandBufferEngine>> engine_; + std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_; GpuPreferences gpu_preferences_; + ServiceDiscardableManager discardable_manager_; scoped_refptr<ContextGroup> group_; MockGLStates gl_states_; base::MessageLoop message_loop_; diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc index 15f477dc1e3..0403e95ac9f 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc @@ -108,9 +108,9 @@ TEST_P(GLES3DecoderTest, MapBufferRangeUnmapBufferReadSucceeds) { const GLsizeiptr kSize = 64; const GLbitfield kAccess = GL_MAP_READ_BIT; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); @@ -162,9 +162,9 @@ TEST_P(GLES3DecoderTest, MapBufferRangeUnmapBufferWriteSucceeds) { const GLbitfield kAccess = GL_MAP_WRITE_BIT; const GLbitfield kMappedAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); @@ -247,9 +247,9 @@ TEST_P(GLES3DecoderTest, FlushMappedBufferRangeSucceeds) { const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; const GLbitfield kMappedAccess = kAccess | GL_MAP_READ_BIT; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); @@ -357,9 +357,9 @@ TEST_P(GLES3DecoderTest, MapBufferRangeNotInitFails) { 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_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); MapBufferRange cmd; @@ -390,9 +390,9 @@ TEST_P(GLES3DecoderTest, MapBufferRangeWriteInvalidateRangeSucceeds) { typedef MapBufferRange::Result Result; Result* result = GetSharedMemoryAs<Result*>(); *result = 0; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); @@ -429,9 +429,9 @@ TEST_P(GLES3DecoderTest, MapBufferRangeWriteInvalidateBufferSucceeds) { typedef MapBufferRange::Result Result; Result* result = GetSharedMemoryAs<Result*>(); *result = 0; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); @@ -466,9 +466,9 @@ TEST_P(GLES3DecoderTest, MapBufferRangeWriteUnsynchronizedBit) { typedef MapBufferRange::Result Result; Result* result = GetSharedMemoryAs<Result*>(); *result = 0; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); @@ -494,9 +494,9 @@ TEST_P(GLES3DecoderTest, MapBufferRangeWithError) { typedef MapBufferRange::Result Result; Result* result = GetSharedMemoryAs<Result*>(); *result = 0; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); int8_t* mem = reinterpret_cast<int8_t*>(&result[1]); @@ -529,9 +529,9 @@ TEST_P(GLES3DecoderTest, MapBufferRangeBadSharedMemoryFails) { typedef MapBufferRange::Result Result; Result* result = GetSharedMemoryAs<Result*>(); *result = 0; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result); MapBufferRange cmd; @@ -580,9 +580,9 @@ TEST_P(GLES3DecoderTest, BufferDataDestroysDataStore) { const GLbitfield kAccess = GL_MAP_WRITE_BIT; const GLbitfield kFilteredAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); @@ -628,9 +628,9 @@ TEST_P(GLES3DecoderTest, DeleteBuffersDestroysDataStore) { const GLbitfield kAccess = GL_MAP_WRITE_BIT; const GLbitfield kFilteredAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); @@ -675,9 +675,9 @@ TEST_P(GLES3DecoderTest, MapUnmapBufferInvalidTarget) { const GLsizeiptr kSize = 64; const GLbitfield kAccess = GL_MAP_WRITE_BIT; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc index f6052949549..60d66be5bb3 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc @@ -8,7 +8,6 @@ #include "base/strings/string_number_conversions.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gl_surface_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" @@ -28,7 +27,7 @@ using ::testing::Pointee; using ::testing::Return; using ::testing::SaveArg; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::SetArgPointee; using ::testing::StrEq; using ::testing::StrictMock; @@ -78,7 +77,7 @@ TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonOOM) { Draw(GL_NO_ERROR, expected_reason_for_other_contexts); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); EXPECT_TRUE(decoder_->WasContextLost()); - EXPECT_EQ(error::kOutOfMemory, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kOutOfMemory, GetContextLostReason()); } TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonWhenStatusIsNoError) { @@ -89,7 +88,7 @@ TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonWhenStatusIsNoError) { Draw(GL_NO_ERROR, expected_reason_for_other_contexts); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); EXPECT_TRUE(decoder_->WasContextLost()); - EXPECT_EQ(error::kOutOfMemory, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kOutOfMemory, GetContextLostReason()); } TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonWhenStatusIsGuilty) { @@ -100,7 +99,7 @@ TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonWhenStatusIsGuilty) { Draw(GL_GUILTY_CONTEXT_RESET_ARB, expected_reason_for_other_contexts); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); EXPECT_TRUE(decoder_->WasContextLost()); - EXPECT_EQ(error::kGuilty, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kGuilty, GetContextLostReason()); } TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonWhenStatusIsUnknown) { @@ -111,7 +110,7 @@ TEST_P(GLES2DecoderDrawOOMTest, ContextLostReasonWhenStatusIsUnknown) { Draw(GL_UNKNOWN_CONTEXT_RESET_ARB, expected_reason_for_other_contexts); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); EXPECT_TRUE(decoder_->WasContextLost()); - EXPECT_EQ(error::kUnknown, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kUnknown, GetContextLostReason()); } INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderDrawOOMTest, ::testing::Bool()); @@ -168,7 +167,7 @@ TEST_P(GLES2DecoderLostContextTest, LostFromMakeCurrent) { EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)).Times(1); decoder_->MakeCurrent(); EXPECT_TRUE(decoder_->WasContextLost()); - EXPECT_EQ(error::kMakeCurrentFailed, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kMakeCurrentFailed, GetContextLostReason()); // We didn't process commands, so we need to clear the decoder error, // so that we can shut down cleanly. @@ -186,7 +185,7 @@ TEST_P(GLES2DecoderLostContextTest, LostFromMakeCurrentWithRobustness) { decoder_->MakeCurrent(); EXPECT_TRUE(decoder_->WasContextLost()); EXPECT_FALSE(decoder_->WasContextLostByRobustnessExtension()); - EXPECT_EQ(error::kMakeCurrentFailed, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kMakeCurrentFailed, GetContextLostReason()); // We didn't process commands, so we need to clear the decoder error, // so that we can shut down cleanly. @@ -204,7 +203,7 @@ TEST_P(GLES2DecoderLostContextTest, LostFromResetAfterMakeCurrent) { decoder_->MakeCurrent(); EXPECT_TRUE(decoder_->WasContextLost()); EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension()); - EXPECT_EQ(error::kGuilty, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kGuilty, GetContextLostReason()); // We didn't process commands, so we need to clear the decoder error, // so that we can shut down cleanly. @@ -220,7 +219,7 @@ TEST_P(GLES2DecoderLostContextTest, LoseGuiltyFromGLError) { DoGetErrorWithContextLost(GL_GUILTY_CONTEXT_RESET_KHR); EXPECT_TRUE(decoder_->WasContextLost()); EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension()); - EXPECT_EQ(error::kGuilty, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kGuilty, GetContextLostReason()); } TEST_P(GLES2DecoderLostContextTest, LoseInnocentFromGLError) { @@ -232,7 +231,7 @@ TEST_P(GLES2DecoderLostContextTest, LoseInnocentFromGLError) { DoGetErrorWithContextLost(GL_INNOCENT_CONTEXT_RESET_KHR); EXPECT_TRUE(decoder_->WasContextLost()); EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension()); - EXPECT_EQ(error::kInnocent, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kInnocent, GetContextLostReason()); } TEST_P(GLES2DecoderLostContextTest, LoseVirtualContextWithRobustness) { @@ -245,7 +244,7 @@ TEST_P(GLES2DecoderLostContextTest, LoseVirtualContextWithRobustness) { EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension()); // ...but make sure we don't pretend, since for virtual contexts we don't // know if this was really the guilty client. - EXPECT_EQ(error::kUnknown, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kUnknown, GetContextLostReason()); } TEST_P(GLES2DecoderLostContextTest, LoseGroupFromRobustness) { @@ -258,7 +257,7 @@ TEST_P(GLES2DecoderLostContextTest, LoseGroupFromRobustness) { EXPECT_CALL(*gl_, GetGraphicsResetStatusARB()).Times(0); LoseContexts(error::kUnknown); EXPECT_TRUE(decoder_->WasContextLost()); - EXPECT_EQ(error::kUnknown, decoder_->GetContextLostReason()); + EXPECT_EQ(error::kUnknown, GetContextLostReason()); // We didn't process commands, so we need to clear the decoder error, // so that we can shut down cleanly. diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc index 97136e1fc7f..6c629c2cadb 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc @@ -10,7 +10,6 @@ #include "base/strings/string_number_conversions.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/gl_surface_mock.h" @@ -42,7 +41,7 @@ using ::testing::Pointee; using ::testing::Return; using ::testing::SaveArg; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::SetArgPointee; using ::testing::StrEq; using ::testing::StrictMock; @@ -77,6 +76,10 @@ class GLES2DecoderRestoreStateTest : public GLES2DecoderManualInitTest { void InitializeContextState(ContextState* state, uint32_t non_default_unit, uint32_t active_unit); + + // ES3 specific. + scoped_refptr<FeatureInfo> SetupForES3Test(); + void AddExpectationsForBindSampler(GLuint unit, GLuint id); }; INSTANTIATE_TEST_CASE_P(Service, @@ -109,6 +112,30 @@ void GLES2DecoderRestoreStateTest::InitializeContextState( state->texture_units[tt].bound_texture_2d = ref_2d; } state->active_texture_unit = active_unit; + + // Set up the sampler units just for convenience of the ES3-specific + // tests in this file. + state->sampler_units.resize(group().max_texture_units()); +} + +scoped_refptr<FeatureInfo> GLES2DecoderRestoreStateTest::SetupForES3Test() { + InitState init; + init.gl_version = "OpenGL ES 3.0"; + init.context_type = CONTEXT_TYPE_OPENGLES3; + InitDecoder(init); + + // Construct a previous ContextState assuming an ES3 context and with all + // texture bindings set to default textures. + scoped_refptr<FeatureInfo> feature_info = new FeatureInfo; + TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( + gl_.get(), "", "", "OpenGL ES 3.0", CONTEXT_TYPE_OPENGLES3); + feature_info->InitializeForTesting(CONTEXT_TYPE_OPENGLES3); + return feature_info; +} + +void GLES2DecoderRestoreStateTest::AddExpectationsForBindSampler(GLuint unit, + GLuint id) { + EXPECT_CALL(*gl_, BindSampler(unit, id)).Times(1).RetiresOnSaturation(); } TEST_P(GLES2DecoderRestoreStateTest, NullPreviousStateBGR) { @@ -136,7 +163,7 @@ TEST_P(GLES2DecoderRestoreStateTest, NullPreviousStateBGR) { // Expect to restore the active texture unit to GL_TEXTURE0. AddExpectationsForActiveTexture(GL_TEXTURE0); - GetDecoder()->RestoreAllTextureUnitBindings(NULL); + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(NULL); } TEST_P(GLES2DecoderRestoreStateTest, NullPreviousState) { @@ -160,7 +187,7 @@ TEST_P(GLES2DecoderRestoreStateTest, NullPreviousState) { // Expect to restore the active texture unit to GL_TEXTURE0. AddExpectationsForActiveTexture(GL_TEXTURE0); - GetDecoder()->RestoreAllTextureUnitBindings(NULL); + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(NULL); } TEST_P(GLES2DecoderRestoreStateTest, WithPreviousStateBGR) { @@ -184,7 +211,7 @@ TEST_P(GLES2DecoderRestoreStateTest, WithPreviousStateBGR) { // Expect to restore active texture unit to GL_TEXTURE0. AddExpectationsForActiveTexture(GL_TEXTURE0); - GetDecoder()->RestoreAllTextureUnitBindings(&prev_state); + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state); } TEST_P(GLES2DecoderRestoreStateTest, WithPreviousState) { @@ -207,7 +234,7 @@ TEST_P(GLES2DecoderRestoreStateTest, WithPreviousState) { // Expect to restore active texture unit to GL_TEXTURE0. AddExpectationsForActiveTexture(GL_TEXTURE0); - GetDecoder()->RestoreAllTextureUnitBindings(&prev_state); + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state); } TEST_P(GLES2DecoderRestoreStateTest, ActiveUnit1) { @@ -237,7 +264,7 @@ TEST_P(GLES2DecoderRestoreStateTest, ActiveUnit1) { // Expect to restore active texture unit to GL_TEXTURE1. AddExpectationsForActiveTexture(GL_TEXTURE1); - GetDecoder()->RestoreAllTextureUnitBindings(&prev_state); + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state); } TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit0BGR) { @@ -275,7 +302,7 @@ TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit0BGR) { // Expect to restore active texture unit to GL_TEXTURE1. AddExpectationsForActiveTexture(GL_TEXTURE1); - GetDecoder()->RestoreAllTextureUnitBindings(&prev_state); + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state); } TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit1BGR) { @@ -307,7 +334,7 @@ TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit1BGR) { // Expect to restore active texture unit to GL_TEXTURE0. AddExpectationsForActiveTexture(GL_TEXTURE0); - GetDecoder()->RestoreAllTextureUnitBindings(&prev_state); + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state); } TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit0) { @@ -343,7 +370,7 @@ TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit0) { // Expect to restore active texture unit to GL_TEXTURE1. AddExpectationsForActiveTexture(GL_TEXTURE1); - GetDecoder()->RestoreAllTextureUnitBindings(&prev_state); + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state); } TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit1) { @@ -373,7 +400,88 @@ TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit1) { // Expect to restore active texture unit to GL_TEXTURE0. AddExpectationsForActiveTexture(GL_TEXTURE0); - GetDecoder()->RestoreAllTextureUnitBindings(&prev_state); + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state); +} + +TEST_P(GLES2DecoderRestoreStateTest, ES3NullPreviousStateWithSampler) { + // This ES3-specific test is scoped within GLES2DecoderRestoreStateTest + // to avoid doing large refactorings of these tests. + InitState init; + init.gl_version = "OpenGL ES 3.0"; + init.context_type = CONTEXT_TYPE_OPENGLES3; + InitDecoder(init); + SetupTexture(); + SetupSampler(); + + InSequence sequence; + // Expect to restore texture bindings for unit GL_TEXTURE0. + AddExpectationsForActiveTexture(GL_TEXTURE0); + AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId); + AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0); + // Expect to restore sampler binding for unit GL_TEXTURE0. + AddExpectationsForBindSampler(0, kServiceSamplerId); + + // Expect to restore texture bindings for remaining units. + for (uint32_t i = 1; i < group().max_texture_units(); ++i) { + AddExpectationsForActiveTexture(GL_TEXTURE0 + i); + AddExpectationsForBindTexture(GL_TEXTURE_2D, 0); + AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0); + AddExpectationsForBindSampler(i, 0); + } + + // Expect to restore the active texture unit to GL_TEXTURE0. + AddExpectationsForActiveTexture(GL_TEXTURE0); + + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(NULL); +} + +TEST_P(GLES2DecoderRestoreStateTest, ES3RestoreExistingSampler) { + // This ES3-specific test is scoped within GLES2DecoderRestoreStateTest + // to avoid doing large refactorings of these tests. + auto feature_info = SetupForES3Test(); + SetupSampler(); + + // Construct a previous ContextState assuming an ES3 context and with all + // texture bindings set to default textures. + ContextState prev_state(feature_info.get(), NULL, NULL); + InitializeContextState(&prev_state, std::numeric_limits<uint32_t>::max(), 0); + + InSequence sequence; + // Expect to restore sampler binding for unit GL_TEXTURE0. + AddExpectationsForBindSampler(0, kServiceSamplerId); + + // Expect to restore the active texture unit to GL_TEXTURE0. + AddExpectationsForActiveTexture(GL_TEXTURE0); + + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state); +} + +TEST_P(GLES2DecoderRestoreStateTest, ES3RestoreZeroSampler) { + // This ES3-specific test is scoped within GLES2DecoderRestoreStateTest + // to avoid doing large refactorings of these tests. + auto feature_info = SetupForES3Test(); + + // Construct a previous ContextState assuming an ES3 context and with all + // texture bindings set to default textures. + SamplerManager sampler_manager(feature_info.get()); + ContextState prev_state(feature_info.get(), NULL, NULL); + InitializeContextState(&prev_state, std::numeric_limits<uint32_t>::max(), 0); + // Set up a sampler in the previous state. The client_id and service_id + // don't matter except that they're non-zero. + prev_state.sampler_units[0] = new Sampler(&sampler_manager, 1, 2); + + InSequence sequence; + // Expect to restore the zero sampler on unit GL_TEXTURE0. + AddExpectationsForBindSampler(0, 0); + + // Expect to restore the active texture unit to GL_TEXTURE0. + AddExpectationsForActiveTexture(GL_TEXTURE0); + + GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state); + + // Tell the sampler manager to destroy itself without a context so we + // don't have to set up more expectations. + sampler_manager.Destroy(false); } TEST_P(GLES2DecoderManualInitTest, ContextStateCapabilityCaching) { diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc index 7d61f120de4..a657fd51cf2 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc @@ -10,7 +10,6 @@ #include "base/strings/string_number_conversions.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/gl_surface_mock.h" @@ -42,7 +41,7 @@ using ::testing::Pointee; using ::testing::Return; using ::testing::SaveArg; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::SetArgPointee; using ::testing::StrEq; using ::testing::StrictMock; @@ -318,21 +317,13 @@ TEST_P(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) { const GLenum kFormat = GL_RGB; // Use a different texture for framebuffer to avoid drawing feedback loops. EXPECT_CALL(*gl_, GenTextures(_, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)) + .WillOnce(SetArgPointee<1>(kNewServiceId)) .RetiresOnSaturation(); GenHelper<GenTexturesImmediate>(kNewClientId); DoBindTexture(GL_TEXTURE_2D, kNewClientId, kNewServiceId); // Pass some data so the texture will be marked as cleared. - DoTexImage2D(GL_TEXTURE_2D, - 0, - kFormat, - kWidth, - kHeight, - 0, - kFormat, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0, kFormat, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_FRAMEBUFFER, @@ -742,16 +733,8 @@ TEST_P(GLES2DecoderWithShaderTest, DrawArraysBadTextureUsesBlack) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); // This is an NPOT texture. As the default filtering requires mips // this should trigger replacing with black textures before rendering. - DoTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - 3, - 1, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); AddExpectationsForSimulatedAttrib0(kNumVertices, 0); { InSequence sequence; @@ -1912,7 +1895,7 @@ TEST_P(GLES2DecoderWithShaderTest, DrawClearsAfterTexImage2DNULLInFBO) { SetupAllNeededVertexBuffers(); // Register a texture id. EXPECT_CALL(*gl_, GenTextures(_, _)) - .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId)) + .WillOnce(SetArgPointee<1>(kFBOServiceTextureId)) .RetiresOnSaturation(); GenHelper<GenTexturesImmediate>(kFBOClientTextureId); @@ -1976,7 +1959,7 @@ TEST_P(GLES2DecoderWithShaderTest, DrawWitFBOThatCantClearDoesNotDraw) { // Register a texture id. EXPECT_CALL(*gl_, GenTextures(_, _)) - .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId)) + .WillOnce(SetArgPointee<1>(kFBOServiceTextureId)) .RetiresOnSaturation(); GenHelper<GenTexturesImmediate>(kFBOClientTextureId); @@ -2073,7 +2056,7 @@ TEST_P(GLES2DecoderManualInitTest, DrawArraysClearsAfterTexImage2DNULLCubemap) { for (int ii = 0; ii < 6; ++ii) { GLenum face = faces[ii]; int32_t shm_id = - (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : kSharedMemoryId; + (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : shared_memory_id_; uint32_t shm_offset = (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : kSharedMemoryOffset; DoTexImage2D(face, @@ -2123,7 +2106,7 @@ TEST_P(GLES2DecoderWithShaderTest, // Register a texture id. EXPECT_CALL(*gl_, GenTextures(_, _)) - .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId)) + .WillOnce(SetArgPointee<1>(kFBOServiceTextureId)) .RetiresOnSaturation(); GenHelper<GenTexturesImmediate>(kFBOClientTextureId); @@ -2199,22 +2182,14 @@ TEST_P(GLES2DecoderWithShaderTest, // Register a texture id. EXPECT_CALL(*gl_, GenTextures(_, _)) - .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId)) + .WillOnce(SetArgPointee<1>(kFBOServiceTextureId)) .RetiresOnSaturation(); GenHelper<GenTexturesImmediate>(kFBOClientTextureId); // Setup "render to" texture that is cleared. DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - 1, - 1, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_FRAMEBUFFER, diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc index bb398143f34..7e080f10005 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc @@ -589,7 +589,7 @@ TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, GenDeletePaths) { EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); - delete_cmd.Init(std::numeric_limits<GLsizei>::max() + 1, + delete_cmd.Init(static_cast<GLuint>(std::numeric_limits<GLsizei>::max()) + 1, std::numeric_limits<GLsizei>::max()); EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -775,7 +775,7 @@ TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, EXPECT_EQ(GL_NO_ERROR, GetGLError()); // Too big range causes client id to wrap, connection error. - gen_cmd.Init(std::numeric_limits<GLsizei>::max() + 3, + gen_cmd.Init(static_cast<GLuint>(std::numeric_limits<GLsizei>::max()) + 3, std::numeric_limits<GLsizei>::max()); EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -819,7 +819,7 @@ TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); // Too big range causes client id to wrap, connection error. - delete_cmd.Init(std::numeric_limits<GLsizei>::max() + 3, + delete_cmd.Init(static_cast<GLuint>(std::numeric_limits<GLsizei>::max()) + 3, std::numeric_limits<GLsizei>::max()); EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(delete_cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc index 0fc0769ee50..91f06007b9c 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc @@ -15,7 +15,6 @@ #include "base/strings/string_number_conversions.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/gl_surface_mock.h" @@ -592,16 +591,8 @@ void GLES2DecoderTest::CheckReadPixelsOutOfRange(GLint in_read_x, // access if (init) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - 0, - kFormat, - kWidth, - kHeight, - 0, - kFormat, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0, kFormat, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_FRAMEBUFFER, @@ -620,9 +611,9 @@ void GLES2DecoderTest::CheckReadPixelsOutOfRange(GLint in_read_x, kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment); typedef ReadPixels::Result Result; Result* result = GetSharedMemoryAs<Result*>(); - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result); void* dest = &result[1]; @@ -725,9 +716,9 @@ TEST_P(GLES2DecoderTest, ReadPixels) { kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment); typedef ReadPixels::Result Result; Result* result = GetSharedMemoryAs<Result*>(); - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result); void* dest = &result[1]; EXPECT_CALL(*gl_, GetError()) @@ -788,9 +779,9 @@ TEST_P(GLES3DecoderTest, ReadPixelsBufferBound) { EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0); typedef ReadPixels::Result Result; Result* result = GetSharedMemoryAs<Result*>(); - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); DoBindBuffer(GL_PIXEL_PACK_BUFFER, client_buffer_id_, kServiceBufferId); @@ -854,9 +845,9 @@ TEST_P(GLES3DecoderTest, ReadPixelsPixelPackBufferMapped) { std::vector<int8_t> mapped_data(size); - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t data_shm_id = kSharedMemoryId; + uint32_t data_shm_id = shared_memory_id_; // uint32_t is Result for both MapBufferRange and UnmapBuffer commands. uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t); EXPECT_CALL(*gl_, @@ -1112,9 +1103,9 @@ TEST_P(GLES2DecoderRGBBackbufferTest, ReadPixelsNoAlphaBackbuffer) { kPackAlignment); typedef ReadPixels::Result Result; Result* result = GetSharedMemoryAs<Result*>(); - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result); void* dest = &result[1]; EXPECT_CALL(*gl_, GetError()) @@ -1178,9 +1169,9 @@ TEST_P(GLES2DecoderTest, ReadPixelsOutOfRange) { TEST_P(GLES2DecoderTest, ReadPixelsInvalidArgs) { typedef ReadPixels::Result Result; Result* result = GetSharedMemoryAs<Result*>(); - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0); ReadPixels cmd; @@ -1292,9 +1283,9 @@ TEST_P(GLES2DecoderManualInitTest, ReadPixelsAsyncError) { Result* result = GetSharedMemoryAs<Result*>(); const GLsizei kWidth = 4; const GLsizei kHeight = 4; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); EXPECT_CALL(*gl_, GetError()) @@ -1402,9 +1393,9 @@ TEST_P(GLES2ReadPixelsAsyncTest, ReadPixelsAsync) { Result* result = GetSharedMemoryAs<Result*>(); const GLsizei kWidth = 4; const GLsizei kHeight = 4; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); char* pixels = reinterpret_cast<char*>(result + 1); @@ -1431,9 +1422,9 @@ TEST_P(GLES2ReadPixelsAsyncTest, ReadPixelsAsyncModifyCommand) { Result* result = GetSharedMemoryAs<Result*>(); const GLsizei kWidth = 4; const GLsizei kHeight = 4; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); char* pixels = reinterpret_cast<char*>(result + 1); @@ -1460,9 +1451,9 @@ TEST_P(GLES2ReadPixelsAsyncTest, ReadPixelsAsyncChangePackAlignment) { Result* result = GetSharedMemoryAs<Result*>(); const GLsizei kWidth = 1; const GLsizei kHeight = 4; - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); char* pixels = reinterpret_cast<char*>(result + 1); @@ -2121,8 +2112,7 @@ TEST_P(GLES3DecoderTest, ClearBufferivImmediateValidArgs) { // TODO(zmo): Set up expectations for the path where the attachment isn't // marked as cleared. - Framebuffer* framebuffer = - group().framebuffer_manager()->GetFramebuffer(client_framebuffer_id_); + Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_); framebuffer->MarkAttachmentAsCleared( group().renderbuffer_manager(), nullptr, GL_COLOR_ATTACHMENT0, true); @@ -2153,8 +2143,7 @@ TEST_P(GLES3DecoderTest, ClearBufferuivImmediateValidArgs) { // TODO(zmo): Set up expectations for the path where the attachment isn't // marked as cleared. - Framebuffer* framebuffer = - group().framebuffer_manager()->GetFramebuffer(client_framebuffer_id_); + Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_); framebuffer->MarkAttachmentAsCleared( group().renderbuffer_manager(), nullptr, GL_COLOR_ATTACHMENT0, true); @@ -2186,8 +2175,7 @@ TEST_P(GLES3DecoderTest, ClearBufferfvImmediateValidArgs) { // TODO(zmo): Set up expectations for the path where the attachment isn't // marked as cleared. - Framebuffer* framebuffer = - group().framebuffer_manager()->GetFramebuffer(client_framebuffer_id_); + Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_); framebuffer->MarkAttachmentAsCleared( group().renderbuffer_manager(), nullptr, GL_DEPTH_ATTACHMENT, true); @@ -2224,8 +2212,7 @@ TEST_P(GLES3DecoderTest, ClearBufferfiValidArgs) { // TODO(zmo): Set up expectations for the path where the attachment isn't // marked as cleared. - Framebuffer* framebuffer = - group().framebuffer_manager()->GetFramebuffer(client_framebuffer_id_); + Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_); framebuffer->MarkAttachmentAsCleared(group().renderbuffer_manager(), nullptr, GL_DEPTH_ATTACHMENT, true); framebuffer->MarkAttachmentAsCleared(group().renderbuffer_manager(), nullptr, @@ -2481,9 +2468,9 @@ TEST_P(GLES2DecoderTest, ReadPixelsGLError) { GLsizei height = 4; typedef ReadPixels::Result Result; Result* result = GetSharedMemoryAs<Result*>(); - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); EXPECT_CALL(*gl_, GetError()) .WillOnce(Return(GL_NO_ERROR)) @@ -2614,9 +2601,9 @@ TEST_P(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnReadPixels) { .RetiresOnSaturation(); typedef ReadPixels::Result Result; Result* result = GetSharedMemoryAs<Result*>(); - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); ReadPixels cmd; cmd.Init(0, @@ -2654,16 +2641,8 @@ TEST_P(GLES3DecoderTest, CopyTexImage2DValidInternalFormat) { GenHelper<GenTexturesImmediate>(kFBOClientTextureId); DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - level, - internal_format, - width, - height, - 0, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, level, internal_format, width, height, 0, format, + type, shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_READ_FRAMEBUFFER, @@ -2720,16 +2699,8 @@ TEST_P(GLES3DecoderManualInitTest, CopyTexImage2DValidInternalFormat_FloatEXT) { GenHelper<GenTexturesImmediate>(kFBOClientTextureId); DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - level, - GL_RGBA16F, - width, - height, - 0, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, level, GL_RGBA16F, width, height, 0, format, type, + shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_READ_FRAMEBUFFER, @@ -2785,16 +2756,8 @@ TEST_P(GLES3DecoderManualInitTest, GenHelper<GenTexturesImmediate>(kFBOClientTextureId); DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - level, - GL_RGBA8, - width, - height, - 0, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, width, height, 0, format, type, + shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_READ_FRAMEBUFFER, @@ -2837,16 +2800,8 @@ TEST_P(GLES3DecoderTest, CopyTexImage2DInvalidInternalFormat) { GenHelper<GenTexturesImmediate>(kFBOClientTextureId); DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - level, - GL_RG8, - width, - height, - 0, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, level, GL_RG8, width, height, 0, format, type, + shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_READ_FRAMEBUFFER, @@ -2886,16 +2841,8 @@ TEST_P(GLES3DecoderTest, CopyTexImage2DInvalidInternalFormat_Float) { GenHelper<GenTexturesImmediate>(kFBOClientTextureId); DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - level, - GL_RGBA8, - width, - height, - 0, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, width, height, 0, format, type, + shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_READ_FRAMEBUFFER, @@ -2938,16 +2885,8 @@ TEST_P(GLES3DecoderTest, CopyTexImage2DInvalidInternalFormat_Integer) { GenHelper<GenTexturesImmediate>(kFBOClientTextureId); DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - level, - GL_RG8UI, - width, - height, - 0, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, level, GL_RG8UI, width, height, 0, format, type, + shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_READ_FRAMEBUFFER, @@ -2990,16 +2929,8 @@ TEST_P(GLES3DecoderTest, CopyTexImage2DInvalidInternalFormat_sRGB) { GenHelper<GenTexturesImmediate>(kFBOClientTextureId); DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - level, - GL_RGB, - width, - height, - 0, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, level, GL_RGB, width, height, 0, format, type, + shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_READ_FRAMEBUFFER, @@ -3078,9 +3009,9 @@ TEST_P(GLES2DecoderManualInitTest, .RetiresOnSaturation(); typedef ReadPixels::Result Result; Result* result = GetSharedMemoryAs<Result*>(); - uint32_t result_shm_id = kSharedMemoryId; + uint32_t result_shm_id = shared_memory_id_; uint32_t result_shm_offset = kSharedMemoryOffset; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); ReadPixels cmd; cmd.Init(0, @@ -3129,7 +3060,7 @@ TEST_P(GLES2DecoderWithShaderTest, CopyTexImageWithInCompleteFBOFails) { void GLES2DecoderWithShaderTest::CheckRenderbufferChangesMarkFBOAsNotComplete( bool bound_fbo) { - FramebufferManager* framebuffer_manager = group().framebuffer_manager(); + FramebufferManager* framebuffer_manager = GetFramebufferManager(); SetupTexture(); DoBindRenderbuffer( GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId); @@ -3189,7 +3120,7 @@ TEST_P(GLES2DecoderWithShaderTest, void GLES2DecoderWithShaderTest::CheckTextureChangesMarkFBOAsNotComplete( bool bound_fbo) { - FramebufferManager* framebuffer_manager = group().framebuffer_manager(); + FramebufferManager* framebuffer_manager = GetFramebufferManager(); const GLuint kFBOClientTextureId = 4100; const GLuint kFBOServiceTextureId = 4101; @@ -3465,7 +3396,7 @@ TEST_P(GLES2DecoderManualInitTest, DiscardFramebufferEXT) { kServiceTextureId, 0, GL_NO_ERROR); - FramebufferManager* framebuffer_manager = group().framebuffer_manager(); + FramebufferManager* framebuffer_manager = GetFramebufferManager(); Framebuffer* framebuffer = framebuffer_manager->GetFramebuffer(client_framebuffer_id_); EXPECT_TRUE(framebuffer->IsCleared()); @@ -3571,7 +3502,7 @@ TEST_P(GLES3DecoderTest, DiscardFramebufferEXTInvalidTarget) { kServiceTextureId, 0, GL_NO_ERROR); - FramebufferManager* framebuffer_manager = group().framebuffer_manager(); + FramebufferManager* framebuffer_manager = GetFramebufferManager(); Framebuffer* framebuffer = framebuffer_manager->GetFramebuffer(client_framebuffer_id_); EXPECT_TRUE(framebuffer->IsCleared()); @@ -3612,7 +3543,7 @@ TEST_P(GLES3DecoderTest, DiscardFramebufferEXTUseCorrectTarget) { .RetiresOnSaturation(); DoBindTexture(GL_TEXTURE_2D, client_texture_id_ + 1, kServiceTextureId + 1); DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, - kSharedMemoryId, kSharedMemoryOffset); + shared_memory_id_, kSharedMemoryOffset); DoFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, @@ -3621,7 +3552,7 @@ TEST_P(GLES3DecoderTest, DiscardFramebufferEXTUseCorrectTarget) { 0, GL_NO_ERROR); - FramebufferManager* framebuffer_manager = group().framebuffer_manager(); + FramebufferManager* framebuffer_manager = GetFramebufferManager(); Framebuffer* framebuffer = framebuffer_manager->GetFramebuffer(client_framebuffer_id_); EXPECT_TRUE(framebuffer->IsCleared()); @@ -3705,7 +3636,7 @@ TEST_P(GLES2DecoderManualInitTest, EXPECT_EQ(GL_NO_ERROR, GetGLError()); // Check that framebuffer is cleared and complete. - FramebufferManager* framebuffer_manager = group().framebuffer_manager(); + FramebufferManager* framebuffer_manager = GetFramebufferManager(); Framebuffer* framebuffer = framebuffer_manager->GetFramebuffer(client_framebuffer_id_); EXPECT_TRUE(framebuffer->IsCleared()); @@ -3739,9 +3670,8 @@ TEST_P(GLES2DecoderManualInitTest, TEST_P(GLES2DecoderTest, ImplementationReadColorFormatAndType) { ClearSharedMemory(); DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - DoTexImage2D( - GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, - kSharedMemoryId, kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); DoBindFramebuffer( GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); DoFramebufferTexture2D(GL_FRAMEBUFFER, @@ -3849,8 +3779,7 @@ TEST_P(GLES3DecoderTest, InvalidateFramebufferDepthStencilAttachment) { GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR); - Framebuffer* framebuffer = - group().framebuffer_manager()->GetFramebuffer(client_framebuffer_id_); + Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_); ASSERT_TRUE(framebuffer); ASSERT_FALSE(framebuffer->GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT)); ASSERT_TRUE(framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT)); diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc index b80fbc0f32f..cdfd539ba8b 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc @@ -11,7 +11,6 @@ #include "base/strings/string_number_conversions.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/gl_surface_mock.h" @@ -208,9 +207,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformivSucceeds) { static_cast<GetUniformiv::Result*>(shared_memory_address_); result->size = 0; GetUniformiv cmd; - cmd.Init(client_program_id_, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformiv(kServiceProgramId, kUniform2RealLocation, _)) .Times(1); @@ -224,9 +221,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformivArrayElementSucceeds) { static_cast<GetUniformiv::Result*>(shared_memory_address_); result->size = 0; GetUniformiv cmd; - cmd.Init(client_program_id_, - kUniform2ElementFakeLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kUniform2ElementFakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformiv(kServiceProgramId, kUniform2ElementRealLocation, _)) @@ -242,9 +237,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) { result->size = 0; GetUniformiv cmd; // non-existant program - cmd.Init(kInvalidClientId, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(kInvalidClientId, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformiv(_, _, _)).Times(0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -254,9 +247,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) { // this case. #if GLES2_TEST_SHADER_VS_PROGRAM_IDS result->size = kInitialResult; - cmd.Init(client_shader_id_, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(client_shader_id_, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0U, result->size); @@ -271,9 +262,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) { cmd2.Init(kNewClientId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); result->size = kInitialResult; - cmd.Init(kNewClientId, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(kNewClientId, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0U, result->size); @@ -286,9 +275,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadLocationFails) { result->size = 0; GetUniformiv cmd; // invalid location - cmd.Init(client_program_id_, - kInvalidUniformLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kInvalidUniformLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformiv(_, _, _)).Times(0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -304,9 +291,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadSharedMemoryFails) { kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformiv(_, _, _)).Times(0); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(client_program_id_, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kUniform2FakeLocation, shared_memory_id_, kInvalidSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); }; @@ -316,9 +301,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformuivSucceeds) { static_cast<GetUniformuiv::Result*>(shared_memory_address_); result->size = 0; GetUniformuiv cmd; - cmd.Init(client_program_id_, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformuiv(kServiceProgramId, kUniform2RealLocation, _)) .Times(1); @@ -332,9 +315,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformuivArrayElementSucceeds) { static_cast<GetUniformuiv::Result*>(shared_memory_address_); result->size = 0; GetUniformuiv cmd; - cmd.Init(client_program_id_, - kUniform2ElementFakeLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kUniform2ElementFakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformuiv(kServiceProgramId, kUniform2ElementRealLocation, _)) @@ -350,9 +331,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformuivBadProgramFails) { result->size = 0; GetUniformuiv cmd; // non-existant program - cmd.Init(kInvalidClientId, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(kInvalidClientId, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformuiv(_, _, _)).Times(0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -362,9 +341,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformuivBadProgramFails) { // this case. #if GLES2_TEST_SHADER_VS_PROGRAM_IDS result->size = kInitialResult; - cmd.Init(client_shader_id_, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(client_shader_id_, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0U, result->size); @@ -379,9 +356,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformuivBadProgramFails) { cmd2.Init(kNewClientId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); result->size = kInitialResult; - cmd.Init(kNewClientId, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(kNewClientId, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0U, result->size); @@ -394,9 +369,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformuivBadLocationFails) { result->size = 0; GetUniformuiv cmd; // invalid location - cmd.Init(client_program_id_, - kInvalidUniformLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kInvalidUniformLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformuiv(_, _, _)).Times(0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -412,9 +385,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformuivBadSharedMemoryFails) { kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformuiv(_, _, _)).Times(0); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(client_program_id_, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kUniform2FakeLocation, shared_memory_id_, kInvalidSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); }; @@ -424,9 +395,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) { static_cast<GetUniformfv::Result*>(shared_memory_address_); result->size = 0; GetUniformfv cmd; - cmd.Init(client_program_id_, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformfv(kServiceProgramId, kUniform2RealLocation, _)) .Times(1); @@ -440,9 +409,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformfvArrayElementSucceeds) { static_cast<GetUniformfv::Result*>(shared_memory_address_); result->size = 0; GetUniformfv cmd; - cmd.Init(client_program_id_, - kUniform2ElementFakeLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kUniform2ElementFakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformfv(kServiceProgramId, kUniform2ElementRealLocation, _)) @@ -458,9 +425,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) { result->size = 0; GetUniformfv cmd; // non-existant program - cmd.Init(kInvalidClientId, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(kInvalidClientId, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformfv(_, _, _)).Times(0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -470,9 +435,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) { // this case. #if GLES2_TEST_SHADER_VS_PROGRAM_IDS result->size = kInitialResult; - cmd.Init(client_shader_id_, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(client_shader_id_, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0U, result->size); @@ -487,9 +450,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) { cmd2.Init(kNewClientId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); result->size = kInitialResult; - cmd.Init(kNewClientId, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(kNewClientId, kUniform2FakeLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0U, result->size); @@ -502,9 +463,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadLocationFails) { result->size = 0; GetUniformfv cmd; // invalid location - cmd.Init(client_program_id_, - kInvalidUniformLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kInvalidUniformLocation, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformfv(_, _, _)).Times(0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -520,9 +479,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadSharedMemoryFails) { kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformfv(_, _, _)).Times(0); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(client_program_id_, - kUniform2FakeLocation, - kSharedMemoryId, + cmd.Init(client_program_id_, kUniform2FakeLocation, shared_memory_id_, kInvalidSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); }; @@ -1130,9 +1087,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformIndicesSucceeds) { GetUniformIndices::Result* result = static_cast<GetUniformIndices::Result*>(shared_memory_address_); GetUniformIndices cmd; - cmd.Init(client_program_id_, - kBucketId, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformIndices(kServiceProgramId, kCount, _, _)) .WillOnce(SetArrayArgument<3>(kIndices, kIndices + kCount)) @@ -1165,10 +1120,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformIndicesBadProgramFails) { static_cast<GetUniformIndices::Result*>(shared_memory_address_); GetUniformIndices cmd; // None-existant program - cmd.Init(kInvalidClientId, - kBucketId, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(kInvalidClientId, kBucketId, shared_memory_id_, kSharedMemoryOffset); result->size = 0; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0, result->GetNumResults()); @@ -1177,9 +1129,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformIndicesBadProgramFails) { EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) .WillOnce(SetArgPointee<2>(GL_FALSE)) .RetiresOnSaturation(); - cmd.Init(client_program_id_, - kBucketId, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, kSharedMemoryOffset); result->size = 0; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1199,9 +1149,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformIndicesBadParamsFails) { GetUniformIndices::Result* result = static_cast<GetUniformIndices::Result*>(shared_memory_address_); GetUniformIndices cmd; - cmd.Init(client_program_id_, - kBucketId, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformIndices(kServiceProgramId, kCount, _, _)) .WillOnce(SetArrayArgument<3>(kIndices, kIndices + kCount)) @@ -1231,10 +1179,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformIndicesResultNotInitFails) { static_cast<GetUniformIndices::Result*>(shared_memory_address_); GetUniformIndices cmd; result->size = 1976; // Any value other than 0. - cmd.Init(kInvalidClientId, - kBucketId, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(kInvalidClientId, kBucketId, shared_memory_id_, kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } @@ -1255,9 +1200,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformIndicesBadSharedMemoryFails) { kSharedMemoryOffset); result->size = 0; EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(client_program_id_, - kBucketId, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, kInvalidSharedMemoryOffset); result->size = 0; EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); @@ -1272,10 +1215,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetActiveUniformsivSucceeds) { GetActiveUniformsiv::Result* result = static_cast<GetActiveUniformsiv::Result*>(shared_memory_address_); GetActiveUniformsiv cmd; - cmd.Init(client_program_id_, - kBucketId, - GL_UNIFORM_TYPE, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, GL_UNIFORM_TYPE, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetActiveUniformsiv( @@ -1303,20 +1243,14 @@ TEST_P(GLES3DecoderWithShaderTest, GetActiveUniformsivBadProgramFails) { static_cast<GetActiveUniformsiv::Result*>(shared_memory_address_); GetActiveUniformsiv cmd; // None-existant program - cmd.Init(kInvalidClientId, - kBucketId, - GL_UNIFORM_TYPE, - kSharedMemoryId, + cmd.Init(kInvalidClientId, kBucketId, GL_UNIFORM_TYPE, shared_memory_id_, kSharedMemoryOffset); result->size = 0; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0, result->GetNumResults()); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); // Unlinked program. - cmd.Init(client_program_id_, - kBucketId, - GL_UNIFORM_TYPE, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, GL_UNIFORM_TYPE, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) .WillOnce(SetArgPointee<2>(GL_FALSE)) @@ -1335,10 +1269,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetActiveUniformsivBadParamsFails) { GetActiveUniformsiv::Result* result = static_cast<GetActiveUniformsiv::Result*>(shared_memory_address_); GetActiveUniformsiv cmd; - cmd.Init(client_program_id_, - kBucketId, - GL_UNIFORM_TYPE, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, GL_UNIFORM_TYPE, shared_memory_id_, kSharedMemoryOffset); result->size = 0; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1355,20 +1286,14 @@ TEST_P(GLES3DecoderWithShaderTest, GetActiveUniformsivBadPnameFails) { static_cast<GetActiveUniformsiv::Result*>(shared_memory_address_); GetActiveUniformsiv cmd; // GL_UNIFORM_BLOCK_NAME_LENGTH should not be supported. - cmd.Init(client_program_id_, - kBucketId, - GL_UNIFORM_BLOCK_NAME_LENGTH, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, GL_UNIFORM_BLOCK_NAME_LENGTH, + shared_memory_id_, kSharedMemoryOffset); result->size = 0; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(0, result->GetNumResults()); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); // Invalid pname - cmd.Init(client_program_id_, - kBucketId, - 1, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, 1, shared_memory_id_, kSharedMemoryOffset); result->size = 0; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1384,10 +1309,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetActiveUniformsivResultNotInitFails) { GetActiveUniformsiv::Result* result = static_cast<GetActiveUniformsiv::Result*>(shared_memory_address_); GetActiveUniformsiv cmd; - cmd.Init(client_program_id_, - kBucketId, - GL_UNIFORM_TYPE, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, GL_UNIFORM_TYPE, shared_memory_id_, kSharedMemoryOffset); result->size = 1976; // Any value other than 0. EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); @@ -1409,10 +1331,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetActiveUniformsivBadSharedMemoryFails) { kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); result->size = 0; - cmd.Init(client_program_id_, - kBucketId, - GL_UNIFORM_TYPE, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, GL_UNIFORM_TYPE, shared_memory_id_, kInvalidSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } @@ -1620,8 +1539,8 @@ TEST_P(GLES2DecoderTest, CompileShaderValidArgs) { static_cast<GetShaderiv::Result*>(shared_memory_address_); result->size = 0; GetShaderiv status_cmd; - status_cmd.Init(client_shader_id_, GL_COMPILE_STATUS, - kSharedMemoryId, kSharedMemoryOffset); + status_cmd.Init(client_shader_id_, GL_COMPILE_STATUS, shared_memory_id_, + kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(status_cmd)); EXPECT_EQ(GL_TRUE, *result->GetData()); } @@ -1902,12 +1821,14 @@ TEST_P(GLES2DecoderWithShaderTest, GetAttribLocation) { SetBucketAsCString(kBucketId, kAttrib2Name); *result = -1; GetAttribLocation cmd; - cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, + kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(kAttrib2Location, *result); SetBucketAsCString(kBucketId, kNonExistentName); *result = -1; - cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, + kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(-1, *result); } @@ -1919,12 +1840,13 @@ TEST_P(GLES2DecoderWithShaderTest, GetAttribLocationInvalidArgs) { *result = -1; GetAttribLocation cmd; // Check no bucket - cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, + kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(-1, *result); // Check bad program id. SetBucketAsCString(kBucketId, kAttrib2Name); - cmd.Init(kInvalidClientId, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(kInvalidClientId, kBucketId, shared_memory_id_, kSharedMemoryOffset); *result = -1; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(-1, *result); @@ -1935,9 +1857,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetAttribLocationInvalidArgs) { kInvalidSharedMemoryId, kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(client_program_id_, - kBucketId, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, kInvalidSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } @@ -1949,7 +1869,8 @@ TEST_P(GLES3DecoderWithShaderTest, GetFragDataLocation) { SetBucketAsCString(kBucketId, kOutputVariable1NameESSL3); *result = -1; GetFragDataLocation cmd; - cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, + kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(static_cast<GLint>(kOutputVariable1ColorName), *result); } @@ -1961,13 +1882,14 @@ TEST_P(GLES3DecoderWithShaderTest, GetFragDataLocationInvalidArgs) { *result = -1; GetFragDataLocation cmd; // Check no bucket - cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, + kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(-1, *result); // Check bad program id. const char* kName = "color"; SetBucketAsCString(kBucketId, kName); - cmd.Init(kInvalidClientId, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(kInvalidClientId, kBucketId, shared_memory_id_, kSharedMemoryOffset); *result = -1; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(-1, *result); @@ -1978,9 +1900,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetFragDataLocationInvalidArgs) { kInvalidSharedMemoryId, kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(client_program_id_, - kBucketId, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, kInvalidSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } @@ -1994,7 +1914,8 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformBlockIndex) { SetBucketAsCString(kBucketId, kName); *result = GL_INVALID_INDEX; GetUniformBlockIndex cmd; - cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, + kSharedMemoryOffset); EXPECT_CALL(*gl_, GetUniformBlockIndex(kServiceProgramId, StrEq(kName))) .WillOnce(Return(kIndex)) .RetiresOnSaturation(); @@ -2009,13 +1930,14 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformBlockIndexInvalidArgs) { *result = GL_INVALID_INDEX; GetUniformBlockIndex cmd; // Check no bucket - cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, + kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_INDEX, *result); // Check bad program id. const char* kName = "color"; SetBucketAsCString(kBucketId, kName); - cmd.Init(kInvalidClientId, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(kInvalidClientId, kBucketId, shared_memory_id_, kSharedMemoryOffset); *result = GL_INVALID_INDEX; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_INDEX, *result); @@ -2026,9 +1948,7 @@ TEST_P(GLES3DecoderWithShaderTest, GetUniformBlockIndexInvalidArgs) { kInvalidSharedMemoryId, kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(client_program_id_, - kBucketId, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, kInvalidSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } @@ -2041,12 +1961,14 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformLocation) { SetBucketAsCString(kBucketId, kUniform2Name); *result = -1; GetUniformLocation cmd; - cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, + kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(kUniform2FakeLocation, *result); SetBucketAsCString(kBucketId, kNonExistentName); *result = -1; - cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, + kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(-1, *result); } @@ -2058,12 +1980,13 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformLocationInvalidArgs) { *result = -1; GetUniformLocation cmd; // Check no bucket - cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, + kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(-1, *result); // Check bad program id. SetBucketAsCString(kBucketId, kUniform2Name); - cmd.Init(kInvalidClientId, kBucketId, kSharedMemoryId, kSharedMemoryOffset); + cmd.Init(kInvalidClientId, kBucketId, shared_memory_id_, kSharedMemoryOffset); *result = -1; EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(-1, *result); @@ -2074,9 +1997,7 @@ TEST_P(GLES2DecoderWithShaderTest, GetUniformLocationInvalidArgs) { kInvalidSharedMemoryId, kSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(client_program_id_, - kBucketId, - kSharedMemoryId, + cmd.Init(client_program_id_, kBucketId, shared_memory_id_, kInvalidSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc index f4067970449..d95c373fdd5 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc @@ -12,7 +12,6 @@ #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/id_allocator.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_state.h" #include "gpu/command_buffer/service/gl_surface_mock.h" @@ -21,6 +20,7 @@ #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/program_manager.h" +#include "gpu/command_buffer/service/service_discardable_manager.h" #include "gpu/command_buffer/service/test_helper.h" #include "gpu/config/gpu_switches.h" #include "testing/gtest/include/gtest/gtest.h" @@ -35,6 +35,7 @@ using ::gl::MockGLInterface; using ::testing::_; +using ::testing::AnyNumber; using ::testing::DoAll; using ::testing::InSequence; using ::testing::Invoke; @@ -44,7 +45,7 @@ using ::testing::Pointee; using ::testing::Return; using ::testing::SaveArg; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::SetArgPointee; using ::testing::StrEq; using ::testing::StrictMock; @@ -85,16 +86,8 @@ TEST_P(GLES2DecoderTest, GenerateMipmapHandlesOutOfMemory) { GLint height = 0; EXPECT_FALSE( texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height, nullptr)); - DoTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - 16, - 16, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D)).Times(1); EXPECT_CALL(*gl_, GetError()) .WillOnce(Return(GL_NO_ERROR)) @@ -221,16 +214,8 @@ TEST_P(GLES2DecoderTest, TexSubImage2DValidArgs) { const int kWidth = 16; const int kHeight = 8; DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - 1, - GL_RGBA, - kWidth, - kHeight, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, TexSubImage2D(GL_TEXTURE_2D, 1, @@ -244,17 +229,8 @@ TEST_P(GLES2DecoderTest, TexSubImage2DValidArgs) { .Times(1) .RetiresOnSaturation(); TexSubImage2D cmd; - cmd.Init(GL_TEXTURE_2D, - 1, - 1, - 0, - kWidth - 1, - kHeight, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 1, 0, kWidth - 1, kHeight, GL_RGBA, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -274,146 +250,48 @@ TEST_P(GLES2DecoderTest, TexSubImage2DBadArgs) { 0, 0); TexSubImage2D cmd; - cmd.Init(GL_TEXTURE0, - 1, - 0, - 0, - kWidth, - kHeight, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE0, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); - cmd.Init(GL_TEXTURE_2D, - 1, - 0, - 0, - kWidth, - kHeight, - GL_TRUE, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_TRUE, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); - cmd.Init(GL_TEXTURE_2D, - 1, - 0, - 0, - kWidth, - kHeight, - GL_RGBA, - GL_UNSIGNED_INT, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_INT, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); - cmd.Init(GL_TEXTURE_2D, - 1, - -1, - 0, - kWidth, - kHeight, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, -1, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - cmd.Init(GL_TEXTURE_2D, - 1, - 1, - 0, - kWidth, - kHeight, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 1, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - cmd.Init(GL_TEXTURE_2D, - 1, - 0, - -1, - kWidth, - kHeight, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 0, -1, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - cmd.Init(GL_TEXTURE_2D, - 1, - 0, - 1, - kWidth, - kHeight, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 0, 1, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - cmd.Init(GL_TEXTURE_2D, - 1, - 0, - 0, - kWidth + 1, - kHeight, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth + 1, kHeight, GL_RGBA, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - cmd.Init(GL_TEXTURE_2D, - 1, - 0, - 0, - kWidth, - kHeight + 1, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight + 1, GL_RGBA, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); - cmd.Init(GL_TEXTURE_2D, - 1, - 0, - 0, - kWidth, - kHeight, - GL_RGB, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - cmd.Init(GL_TEXTURE_2D, - 1, - 0, - 0, - kWidth, - kHeight, - GL_RGBA, - GL_UNSIGNED_SHORT_4_4_4_4, - kSharedMemoryId, - kSharedMemoryOffset, + cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA, + GL_UNSIGNED_SHORT_4_4_4_4, shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); @@ -429,17 +307,8 @@ TEST_P(GLES2DecoderTest, TexSubImage2DBadArgs) { kSharedMemoryOffset, GL_FALSE); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); - cmd.Init(GL_TEXTURE_2D, - 1, - 0, - 0, - kWidth, - kHeight, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kInvalidSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kInvalidSharedMemoryOffset, GL_FALSE); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } @@ -447,15 +316,8 @@ TEST_P(GLES3DecoderTest, TexSubImage2DTypesDoNotMatchUnsizedFormat) { const int kWidth = 16; const int kHeight = 8; DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - 1, - GL_RGBA, - kWidth, - kHeight, - 0, - GL_RGBA, - GL_UNSIGNED_SHORT_4_4_4_4, - kSharedMemoryId, + DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, + GL_UNSIGNED_SHORT_4_4_4_4, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, TexSubImage2D(GL_TEXTURE_2D, @@ -470,17 +332,8 @@ TEST_P(GLES3DecoderTest, TexSubImage2DTypesDoNotMatchUnsizedFormat) { .Times(1) .RetiresOnSaturation(); TexSubImage2D cmd; - cmd.Init(GL_TEXTURE_2D, - 1, - 1, - 0, - kWidth - 1, - kHeight, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 1, 1, 0, kWidth - 1, kHeight, GL_RGBA, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -489,16 +342,8 @@ TEST_P(GLES3DecoderTest, TexSubImage2DTypesDoNotMatchSizedFormat) { const int kWidth = 16; const int kHeight = 8; DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - 1, - GL_RGBA4, - kWidth, - kHeight, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA4, kWidth, kHeight, 0, GL_RGBA, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, TexSubImage2D(GL_TEXTURE_2D, 1, @@ -512,16 +357,8 @@ TEST_P(GLES3DecoderTest, TexSubImage2DTypesDoNotMatchSizedFormat) { .Times(1) .RetiresOnSaturation(); TexSubImage2D cmd; - cmd.Init(GL_TEXTURE_2D, - 1, - 1, - 0, - kWidth - 1, - kHeight, - GL_RGBA, - GL_UNSIGNED_SHORT_4_4_4_4, - kSharedMemoryId, - kSharedMemoryOffset, + cmd.Init(GL_TEXTURE_2D, 1, 1, 0, kWidth - 1, kHeight, GL_RGBA, + GL_UNSIGNED_SHORT_4_4_4_4, shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -531,16 +368,8 @@ TEST_P(GLES2DecoderTest, CopyTexSubImage2DValidArgs) { const int kWidth = 16; const int kHeight = 8; DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - 1, - GL_RGBA, - kWidth, - kHeight, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, CopyTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth, kHeight)) .Times(1) @@ -609,15 +438,8 @@ TEST_P(GLES2DecoderTest, TexImage2DRedefinitionSucceeds) { _)) .Times(1) .RetiresOnSaturation(); - cmd.Init(GL_TEXTURE_2D, - 0, - GL_RGBA, - kWidth, - kHeight, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, GL_RGBA, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset); } else { cmd.Init(GL_TEXTURE_2D, 0, @@ -646,16 +468,8 @@ TEST_P(GLES2DecoderTest, TexImage2DRedefinitionSucceeds) { // (last GL_TRUE argument). It will be skipped if there are bugs in the // redefinition case. TexSubImage2D cmd2; - cmd2.Init(GL_TEXTURE_2D, - 0, - 0, - 0, - kWidth, - kHeight - 1, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, + cmd2.Init(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight - 1, GL_RGBA, + GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset, GL_TRUE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); } @@ -694,15 +508,8 @@ TEST_P(GLES2DecoderTest, TexImage2DGLError) { .Times(1) .RetiresOnSaturation(); TexImage2D cmd; - cmd.Init(target, - level, - internal_format, - width, - height, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(target, level, internal_format, width, height, format, type, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); EXPECT_FALSE( @@ -767,7 +574,7 @@ TEST_P(GLES2DecoderManualInitTest, CopyTexImage2DUnsizedInternalFormat) { GLsizei height = 4; GLint border = 0; EXPECT_CALL(*gl_, GenTextures(_, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)) + .WillOnce(SetArgPointee<1>(kNewServiceId)) .RetiresOnSaturation(); GenHelper<GenTexturesImmediate>(kNewClientId); @@ -857,7 +664,7 @@ TEST_P(GLES2DecoderManualInitTest, CopyTexImage2DUnsizedInternalFormatES3) { GLsizei height = 4; GLint border = 0; EXPECT_CALL(*gl_, GenTextures(_, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)) + .WillOnce(SetArgPointee<1>(kNewServiceId)) .RetiresOnSaturation(); GenHelper<GenTexturesImmediate>(kNewClientId); @@ -1113,7 +920,7 @@ TEST_P(GLES3DecoderTest, CopyTexSubImage3DFaiures) { const GLenum kType = GL_UNSIGNED_BYTE; DoBindTexture(kTarget, client_texture_id_, kServiceTextureId); DoTexImage3D(kTarget, kLevel, kInternalFormat, kWidth, kHeight, kDepth, 0, - kFormat, kType, kSharedMemoryId, kSharedMemoryOffset); + kFormat, kType, shared_memory_id_, kSharedMemoryOffset); cmd.Init(kTarget, kLevel, kXoffset, kYoffset, kZoffset, kX, kY, kWidth, kHeight); @@ -1139,7 +946,7 @@ TEST_P(GLES3DecoderTest, CopyTexSubImage3DCheckArgs) { DoBindTexture(kTarget, client_texture_id_, kServiceTextureId); DoTexImage3D(kTarget, kLevel, kInternalFormat, kWidth, kHeight, kDepth, - kBorder, kFormat, kType, kSharedMemoryId, kSharedMemoryOffset); + kBorder, kFormat, kType, shared_memory_id_, kSharedMemoryOffset); // Valid args EXPECT_CALL(*gl_, @@ -1240,7 +1047,7 @@ TEST_P(GLES3DecoderTest, CopyTexSubImage3DFeedbackLoopSucceeds0) { .Times(1) .RetiresOnSaturation(); DoTexImage3D(kTarget, kLevel, kInternalFormat, kWidth, kHeight, kDepth, - kBorder, kFormat, kType, kSharedMemoryId, kSharedMemoryOffset); + kBorder, kFormat, kType, shared_memory_id_, kSharedMemoryOffset); tex_layer.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, client_texture_id_, kLevel, kLayer); EXPECT_EQ(error::kNoError, ExecuteCmd(tex_layer)); @@ -1256,7 +1063,7 @@ TEST_P(GLES3DecoderTest, CopyTexSubImage3DFeedbackLoopSucceeds0) { .Times(1) .RetiresOnSaturation(); DoTexImage3D(kTarget, kLevel, kInternalFormat, kWidth, kHeight, kDepth, - kBorder, kFormat, kType, kSharedMemoryId, kSharedMemoryOffset); + kBorder, kFormat, kType, shared_memory_id_, kSharedMemoryOffset); cmd.Init(kTarget, kLevel, kXoffset, kYoffset, kZoffset, kX, kY, kWidth, kHeight); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1295,7 +1102,7 @@ TEST_P(GLES3DecoderTest, CopyTexSubImage3DFeedbackLoopSucceeds1) { .Times(1) .RetiresOnSaturation(); DoTexImage3D(kTarget, kLevel, kInternalFormat, kWidth, kHeight, kDepth, - kBorder, kFormat, kType, kSharedMemoryId, kSharedMemoryOffset); + kBorder, kFormat, kType, shared_memory_id_, kSharedMemoryOffset); tex_layer.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, client_texture_id_, kLevel, kLayer); EXPECT_EQ(error::kNoError, ExecuteCmd(tex_layer)); @@ -1340,7 +1147,7 @@ TEST_P(GLES3DecoderTest, CopyTexSubImage3DFeedbackLoopFails) { // The source and the target for CopyTexSubImage3D are the same 3d texture. // And level / zoffset of 3D texture equal to level / layer of read attachment // in fbo. - GLint kLevel = 1; + GLint kLevel = 0; // This has to be base level, or fbo is incomplete. GLint kLayer = 0; // kZoffset is 0 EXPECT_CALL(*gl_, FramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, @@ -1348,7 +1155,7 @@ TEST_P(GLES3DecoderTest, CopyTexSubImage3DFeedbackLoopFails) { .Times(1) .RetiresOnSaturation(); DoTexImage3D(kTarget, kLevel, kInternalFormat, kWidth, kHeight, kDepth, - kBorder, kFormat, kType, kSharedMemoryId, kSharedMemoryOffset); + kBorder, kFormat, kType, shared_memory_id_, kSharedMemoryOffset); tex_layer.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, client_texture_id_, kLevel, kLayer); EXPECT_EQ(error::kNoError, ExecuteCmd(tex_layer)); @@ -2182,17 +1989,8 @@ TEST_P(GLES2DecoderManualInitTest, CompressedTexImage2DETC1) { EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format)); EXPECT_EQ(kFormat, internal_format); TexSubImage2D texsub_cmd; - texsub_cmd.Init(GL_TEXTURE_2D, - 0, - 0, - 0, - 4, - 4, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + texsub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(texsub_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); @@ -2213,7 +2011,7 @@ TEST_P(GLES2DecoderManualInitTest, EGLImageExternalBindTexture) { InitDecoder(init); EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_EXTERNAL_OES, kNewServiceId)); EXPECT_CALL(*gl_, GenTextures(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); BindTexture cmd; cmd.Init(GL_TEXTURE_EXTERNAL_OES, kNewClientId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -2367,15 +2165,8 @@ TEST_P(GLES2DecoderManualInitTest, EGLImageExternalTexImage2DError) { DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId); ASSERT_TRUE(GetTexture(client_texture_id_) != NULL); TexImage2D cmd; - cmd.Init(target, - level, - internal_format, - width, - height, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(target, level, internal_format, width, height, format, type, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); // TexImage2D is not allowed with GL_TEXTURE_EXTERNAL_OES targets. @@ -2572,15 +2363,8 @@ TEST_P(GLES2DecoderManualInitTest, NoDefaultTexImage2D) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); TexImage2D cmd2; - cmd2.Init(GL_TEXTURE_2D, - 0, - GL_RGBA, - 2, - 2, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + cmd2.Init(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } @@ -2596,17 +2380,8 @@ TEST_P(GLES2DecoderManualInitTest, NoDefaultTexSubImage2D) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); TexSubImage2D cmd2; - cmd2.Init(GL_TEXTURE_2D, - 0, - 1, - 1, - 1, - 1, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd2.Init(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } @@ -2618,7 +2393,7 @@ TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleBindTexture) { InitDecoder(init); EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_RECTANGLE_ARB, kNewServiceId)); EXPECT_CALL(*gl_, GenTextures(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); BindTexture cmd; cmd.Init(GL_TEXTURE_RECTANGLE_ARB, kNewClientId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -2773,15 +2548,8 @@ TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTexImage2D) { ASSERT_TRUE(GetTexture(client_texture_id_) != NULL); TexImage2D cmd; - cmd.Init(target, - level, - internal_format, - width, - height, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(target, level, internal_format, width, height, format, type, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); @@ -2806,15 +2574,8 @@ TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTexImage2DInvalid) { ASSERT_TRUE(GetTexture(client_texture_id_) != NULL); TexImage2D cmd; - cmd.Init(target, - level, - internal_format, - width, - height, - format, - type, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(target, level, internal_format, width, height, format, type, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); @@ -2841,10 +2602,10 @@ TEST_P(GLES2DecoderManualInitTest, TexSubImage2DClearsAfterTexImage2DNULL) { .RetiresOnSaturation(); TexSubImage2D cmd; cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 2, 1, GL_RGBA, GL_UNSIGNED_BYTE, - kSharedMemoryId, kSharedMemoryOffset, GL_FALSE); + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); cmd.Init(GL_TEXTURE_2D, 0, 0, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, - kSharedMemoryId, kSharedMemoryOffset, GL_FALSE); + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); // Test if we call it again it does not clear. EXPECT_CALL(*gl_, TexSubImage2D(GL_TEXTURE_2D, 0, 0, 1, 1, 1, GL_RGBA, @@ -2858,16 +2619,8 @@ TEST_P(GLES2DecoderTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); DoTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); - DoTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - 2, - 2, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); EXPECT_CALL(*gl_, TexSubImage2D(GL_TEXTURE_2D, 0, @@ -2881,17 +2634,8 @@ TEST_P(GLES2DecoderTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) { .Times(1) .RetiresOnSaturation(); TexSubImage2D cmd; - cmd.Init(GL_TEXTURE_2D, - 0, - 1, - 1, - 1, - 1, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); // Test if we call it again it does not clear. EXPECT_CALL(*gl_, @@ -2932,15 +2676,8 @@ TEST_P( .Times(1) .RetiresOnSaturation(); TexImage2D cmd; - cmd.Init(GL_TEXTURE_2D, - 0, - GL_RGBA, - 2, - 2, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } @@ -2957,17 +2694,8 @@ TEST_P( .Times(1) .RetiresOnSaturation(); TexSubImage2D cmd; - cmd.Init(GL_TEXTURE_2D, - 0, - 1, - 1, - 1, - 1, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); // Test if we call it again it does not clear. EXPECT_CALL(*gl_, @@ -2988,16 +2716,8 @@ TEST_P( TEST_P(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DWithDataThenNULL) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); // Put in data (so it should be marked as cleared) - DoTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - 2, - 2, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); // Put in no data. TexImage2D tex_cmd; tex_cmd.Init( @@ -3014,10 +2734,10 @@ TEST_P(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DWithDataThenNULL) { .RetiresOnSaturation(); TexSubImage2D cmd; cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 2, 1, GL_RGBA, GL_UNSIGNED_BYTE, - kSharedMemoryId, kSharedMemoryOffset, GL_FALSE); + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); cmd.Init(GL_TEXTURE_2D, 0, 0, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, - kSharedMemoryId, kSharedMemoryOffset, GL_FALSE); + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } @@ -3154,14 +2874,8 @@ TEST_P(GLES2DecoderManualInitTest, CompressedImage2DMarksTextureAsCleared) { .WillOnce(Return(GL_NO_ERROR)) .RetiresOnSaturation(); CompressedTexImage2D cmd; - cmd.Init(GL_TEXTURE_2D, - 0, - GL_COMPRESSED_RGB_S3TC_DXT1_EXT, - 4, - 4, - 8, - kSharedMemoryId, - kSharedMemoryOffset); + cmd.Init(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 8, + shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); TextureManager* manager = group().texture_manager(); TextureRef* texture_ref = manager->GetTexture(client_texture_id_); @@ -3226,7 +2940,7 @@ TEST_P(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) { // Create new texture for consume. EXPECT_CALL(*gl_, GenTextures(_, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)) + .WillOnce(SetArgPointee<1>(kNewServiceId)) .RetiresOnSaturation(); DoBindTexture(GL_TEXTURE_2D, kNewClientId, kNewServiceId); @@ -3409,8 +3123,8 @@ TEST_P(GLES2DecoderTest, CreateAndConsumeTextureCHROMIUMInvalidMailbox) { GLuint new_texture_id = kNewClientId; EXPECT_CALL(*gl_, GenTextures(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)) - .RetiresOnSaturation(); + .WillOnce(SetArgPointee<1>(kNewServiceId)) + .RetiresOnSaturation(); EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, _)) .Times(2) .RetiresOnSaturation(); @@ -3456,8 +3170,8 @@ TEST_P(GLES2DecoderTest, CreateAndConsumeTextureCHROMIUMInvalidTarget) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); EXPECT_CALL(*gl_, GenTextures(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)) - .RetiresOnSaturation(); + .WillOnce(SetArgPointee<1>(kNewServiceId)) + .RetiresOnSaturation(); EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, _)) .Times(2) .RetiresOnSaturation(); @@ -3506,15 +3220,8 @@ TEST_P(GLES2DecoderManualInitTest, DepthTextureBadArgs) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); // Check trying to upload data fails. TexImage2D tex_cmd; - tex_cmd.Init(GL_TEXTURE_2D, - 0, - GL_DEPTH_COMPONENT, - 1, - 1, - GL_DEPTH_COMPONENT, - GL_UNSIGNED_INT, - kSharedMemoryId, - kSharedMemoryOffset); + tex_cmd.Init(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, GL_DEPTH_COMPONENT, + GL_UNSIGNED_INT, shared_memory_id_, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); // Try level > 0. @@ -3544,16 +3251,8 @@ TEST_P(GLES2DecoderManualInitTest, DepthTextureBadArgs) { // Check that trying to update it fails. TexSubImage2D tex_sub_cmd; - tex_sub_cmd.Init(GL_TEXTURE_2D, - 0, - 0, - 0, - 1, - 1, - GL_DEPTH_COMPONENT, - GL_UNSIGNED_INT, - kSharedMemoryId, - kSharedMemoryOffset, + tex_sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, + GL_UNSIGNED_INT, shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(tex_sub_cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); @@ -3691,7 +3390,7 @@ TEST_P(GLES2DecoderTest, GLImageAttachedAfterSubTexImage2D) { GLint border = 0; GLenum format = GL_RGBA; GLenum type = GL_UNSIGNED_BYTE; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset; GLboolean internal = 0; @@ -3736,7 +3435,7 @@ TEST_P(GLES2DecoderTest, GLImageAttachedAfterClearLevel) { GLint border = 0; GLenum format = GL_RGBA; GLenum type = GL_UNSIGNED_BYTE; - uint32_t pixels_shm_id = kSharedMemoryId; + uint32_t pixels_shm_id = shared_memory_id_; uint32_t pixels_shm_offset = kSharedMemoryOffset; // Define texture first. @@ -3846,16 +3545,8 @@ class MockGLImage : public gl::GLImage { TEST_P(GLES2DecoderWithShaderTest, CopyTexImage) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - DoTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - 1, - 1, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - kSharedMemoryId, - kSharedMemoryOffset); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_id_, kSharedMemoryOffset); TextureRef* texture_ref = group().texture_manager()->GetTexture(client_texture_id_); @@ -4081,17 +3772,8 @@ TEST_P(GLES2DecoderManualInitTest, TexSubImage2DFloatOnGLES3) { .Times(1) .RetiresOnSaturation(); TexSubImage2D cmd; - cmd.Init(GL_TEXTURE_2D, - 0, - 0, - 0, - kWidth, - kHeight, - GL_RGBA, - GL_FLOAT, - kSharedMemoryId, - kSharedMemoryOffset, - GL_FALSE); + cmd.Init(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_FLOAT, + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -4123,10 +3805,10 @@ TEST_P(GLES2DecoderManualInitTest, TexSubImage2DFloatDoesClearOnGLES3) { .RetiresOnSaturation(); TexSubImage2D cmd; cmd.Init(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight - 1, GL_RGBA, GL_FLOAT, - kSharedMemoryId, kSharedMemoryOffset, GL_FALSE); + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); cmd.Init(GL_TEXTURE_2D, 0, 0, kHeight - 1, kWidth - 1, 1, GL_RGBA, GL_FLOAT, - kSharedMemoryId, kSharedMemoryOffset, GL_FALSE); + shared_memory_id_, kSharedMemoryOffset, GL_FALSE); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -4398,24 +4080,36 @@ class GLES2DecoderTexStorageFormatAndTypeTest void DoTexStorageFormatAndType(const InitState& init, GLenum format, GLenum adjusted_internal_format) { + GLsizei kWidth = 512; + GLsizei kHeight = 512; + // Purposely set kLevels to be smaller than 10 = log2(512) + 1. + GLsizei kLevels = 5; InitDecoder(init); DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); - EXPECT_CALL(*gl_, TexStorage2DEXT(GL_TEXTURE_2D, 2, format, 2, 2)) + EXPECT_CALL( + *gl_, TexStorage2DEXT(GL_TEXTURE_2D, kLevels, format, kWidth, kHeight)) .Times(1) .RetiresOnSaturation(); TexStorage2DEXT cmd; - cmd.Init(GL_TEXTURE_2D, 2, format, 2, 2); + cmd.Init(GL_TEXTURE_2D, kLevels, format, kWidth, kHeight); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); TextureRef* texture_ref = group().texture_manager()->GetTexture(client_texture_id_); Texture* texture = texture_ref->texture(); - GLenum type; - GLenum internal_format; - EXPECT_TRUE( - texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format)); - EXPECT_EQ(static_cast<GLenum>(adjusted_internal_format), internal_format); - EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); + for (GLsizei ii = 0; ii < kLevels; ++ii) { + GLenum type = 0, internal_format = 0; + GLsizei level_width = 0, level_height = 0; + EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, static_cast<GLint>(ii), + &type, &internal_format)); + EXPECT_EQ(static_cast<GLenum>(adjusted_internal_format), internal_format); + EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); + EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, static_cast<GLint>(ii), + &level_width, &level_height, nullptr)); + EXPECT_EQ(kWidth >> ii, level_width); + EXPECT_EQ(kHeight >> ii, level_height); + } + EXPECT_TRUE(texture->texture_complete()); } }; @@ -4480,7 +4174,7 @@ TEST_P(GLES3DecoderTest, TexImage3DValidArgs) { DoBindTexture(kTarget, client_texture_id_, kServiceTextureId); DoTexImage3D(kTarget, kLevel, kInternalFormat, kWidth, kHeight, kDepth, 0, - kFormat, kType, kSharedMemoryId, kSharedMemoryOffset); + kFormat, kType, shared_memory_id_, kSharedMemoryOffset); } TEST_P(GLES3DecoderTest, ClearLevel3DSingleCall) { @@ -4769,7 +4463,7 @@ TEST_P(GLES2DecoderTest, BindTextureValidArgsNewId) { .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*gl_, GenTextures(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); + .WillOnce(SetArgPointee<1>(kNewServiceId)); if (!feature_info()->gl_version_info().BehavesLikeGLES() && feature_info()->gl_version_info().IsAtLeastGL(3, 2)) { EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, @@ -4859,6 +4553,88 @@ TEST_P(WebGL2DecoderTest, TexSwizzleDisabled) { } } +TEST_P(GLES2DecoderTest, TestInitDiscardableTexture) { + EXPECT_EQ(0u, group().discardable_manager()->NumCacheEntriesForTesting()); + DoInitializeDiscardableTextureCHROMIUM(client_texture_id_); + EXPECT_EQ(1u, group().discardable_manager()->NumCacheEntriesForTesting()); +} + +TEST_P(GLES2DecoderTest, TestInitInvalidDiscardableTexture) { + EXPECT_EQ(0u, group().discardable_manager()->NumCacheEntriesForTesting()); + DoInitializeDiscardableTextureCHROMIUM(0); + EXPECT_EQ(0u, group().discardable_manager()->NumCacheEntriesForTesting()); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderTest, TestUnlockDiscardableTexture) { + const ContextGroup& context_group = group(); + EXPECT_EQ(0u, + context_group.discardable_manager()->NumCacheEntriesForTesting()); + DoInitializeDiscardableTextureCHROMIUM(client_texture_id_); + EXPECT_TRUE(context_group.discardable_manager()->IsEntryLockedForTesting( + client_texture_id_, context_group.texture_manager())); + DoUnlockDiscardableTextureCHROMIUM(client_texture_id_); + EXPECT_FALSE(context_group.discardable_manager()->IsEntryLockedForTesting( + client_texture_id_, context_group.texture_manager())); +} + +TEST_P(GLES2DecoderTest, TestDeleteDiscardableTexture) { + EXPECT_EQ(0u, group().discardable_manager()->NumCacheEntriesForTesting()); + DoInitializeDiscardableTextureCHROMIUM(client_texture_id_); + EXPECT_EQ(1u, group().discardable_manager()->NumCacheEntriesForTesting()); + DoDeleteTexture(client_texture_id_, kServiceTextureId); + EXPECT_EQ(0u, group().discardable_manager()->NumCacheEntriesForTesting()); +} + +TEST_P(GLES2DecoderManualInitTest, + TestDiscardableTextureUnusableWhileUnlocked) { + base::CommandLine command_line(0, NULL); + InitState init; + init.bind_generates_resource = false; + InitDecoderWithCommandLine(init, &command_line); + + DoInitializeDiscardableTextureCHROMIUM(client_texture_id_); + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0)).RetiresOnSaturation(); + DoUnlockDiscardableTextureCHROMIUM(client_texture_id_); + { + // Avoid DoBindTexture, as we expect failure. + cmds::BindTexture cmd; + cmd.Init(GL_TEXTURE_2D, client_texture_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + } + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + DoLockDiscardableTextureCHROMIUM(client_texture_id_); + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTest, TestDiscardableTextureBindGeneratesUnlocked) { + DoInitializeDiscardableTextureCHROMIUM(client_texture_id_); + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + // Unlock will unbind the texture. + EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0)).RetiresOnSaturation(); + DoUnlockDiscardableTextureCHROMIUM(client_texture_id_); + + // At this point, the texture is unlocked and unusable. Bind will generate a + // new resource. + EXPECT_CALL(*gl_, GenTextures(_, _)) + .WillOnce(SetArgPointee<1>(kNewServiceId)) + .RetiresOnSaturation(); + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kNewServiceId); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Re-locking should delete the previous resource (preserving the generated + // one). + EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(kServiceTextureId))) + .RetiresOnSaturation(); + DoLockDiscardableTextureCHROMIUM(client_texture_id_); + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kNewServiceId); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + // TODO(gman): Complete this test. // TEST_P(GLES2DecoderTest, CompressedTexImage2DGLError) { // } diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc b/chromium/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc index 97201e637ee..1f560dd1909 100644 --- a/chromium/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc +++ b/chromium/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc @@ -412,11 +412,25 @@ void SRGBConverter::GenerateMipmap(const gles2::GLES2Decoder* decoder, GLenum internal_format = 0; GLenum format = 0; GLsizei base_level = tex->base_level(); + GLsizei max_level = tex->max_level(); tex->GetLevelSize(target, base_level, &width, &height, &depth); tex->GetLevelType(target, base_level, &type, &internal_format); format = TextureManager::ExtractFormatFromStorageFormat(internal_format); - const GLint mipmap_levels = - TextureManager::ComputeMipMapCount(target, width, height, depth); + GLint mipmap_levels; + if (tex->IsImmutable()) { + mipmap_levels = tex->GetImmutableLevels(); + } else { + mipmap_levels = + TextureManager::ComputeMipMapCount(target, width, height, depth); + } + GLint max_mipmap_available_level; + base::CheckedNumeric<GLint> max = base_level; + max = max - 1 + mipmap_levels; + if (!max.IsValid() || max.ValueOrDie() > max_level) { + max_mipmap_available_level = max_level; + } else { + max_mipmap_available_level = max.ValueOrDie(); + } glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[1]); if (feature_info_->ext_color_buffer_float_available() && @@ -458,26 +472,30 @@ void SRGBConverter::GenerateMipmap(const gles2::GLES2Decoder* decoder, glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - width >>= 1; - height >>= 1; - // TODO(yizhou): An optimization. Attach 1 level at a time, once for every - // iteration of the loop. - for (GLint level = base_level + 1; level < base_level + mipmap_levels; + width = (width == 1) ? 1 : width >> 1; + height = (height == 1) ? 1 : height >> 1; + + base::CheckedNumeric<GLint> level = base_level; + level += 1; + for (; level.IsValid() && level.ValueOrDie() <= max_mipmap_available_level; ++level) { // copy mipmaps level by level from srgb_converter_textures_[1] to tex // generate mipmap for tex manually glBindTexture(GL_TEXTURE_2D, tex->service_id()); - glTexImage2D(GL_TEXTURE_2D, level, internal_format, width, height, 0, - format, type, nullptr); + if (!tex->IsImmutable()) { + glTexImage2D(GL_TEXTURE_2D, level.ValueOrDie(), internal_format, width, + height, 0, format, type, nullptr); + } glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, tex->service_id(), level); + GL_TEXTURE_2D, tex->service_id(), + level.ValueOrDie()); glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[1]); glViewport(0, 0, width, height); glDrawArrays(GL_TRIANGLES, 0, 6); - width >>= 1; - height >>= 1; + width = (width == 1) ? 1 : width >> 1; + height = (height == 1) ? 1 : height >> 1; } // Restore state diff --git a/chromium/gpu/command_buffer/service/gpu_preferences.h b/chromium/gpu/command_buffer/service/gpu_preferences.h index b7db89f457c..8dd0ff114ea 100644 --- a/chromium/gpu/command_buffer/service/gpu_preferences.h +++ b/chromium/gpu/command_buffer/service/gpu_preferences.h @@ -44,6 +44,9 @@ struct GPU_EXPORT GpuPreferences { // Prioritizes the UI's command stream in the GPU process. bool ui_prioritize_in_gpu_process = false; + // Enable the GPU process scheduler. + bool enable_gpu_scheduler = false; + // Disables hardware acceleration of video decode, where available. bool disable_accelerated_video_decode = false; diff --git a/chromium/gpu/command_buffer/service/gpu_tracer.h b/chromium/gpu/command_buffer/service/gpu_tracer.h index 37bd617552b..746ebd08f7e 100644 --- a/chromium/gpu/command_buffer/service/gpu_tracer.h +++ b/chromium/gpu/command_buffer/service/gpu_tracer.h @@ -15,7 +15,6 @@ #include <vector> #include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "base/threading/thread.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/gpu_export.h" @@ -54,8 +53,7 @@ struct TraceMarker { }; // Traces GPU Commands. -class GPU_EXPORT GPUTracer - : public base::SupportsWeakPtr<GPUTracer> { +class GPU_EXPORT GPUTracer { public: explicit GPUTracer(gles2::GLES2Decoder* decoder); virtual ~GPUTracer(); diff --git a/chromium/gpu/command_buffer/service/mailbox_manager_sync.h b/chromium/gpu/command_buffer/service/mailbox_manager_sync.h index ba0c05e879f..a1a64aaa54f 100644 --- a/chromium/gpu/command_buffer/service/mailbox_manager_sync.h +++ b/chromium/gpu/command_buffer/service/mailbox_manager_sync.h @@ -96,4 +96,3 @@ class GPU_EXPORT MailboxManagerSync : public MailboxManager { } // namespace gpu #endif // GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_SYNC_H_ - diff --git a/chromium/gpu/command_buffer/service/memory_program_cache_unittest.cc b/chromium/gpu/command_buffer/service/memory_program_cache_unittest.cc index 61726ed969b..6cad7e3e235 100644 --- a/chromium/gpu/command_buffer/service/memory_program_cache_unittest.cc +++ b/chromium/gpu/command_buffer/service/memory_program_cache_unittest.cc @@ -143,11 +143,11 @@ class MemoryProgramCacheTest : public GpuServiceTest { TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true, nullptr, nullptr, nullptr, &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, - nullptr, &vertex_output_variable_list, nullptr); - TestHelper::SetShaderStates( - gl_.get(), fragment_shader_, true, nullptr, nullptr, nullptr, - &fragment_attrib_map, &fragment_uniform_map, &fragment_varying_map, - nullptr, &fragment_output_variable_list, nullptr); + nullptr, &vertex_output_variable_list); + TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true, nullptr, + nullptr, nullptr, &fragment_attrib_map, + &fragment_uniform_map, &fragment_varying_map, + nullptr, &fragment_output_variable_list); } void SetExpectationsForSaveLinkedProgram( diff --git a/chromium/gpu/command_buffer/service/mocks.cc b/chromium/gpu/command_buffer/service/mocks.cc index f095a8e647e..52b0ea11d62 100644 --- a/chromium/gpu/command_buffer/service/mocks.cc +++ b/chromium/gpu/command_buffer/service/mocks.cc @@ -2,10 +2,10 @@ // 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/mocks.h" #include "base/threading/thread.h" #include "base/time/time.h" -#include "gpu/command_buffer/service/command_executor.h" -#include "gpu/command_buffer/service/mocks.h" +#include "gpu/command_buffer/service/command_buffer_service.h" using testing::Invoke; using testing::_; @@ -28,19 +28,44 @@ error::Error AsyncAPIMock::FakeDoCommands(unsigned int num_commands, const volatile void* buffer, int num_entries, int* entries_processed) { - return AsyncAPIInterface::DoCommands( - num_commands, buffer, num_entries, entries_processed); + DCHECK(entries_processed); + int commands_to_process = num_commands; + error::Error result = error::kNoError; + const volatile CommandBufferEntry* cmd_data = + static_cast<const volatile CommandBufferEntry*>(buffer); + int process_pos = 0; + + while (process_pos < num_entries && result == error::kNoError && + commands_to_process--) { + CommandHeader header = CommandHeader::FromVolatile(cmd_data->value_header); + DCHECK_GT(header.size, 0u); + DCHECK_LE(static_cast<int>(header.size) + process_pos, num_entries); + + const unsigned int command = header.command; + const unsigned int arg_count = header.size - 1; + + result = DoCommand(command, arg_count, cmd_data); + + if (result != error::kDeferCommandUntilLater) { + process_pos += header.size; + cmd_data += header.size; + } + } + + *entries_processed = process_pos; + + return result; } void AsyncAPIMock::SetToken(unsigned int command, unsigned int arg_count, const volatile void* _args) { - DCHECK(engine_); + DCHECK(command_buffer_service_); DCHECK_EQ(1u, command); DCHECK_EQ(1u, arg_count); const volatile cmd::SetToken* args = static_cast<const volatile cmd::SetToken*>(_args); - engine_->set_token(args->token); + command_buffer_service_->SetToken(args->token); } namespace gles2 { diff --git a/chromium/gpu/command_buffer/service/mocks.h b/chromium/gpu/command_buffer/service/mocks.h index a47ca6fa7d2..58d32fed1ce 100644 --- a/chromium/gpu/command_buffer/service/mocks.h +++ b/chromium/gpu/command_buffer/service/mocks.h @@ -17,8 +17,7 @@ #include <vector> #include "base/logging.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" -#include "gpu/command_buffer/service/cmd_parser.h" +#include "gpu/command_buffer/service/async_api_interface.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/command_buffer/service/program_cache.h" #include "gpu/command_buffer/service/shader_translator.h" @@ -26,6 +25,8 @@ namespace gpu { +class CommandBufferServiceBase; + // Mocks an AsyncAPIInterface, using GMock. class AsyncAPIMock : public AsyncAPIInterface { public: @@ -59,6 +60,9 @@ class AsyncAPIMock : public AsyncAPIInterface { volatile CommandBufferEntry* args_; }; + void BeginDecoding() override {} + void EndDecoding() override {} + MOCK_METHOD3(DoCommand, error::Error(unsigned int command, unsigned int arg_count, @@ -70,12 +74,13 @@ class AsyncAPIMock : public AsyncAPIInterface { int num_entries, int* entries_processed)); - const char* GetCommandName(unsigned int command_id) const { - return ""; - }; + base::StringPiece GetLogPrefix() override { return "None"; } // Sets the engine, to forward SetToken commands to it. - void set_engine(CommandBufferEngine *engine) { engine_ = engine; } + void set_command_buffer_service( + CommandBufferServiceBase* command_buffer_service) { + command_buffer_service_ = command_buffer_service; + } // Forwards the SetToken commands to the engine. void SetToken(unsigned int command, @@ -83,7 +88,7 @@ class AsyncAPIMock : public AsyncAPIInterface { const volatile void* _args); private: - CommandBufferEngine *engine_; + CommandBufferServiceBase* command_buffer_service_; }; namespace gles2 { @@ -99,17 +104,16 @@ class MockShaderTranslator : public ShaderTranslatorInterface { ShShaderOutput shader_output_language, ShCompileOptions driver_bug_workarounds, bool gl_shader_interm_output)); - MOCK_CONST_METHOD10(Translate, - bool(const std::string& shader_source, - std::string* info_log, - std::string* translated_source, - int* shader_version, - AttributeMap* attrib_map, - UniformMap* uniform_map, - VaryingMap* varying_map, - InterfaceBlockMap* interface_block_map, - OutputVariableList* output_variable_list, - NameMap* name_map)); + MOCK_CONST_METHOD9(Translate, + bool(const std::string& shader_source, + std::string* info_log, + std::string* translated_source, + int* shader_version, + AttributeMap* attrib_map, + UniformMap* uniform_map, + VaryingMap* varying_map, + InterfaceBlockMap* interface_block_map, + OutputVariableList* output_variable_list)); MOCK_CONST_METHOD0( GetStringForOptionsThatWouldAffectCompilation, std::string()); private: diff --git a/chromium/gpu/command_buffer/service/program_manager.cc b/chromium/gpu/command_buffer/service/program_manager.cc index f8dcbc197a9..ff78aa984fd 100644 --- a/chromium/gpu/command_buffer/service/program_manager.cc +++ b/chromium/gpu/command_buffer/service/program_manager.cc @@ -1555,6 +1555,31 @@ const std::string* Program::GetOriginalNameFromHashedName( return nullptr; } +const sh::Varying* Program::GetVaryingInfo( + const std::string& hashed_name) const { + for (auto shader : attached_shaders_) { + if (shader) { + const sh::Varying* info = shader->GetVaryingInfo(hashed_name); + if (info) + return info; + } + } + return nullptr; +} + +const sh::InterfaceBlock* Program::GetInterfaceBlockInfo( + const std::string& hashed_name) const { + for (auto shader : attached_shaders_) { + if (shader) { + const sh::InterfaceBlock* info = + shader->GetInterfaceBlockInfo(hashed_name); + if (info) + return info; + } + } + return nullptr; +} + const Program::FragmentInputInfo* Program::GetFragmentInputInfoByFakeLocation( GLint fake_location) const { if (fake_location < 0) @@ -2229,18 +2254,17 @@ bool Program::GetUniformBlocks(CommonDecoder::Bucket* bucket) const { program, ii, static_cast<GLsizei>(param), &length, &buffer[0]); DCHECK_EQ(param, length + 1); names[ii] = std::string(&buffer[0], length); - // TODO(zmo): optimize the name mapping lookup. size_t pos = names[ii].find_first_of('['); - const std::string* original_name; + const sh::InterfaceBlock* interface_block = nullptr; std::string array_index_str = ""; if (pos != std::string::npos) { - original_name = GetOriginalNameFromHashedName(names[ii].substr(0, pos)); + interface_block = GetInterfaceBlockInfo(names[ii].substr(0, pos)); array_index_str = names[ii].substr(pos); } else { - original_name = GetOriginalNameFromHashedName(names[ii]); + interface_block = GetInterfaceBlockInfo(names[ii]); } - if (original_name) - names[ii] = *original_name + array_index_str; + if (interface_block) + names[ii] = interface_block->name + array_index_str; blocks[ii].name_length = names[ii].size() + 1; size += blocks[ii].name_length; @@ -2370,10 +2394,9 @@ bool Program::GetTransformFeedbackVaryings( varyings[ii].name_offset = static_cast<uint32_t>(size.ValueOrDefault(0)); DCHECK_GT(max_name_length, var_name_length); names[ii] = std::string(&buffer[0], var_name_length); - // TODO(zmo): optimize the name mapping lookup. - const std::string* original_name = GetOriginalNameFromHashedName(names[ii]); - if (original_name) - names[ii] = *original_name; + const sh::Varying* varying = GetVaryingInfo(names[ii]); + if (varying) + names[ii] = varying->name; varyings[ii].name_length = names[ii].size() + 1; size += names[ii].size(); size += 1; diff --git a/chromium/gpu/command_buffer/service/program_manager.h b/chromium/gpu/command_buffer/service/program_manager.h index c1cd9c6924c..3126c574d7f 100644 --- a/chromium/gpu/command_buffer/service/program_manager.h +++ b/chromium/gpu/command_buffer/service/program_manager.h @@ -235,10 +235,18 @@ class GPU_EXPORT Program : public base::RefCounted<Program> { const std::string* GetUniformMappedName( const std::string& original_name) const; - // If the hashed name is not found, return NULL. + // If the hashed name name is not found, return NULL. + // Use this only when one of the more specific Get*Info methods can't be used. const std::string* GetOriginalNameFromHashedName( const std::string& hashed_name) const; + // If the hashed name is not found, return NULL. + const sh::Varying* GetVaryingInfo(const std::string& hashed_name) const; + + // If the hashed name is not found, return NULL. + const sh::InterfaceBlock* GetInterfaceBlockInfo( + const std::string& hashed_name) const; + const FragmentInputInfo* GetFragmentInputInfoByFakeLocation( GLint fake_location) const; diff --git a/chromium/gpu/command_buffer/service/program_manager_unittest.cc b/chromium/gpu/command_buffer/service/program_manager_unittest.cc index 6bb1ca244d1..7d6cdacf8dd 100644 --- a/chromium/gpu/command_buffer/service/program_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/program_manager_unittest.cc @@ -427,11 +427,11 @@ class ProgramManagerWithShaderTest : public ProgramManagerTestBase { TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, shader_version, &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, - nullptr, &vertex_output_variable_list, nullptr); + nullptr, &vertex_output_variable_list); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, shader_version, &frag_attrib_map, &frag_uniform_map, &frag_varying_map, nullptr, - &frag_output_variable_list, nullptr); + &frag_output_variable_list); // Set up program Program* program = @@ -875,13 +875,13 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) { ASSERT_TRUE(vshader != NULL); TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, nullptr, &attrib_map, &uniform_map, &varying_map, - nullptr, &output_variable_list, nullptr); + nullptr, &output_variable_list); Shader* fshader = shader_manager_.CreateShader( kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER); ASSERT_TRUE(fshader != NULL); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, &attrib_map, &uniform_map, &varying_map, - nullptr, &output_variable_list, nullptr); + nullptr, &output_variable_list); static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = { { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, }, { kAttrib2Name, kAttrib2Size, kAttrib2BadType, kAttrib2Location, }, @@ -1546,7 +1546,7 @@ TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) { // Set Status TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, nullptr, &attrib_map, nullptr, nullptr, nullptr, - nullptr, nullptr); + nullptr); // Check attrib infos got copied. for (AttributeMap::const_iterator it = attrib_map.begin(); it != attrib_map.end(); ++it) { @@ -1561,7 +1561,7 @@ TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) { } TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, &attrib_map, nullptr, nullptr, nullptr, - nullptr, nullptr); + nullptr); // Set up program Program* program = manager_->CreateProgram(kClientProgramId, kServiceProgramId); @@ -1629,10 +1629,10 @@ TEST_F(ProgramManagerWithShaderTest, UniformsPrecisionMismatch) { // Set Status TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, nullptr, nullptr, &vertex_uniform_map, nullptr, - nullptr, nullptr, nullptr); + nullptr, nullptr); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, nullptr, &frag_uniform_map, nullptr, - nullptr, nullptr, nullptr); + nullptr, nullptr); // Set up program Program* program = manager_->CreateProgram(kClientProgramId, kServiceProgramId); @@ -1751,7 +1751,7 @@ TEST_F(ProgramManagerWithShaderTest, FragmentOutputTypes) { kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER); TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr); + nullptr); Shader* fshader = shader_manager_.CreateShader( kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER); ASSERT_TRUE(vshader && fshader); @@ -1764,7 +1764,7 @@ TEST_F(ProgramManagerWithShaderTest, FragmentOutputTypes) { { // No outputs. TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr); + nullptr); EXPECT_TRUE(LinkAsExpected(program, true)); EXPECT_EQ(0u, program->fragment_output_type_mask()); EXPECT_EQ(0u, program->fragment_output_written_mask()); @@ -1778,7 +1778,7 @@ TEST_F(ProgramManagerWithShaderTest, FragmentOutputTypes) { fragment_outputs.push_back(var); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - &fragment_outputs, nullptr); + &fragment_outputs); EXPECT_TRUE(LinkAsExpected(program, true)); EXPECT_EQ(0x3u, program->fragment_output_type_mask()); EXPECT_EQ(0x3u, program->fragment_output_written_mask()); @@ -1792,7 +1792,7 @@ TEST_F(ProgramManagerWithShaderTest, FragmentOutputTypes) { fragment_outputs.push_back(var); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - &fragment_outputs, nullptr); + &fragment_outputs); EXPECT_TRUE(LinkAsExpected(program, true)); EXPECT_EQ(0xFFFFu, program->fragment_output_type_mask()); EXPECT_EQ(0xFFFFu, program->fragment_output_written_mask()); @@ -1810,7 +1810,7 @@ TEST_F(ProgramManagerWithShaderTest, FragmentOutputTypes) { fragment_outputs.push_back(var); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - &fragment_outputs, nullptr); + &fragment_outputs); EXPECT_TRUE(LinkAsExpected(program, true)); EXPECT_EQ(0x3u, program->fragment_output_type_mask()); EXPECT_EQ(0x3u, program->fragment_output_written_mask()); @@ -1824,7 +1824,7 @@ TEST_F(ProgramManagerWithShaderTest, FragmentOutputTypes) { fragment_outputs.push_back(var); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - &fragment_outputs, nullptr); + &fragment_outputs); EXPECT_TRUE(LinkAsExpected(program, true)); EXPECT_EQ(0x2u, program->fragment_output_type_mask()); EXPECT_EQ(0x3u, program->fragment_output_written_mask()); @@ -1838,7 +1838,7 @@ TEST_F(ProgramManagerWithShaderTest, FragmentOutputTypes) { fragment_outputs.push_back(var); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - &fragment_outputs, nullptr); + &fragment_outputs); EXPECT_TRUE(LinkAsExpected(program, true)); EXPECT_EQ(0x2u, program->fragment_output_type_mask()); EXPECT_EQ(0x3u, program->fragment_output_written_mask()); @@ -1856,7 +1856,7 @@ TEST_F(ProgramManagerWithShaderTest, FragmentOutputTypes) { fragment_outputs.push_back(var); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - &fragment_outputs, nullptr); + &fragment_outputs); EXPECT_TRUE(LinkAsExpected(program, true)); EXPECT_EQ(0xF1u, program->fragment_output_type_mask()); EXPECT_EQ(0xF3u, program->fragment_output_written_mask()); @@ -2360,10 +2360,10 @@ TEST_P(ProgramManagerWithPathRenderingTest, BindFragmentInputLocation) { kFragmentInput3StaticUse, kFragmentInput3Name); TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, &varying_map, nullptr, - nullptr, nullptr); + nullptr); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, &varying_map, nullptr, - nullptr, nullptr); + nullptr); Program* program = manager_->CreateProgram(kClientProgramId, kServiceProgramId); ASSERT_TRUE(program != NULL); diff --git a/chromium/gpu/command_buffer/service/query_manager_unittest.cc b/chromium/gpu/command_buffer/service/query_manager_unittest.cc index aa6be4f35cb..798885f3f60 100644 --- a/chromium/gpu/command_buffer/service/query_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/query_manager_unittest.cc @@ -7,8 +7,8 @@ #include <memory> +#include "gpu/command_buffer/client/client_test_helper.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/error_state_mock.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" @@ -25,19 +25,17 @@ using ::testing::_; using ::testing::InSequence; using ::testing::Return; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; namespace gpu { namespace gles2 { class QueryManagerTest : public GpuServiceTest { public: - static const int32_t kSharedMemoryId = 401; static const uint32_t kSharedMemoryOffset = 132; - static const int32_t kSharedMemory2Id = 402; static const uint32_t kSharedMemory2Offset = 232; static const size_t kSharedBufferSize = 2048; - static const int32_t kInvalidSharedMemoryId = 403; + static const int32_t kInvalidSharedMemoryId = -1; static const uint32_t kInvalidSharedMemoryOffset = kSharedBufferSize + 1; static const uint32_t kInitialResult = 0xBDBDBDBDu; static const uint8_t kInitialMemoryValue = 0xBDu; @@ -58,14 +56,21 @@ class QueryManagerTest : public GpuServiceTest { decoder_.reset(); manager_->Destroy(false); manager_.reset(); - engine_.reset(); + command_buffer_service_.reset(); GpuServiceTest::TearDown(); } void SetUpMockGL(const char* extension_expectations) { - engine_.reset(new MockCommandBufferEngine()); + command_buffer_service_.reset(new FakeCommandBufferServiceBase()); + scoped_refptr<gpu::Buffer> buffer = + command_buffer_service_->CreateTransferBufferHelper(kSharedBufferSize, + &shared_memory_id_); + memset(buffer->memory(), kInitialMemoryValue, kSharedBufferSize); + buffer = command_buffer_service_->CreateTransferBufferHelper( + kSharedBufferSize, &shared_memory2_id_); + memset(buffer->memory(), kInitialMemoryValue, kSharedBufferSize); decoder_.reset(new MockGLES2Decoder()); - decoder_->set_engine(engine_.get()); + decoder_->set_command_buffer_service(command_buffer_service_.get()); TestHelper::SetupFeatureInfoInitExpectations( gl_.get(), extension_expectations); EXPECT_CALL(*decoder_.get(), GetGLContext()) @@ -81,8 +86,8 @@ class QueryManagerTest : public GpuServiceTest { uint32_t shm_offset, GLuint service_id) { EXPECT_CALL(*gl_, GenQueries(1, _)) - .WillOnce(SetArgumentPointee<1>(service_id)) - .RetiresOnSaturation(); + .WillOnce(SetArgPointee<1>(service_id)) + .RetiresOnSaturation(); return manager_->CreateQuery(target, client_id, shm_id, shm_offset); } @@ -102,66 +107,11 @@ class QueryManagerTest : public GpuServiceTest { std::unique_ptr<MockGLES2Decoder> decoder_; std::unique_ptr<QueryManager> manager_; + int32_t shared_memory_id_ = 0; + int32_t shared_memory2_id_ = 0; + private: - class MockCommandBufferEngine : public CommandBufferEngine { - public: - MockCommandBufferEngine() { - std::unique_ptr<base::SharedMemory> shared_memory( - new base::SharedMemory()); - shared_memory->CreateAndMapAnonymous(kSharedBufferSize); - valid_buffer_ = MakeBufferFromSharedMemory(std::move(shared_memory), - kSharedBufferSize); - - std::unique_ptr<base::SharedMemory> shared_memory2( - new base::SharedMemory()); - shared_memory2->CreateAndMapAnonymous(kSharedBufferSize); - valid_buffer2_ = MakeBufferFromSharedMemory(std::move(shared_memory2), - kSharedBufferSize); - - ClearSharedMemory(); - } - - ~MockCommandBufferEngine() override {} - - scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32_t shm_id) override { - switch (shm_id) { - case kSharedMemoryId: return valid_buffer_; - case kSharedMemory2Id: return valid_buffer2_; - default: return invalid_buffer_; - } - } - - void ClearSharedMemory() { - memset(valid_buffer_->memory(), kInitialMemoryValue, kSharedBufferSize); - memset(valid_buffer2_->memory(), kInitialMemoryValue, kSharedBufferSize); - } - - void set_token(int32_t token) override { DCHECK(false); } - - bool SetGetBuffer(int32_t /* transfer_buffer_id */) override { - DCHECK(false); - return false; - } - - // Overridden from CommandBufferEngine. - bool SetGetOffset(int32_t offset) override { - DCHECK(false); - return false; - } - - // Overridden from CommandBufferEngine. - int32_t GetGetOffset() override { - DCHECK(false); - return 0; - } - - private: - scoped_refptr<gpu::Buffer> valid_buffer_; - scoped_refptr<gpu::Buffer> valid_buffer2_; - scoped_refptr<gpu::Buffer> invalid_buffer_; - }; - - std::unique_ptr<MockCommandBufferEngine> engine_; + std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_; }; class QueryManagerManualSetupTest : public QueryManagerTest { @@ -173,9 +123,7 @@ class QueryManagerManualSetupTest : public QueryManagerTest { // GCC requires these declarations, but MSVC requires they not be present #ifndef COMPILER_MSVC -const int32_t QueryManagerTest::kSharedMemoryId; const uint32_t QueryManagerTest::kSharedMemoryOffset; -const int32_t QueryManagerTest::kSharedMemory2Id; const uint32_t QueryManagerTest::kSharedMemory2Offset; const size_t QueryManagerTest::kSharedBufferSize; const int32_t QueryManagerTest::kInvalidSharedMemoryId; @@ -192,8 +140,8 @@ TEST_F(QueryManagerTest, Basic) { EXPECT_FALSE(manager_->HavePendingQueries()); // Check we can create a Query. scoped_refptr<QueryManager::Query> query( - CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id, - kSharedMemoryId, kSharedMemoryOffset, kService1Id)); + CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id, shared_memory_id_, + kSharedMemoryOffset, kService1Id)); ASSERT_TRUE(query.get() != NULL); // Check we can get the same Query. EXPECT_EQ(query.get(), manager_->GetQuery(kClient1Id)); @@ -217,8 +165,8 @@ TEST_F(QueryManagerTest, Destroy) { // Create Query. scoped_refptr<QueryManager::Query> query( - CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id, - kSharedMemoryId, kSharedMemoryOffset, kService1Id)); + CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id, shared_memory_id_, + kSharedMemoryOffset, kService1Id)); ASSERT_TRUE(query.get() != NULL); EXPECT_CALL(*gl_, DeleteQueries(1, ::testing::Pointee(kService1Id))) .Times(1) @@ -237,15 +185,15 @@ TEST_F(QueryManagerTest, QueryBasic) { // Create Query. scoped_refptr<QueryManager::Query> query( - CreateQuery(kTarget, kClient1Id, - kSharedMemoryId, kSharedMemoryOffset, kService1Id)); + CreateQuery(kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, + kService1Id)); ASSERT_TRUE(query.get() != NULL); EXPECT_TRUE(query->IsValid()); EXPECT_FALSE(query->IsDeleted()); EXPECT_FALSE(query->IsPending()); EXPECT_EQ(kTarget, query->target()); - EXPECT_EQ(kSharedMemoryId, query->shm_id()); + EXPECT_EQ(shared_memory_id_, query->shm_id()); EXPECT_EQ(kSharedMemoryOffset, query->shm_offset()); } @@ -261,13 +209,13 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) { // Create Query. scoped_refptr<QueryManager::Query> query( - CreateQuery(kTarget, kClient1Id, - kSharedMemoryId, kSharedMemoryOffset, kService1Id)); + CreateQuery(kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, + kService1Id)); ASSERT_TRUE(query.get() != NULL); // Setup shared memory like client would. QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>( - kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync)); + shared_memory_id_, kSharedMemoryOffset, sizeof(*sync)); ASSERT_TRUE(sync != NULL); sync->Reset(); @@ -279,8 +227,8 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) { // Process with return not available. // Expect 1 GL command. EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(0)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(0)) .RetiresOnSaturation(); EXPECT_TRUE(manager_->ProcessPendingQueries(false)); EXPECT_TRUE(query->IsPending()); @@ -290,12 +238,11 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) { // Process with return available. // Expect 2 GL commands. EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(1)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(1)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) - .WillOnce(SetArgumentPointee<2>(kResult)) + EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) + .WillOnce(SetArgPointee<2>(kResult)) .RetiresOnSaturation(); EXPECT_TRUE(manager_->ProcessPendingQueries(false)); EXPECT_FALSE(query->IsPending()); @@ -325,24 +272,21 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) { // Setup shared memory like client would. QuerySync* sync1 = decoder_->GetSharedMemoryAs<QuerySync*>( - kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync1) * 3); + shared_memory_id_, kSharedMemoryOffset, sizeof(*sync1) * 3); ASSERT_TRUE(sync1 != NULL); QuerySync* sync2 = sync1 + 1; QuerySync* sync3 = sync2 + 1; // Create Queries. scoped_refptr<QueryManager::Query> query1( - CreateQuery(kTarget, kClient1Id, - kSharedMemoryId, kSharedMemoryOffset + sizeof(*sync1) * 0, - kService1Id)); + CreateQuery(kTarget, kClient1Id, shared_memory_id_, + kSharedMemoryOffset + sizeof(*sync1) * 0, kService1Id)); scoped_refptr<QueryManager::Query> query2( - CreateQuery(kTarget, kClient2Id, - kSharedMemoryId, kSharedMemoryOffset + sizeof(*sync1) * 1, - kService2Id)); + CreateQuery(kTarget, kClient2Id, shared_memory_id_, + kSharedMemoryOffset + sizeof(*sync1) * 1, kService2Id)); scoped_refptr<QueryManager::Query> query3( - CreateQuery(kTarget, kClient3Id, - kSharedMemoryId, kSharedMemoryOffset + sizeof(*sync1) * 2, - kService3Id)); + CreateQuery(kTarget, kClient3Id, shared_memory_id_, + kSharedMemoryOffset + sizeof(*sync1) * 2, kService3Id)); ASSERT_TRUE(query1.get() != NULL); ASSERT_TRUE(query2.get() != NULL); ASSERT_TRUE(query3.get() != NULL); @@ -365,25 +309,23 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) { // Expect 4 GL commands. { InSequence s; - EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(1)) + EXPECT_CALL( + *gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(1)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) - .WillOnce(SetArgumentPointee<2>(kResult1)) + EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) + .WillOnce(SetArgPointee<2>(kResult1)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(1)) + EXPECT_CALL( + *gl_, GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(1)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_EXT, _)) - .WillOnce(SetArgumentPointee<2>(kResult2)) + EXPECT_CALL(*gl_, GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_EXT, _)) + .WillOnce(SetArgPointee<2>(kResult2)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(0)) + EXPECT_CALL( + *gl_, GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(0)) .RetiresOnSaturation(); EXPECT_TRUE(manager_->ProcessPendingQueries(false)); } @@ -401,8 +343,8 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) { // Process with renaming query. No result. // Expect 1 GL commands. EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(0)) + GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(0)) .RetiresOnSaturation(); EXPECT_TRUE(manager_->ProcessPendingQueries(false)); EXPECT_TRUE(query3->IsPending()); @@ -413,12 +355,11 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) { // Process with renaming query. With result. // Expect 2 GL commands. EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(1)) + GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(1)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_EXT, _)) - .WillOnce(SetArgumentPointee<2>(kResult3)) + EXPECT_CALL(*gl_, GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_EXT, _)) + .WillOnce(SetArgPointee<2>(kResult3)) .RetiresOnSaturation(); EXPECT_TRUE(manager_->ProcessPendingQueries(false)); EXPECT_FALSE(query3->IsPending()); @@ -446,12 +387,11 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryId) { // Process with return available. // Expect 2 GL commands. EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(1)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(1)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) - .WillOnce(SetArgumentPointee<2>(kResult)) + EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) + .WillOnce(SetArgPointee<2>(kResult)) .RetiresOnSaturation(); EXPECT_FALSE(manager_->ProcessPendingQueries(false)); } @@ -465,8 +405,8 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryOffset) { // Create Query. scoped_refptr<QueryManager::Query> query( - CreateQuery(kTarget, kClient1Id, - kSharedMemoryId, kInvalidSharedMemoryOffset, kService1Id)); + CreateQuery(kTarget, kClient1Id, shared_memory_id_, + kInvalidSharedMemoryOffset, kService1Id)); ASSERT_TRUE(query.get() != NULL); // Queue it @@ -475,12 +415,11 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryOffset) { // Process with return available. // Expect 2 GL commands. EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(1)) + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(1)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) - .WillOnce(SetArgumentPointee<2>(kResult)) + EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) + .WillOnce(SetArgPointee<2>(kResult)) .RetiresOnSaturation(); EXPECT_FALSE(manager_->ProcessPendingQueries(false)); } @@ -493,8 +432,8 @@ TEST_F(QueryManagerTest, ExitWithPendingQuery) { // Create Query. scoped_refptr<QueryManager::Query> query( - CreateQuery(kTarget, kClient1Id, - kSharedMemoryId, kSharedMemoryOffset, kService1Id)); + CreateQuery(kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, + kService1Id)); ASSERT_TRUE(query.get() != NULL); // Queue it @@ -518,10 +457,10 @@ TEST_F(QueryManagerTest, ARBOcclusionQuery2) { new QueryManager(decoder_.get(), feature_info.get())); EXPECT_CALL(*gl_, GenQueries(1, _)) - .WillOnce(SetArgumentPointee<1>(kService1Id)) + .WillOnce(SetArgPointee<1>(kService1Id)) .RetiresOnSaturation(); QueryManager::Query* query = manager->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); EXPECT_CALL(*gl_, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT, kService1Id)) @@ -552,10 +491,10 @@ TEST_F(QueryManagerTest, ARBOcclusionQuery) { new QueryManager(decoder_.get(), feature_info.get())); EXPECT_CALL(*gl_, GenQueries(1, _)) - .WillOnce(SetArgumentPointee<1>(kService1Id)) + .WillOnce(SetArgPointee<1>(kService1Id)) .RetiresOnSaturation(); QueryManager::Query* query = manager->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id)) @@ -585,10 +524,10 @@ TEST_F(QueryManagerTest, ARBOcclusionPauseResume) { new QueryManager(decoder_.get(), feature_info.get())); EXPECT_CALL(*gl_, GenQueries(1, _)) - .WillOnce(SetArgumentPointee<1>(kService1Id)) + .WillOnce(SetArgPointee<1>(kService1Id)) .RetiresOnSaturation(); QueryManager::Query* query = manager->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id)) @@ -603,7 +542,7 @@ TEST_F(QueryManagerTest, ARBOcclusionPauseResume) { manager->PauseQueries(); EXPECT_CALL(*gl_, GenQueries(1, _)) - .WillOnce(SetArgumentPointee<1>(kService2Id)) + .WillOnce(SetArgPointee<1>(kService2Id)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService2Id)) .Times(1) @@ -615,23 +554,21 @@ TEST_F(QueryManagerTest, ARBOcclusionPauseResume) { .RetiresOnSaturation(); EXPECT_TRUE(manager->EndQuery(query, kSubmitCount)); - EXPECT_CALL(*gl_, GetQueryObjectuiv(kService2Id, - GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(1u)) + EXPECT_CALL(*gl_, + GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(1u)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, - GL_QUERY_RESULT_EXT, _)) - .WillOnce(SetArgumentPointee<2>(0u)) + EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) + .WillOnce(SetArgPointee<2>(0u)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, GetQueryObjectuiv(kService2Id, - GL_QUERY_RESULT_EXT, _)) - .WillOnce(SetArgumentPointee<2>(1u)) + EXPECT_CALL(*gl_, GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_EXT, _)) + .WillOnce(SetArgPointee<2>(1u)) .RetiresOnSaturation(); EXPECT_TRUE(manager->ProcessPendingQueries(false)); EXPECT_TRUE(query->IsFinished()); QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>( - kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync)); + shared_memory_id_, kSharedMemoryOffset, sizeof(*sync)); EXPECT_EQ(1u, sync->result); // Make sure new query still works. @@ -647,13 +584,12 @@ TEST_F(QueryManagerTest, ARBOcclusionPauseResume) { EXPECT_TRUE(manager->BeginQuery(query)); EXPECT_TRUE(manager->EndQuery(query, kSubmitCount + 1)); - EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, - GL_QUERY_RESULT_AVAILABLE_EXT, _)) - .WillOnce(SetArgumentPointee<2>(1u)) + EXPECT_CALL(*gl_, + GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) + .WillOnce(SetArgPointee<2>(1u)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, - GL_QUERY_RESULT_EXT, _)) - .WillOnce(SetArgumentPointee<2>(0u)) + EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _)) + .WillOnce(SetArgPointee<2>(0u)) .RetiresOnSaturation(); EXPECT_TRUE(manager->ProcessPendingQueries(false)); EXPECT_TRUE(query->IsFinished()); @@ -674,7 +610,7 @@ TEST_F(QueryManagerTest, TimeElapsedQuery) { base::Bind(&gl::GPUTimingFake::GetFakeCPUTime)); QueryManager::Query* query = manager_->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); fake_timing_queries.ExpectGPUTimerQuery(*gl_, true); @@ -689,7 +625,7 @@ TEST_F(QueryManagerTest, TimeElapsedQuery) { EXPECT_TRUE(query->IsFinished()); QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>( - kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync)); + shared_memory_id_, kSharedMemoryOffset, sizeof(*sync)); const uint64_t expected_result = 100u * base::Time::kNanosecondsPerMicrosecond; EXPECT_EQ(expected_result, sync->result); @@ -706,7 +642,7 @@ TEST_F(QueryManagerTest, TimeElapsedPauseResume) { base::Bind(&gl::GPUTimingFake::GetFakeCPUTime)); QueryManager::Query* query = manager_->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); fake_timing_queries.ExpectGPUTimerQuery(*gl_, true); @@ -731,7 +667,7 @@ TEST_F(QueryManagerTest, TimeElapsedPauseResume) { EXPECT_TRUE(query->IsFinished()); QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>( - kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync)); + shared_memory_id_, kSharedMemoryOffset, sizeof(*sync)); const uint64_t expected_result = 300u * base::Time::kNanosecondsPerMicrosecond; EXPECT_EQ(expected_result, sync->result); @@ -762,10 +698,9 @@ TEST_F(QueryManagerManualSetupTest, TimeElapsedDisjoint) { SetUpMockGL("GL_EXT_disjoint_timer_query"); DisjointValueSync* disjoint_sync = - decoder_->GetSharedMemoryAs<DisjointValueSync*>(kSharedMemory2Id, - kSharedMemory2Offset, - sizeof(*disjoint_sync)); - manager_->SetDisjointSync(kSharedMemory2Id, kSharedMemory2Offset); + decoder_->GetSharedMemoryAs<DisjointValueSync*>( + shared_memory2_id_, kSharedMemory2Offset, sizeof(*disjoint_sync)); + manager_->SetDisjointSync(shared_memory2_id_, kSharedMemory2Offset); const uint32_t current_disjoint_value = disjoint_sync->GetDisjointCount(); ASSERT_EQ(0u, current_disjoint_value); @@ -775,7 +710,7 @@ TEST_F(QueryManagerManualSetupTest, TimeElapsedDisjoint) { const base::subtle::Atomic32 kSubmitCount = 123; QueryManager::Query* query = manager_->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); // Disjoint happening before the query should not trigger a disjoint event. @@ -812,7 +747,7 @@ TEST_F(QueryManagerTest, TimeStampQuery) { base::Bind(&gl::GPUTimingFake::GetFakeCPUTime)); QueryManager::Query* query = manager_->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); const uint64_t expected_result = @@ -823,7 +758,7 @@ TEST_F(QueryManagerTest, TimeStampQuery) { EXPECT_TRUE(manager_->ProcessPendingQueries(false)); QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>( - kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync)); + shared_memory_id_, kSharedMemoryOffset, sizeof(*sync)); EXPECT_EQ(expected_result, sync->result); manager_->Destroy(false); @@ -839,7 +774,7 @@ TEST_F(QueryManagerTest, TimeStampQueryPending) { base::Bind(&gl::GPUTimingFake::GetFakeCPUTime)); QueryManager::Query* query = manager_->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); const uint64_t expected_result = @@ -853,7 +788,7 @@ TEST_F(QueryManagerTest, TimeStampQueryPending) { EXPECT_TRUE(manager_->ProcessPendingQueries(false)); QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>( - kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync)); + shared_memory_id_, kSharedMemoryOffset, sizeof(*sync)); EXPECT_EQ(expected_result, sync->result); manager_->Destroy(false); @@ -867,10 +802,9 @@ TEST_F(QueryManagerManualSetupTest, TimeStampDisjoint) { SetUpMockGL("GL_EXT_disjoint_timer_query"); DisjointValueSync* disjoint_sync = - decoder_->GetSharedMemoryAs<DisjointValueSync*>(kSharedMemory2Id, - kSharedMemory2Offset, - sizeof(*disjoint_sync)); - manager_->SetDisjointSync(kSharedMemory2Id, kSharedMemory2Offset); + decoder_->GetSharedMemoryAs<DisjointValueSync*>( + shared_memory2_id_, kSharedMemory2Offset, sizeof(*disjoint_sync)); + manager_->SetDisjointSync(shared_memory2_id_, kSharedMemory2Offset); const uint32_t current_disjoint_value = disjoint_sync->GetDisjointCount(); ASSERT_EQ(0u, current_disjoint_value); @@ -880,7 +814,7 @@ TEST_F(QueryManagerManualSetupTest, TimeStampDisjoint) { const base::subtle::Atomic32 kSubmitCount = 123; QueryManager::Query* query = manager_->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); // Disjoint happening before the query should not trigger a disjoint event. @@ -913,10 +847,9 @@ TEST_F(QueryManagerManualSetupTest, DisjointContinualTest) { SetUpMockGL("GL_EXT_disjoint_timer_query"); DisjointValueSync* disjoint_sync = - decoder_->GetSharedMemoryAs<DisjointValueSync*>(kSharedMemory2Id, - kSharedMemory2Offset, - sizeof(*disjoint_sync)); - manager_->SetDisjointSync(kSharedMemory2Id, kSharedMemory2Offset); + decoder_->GetSharedMemoryAs<DisjointValueSync*>( + shared_memory2_id_, kSharedMemory2Offset, sizeof(*disjoint_sync)); + manager_->SetDisjointSync(shared_memory2_id_, kSharedMemory2Offset); const uint32_t current_disjoint_value = disjoint_sync->GetDisjointCount(); ASSERT_EQ(0u, current_disjoint_value); @@ -931,7 +864,7 @@ TEST_F(QueryManagerManualSetupTest, DisjointContinualTest) { const base::subtle::Atomic32 kSubmitCount = 123; QueryManager::Query* query = manager_->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false); @@ -958,12 +891,12 @@ TEST_F(QueryManagerTest, GetErrorQuery) { new QueryManager(decoder_.get(), feature_info.get())); QueryManager::Query* query = manager->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); // Setup shared memory like client would. QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>( - kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync)); + shared_memory_id_, kSharedMemoryOffset, sizeof(*sync)); ASSERT_TRUE(sync != NULL); sync->Reset(); @@ -999,10 +932,10 @@ TEST_F(QueryManagerTest, OcclusionQuery) { new QueryManager(decoder_.get(), feature_info.get())); EXPECT_CALL(*gl_, GenQueries(1, _)) - .WillOnce(SetArgumentPointee<1>(kService1Id)) + .WillOnce(SetArgPointee<1>(kService1Id)) .RetiresOnSaturation(); QueryManager::Query* query = manager->CreateQuery( - kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset); ASSERT_TRUE(query != NULL); EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id)) diff --git a/chromium/gpu/command_buffer/service/scheduler.cc b/chromium/gpu/command_buffer/service/scheduler.cc new file mode 100644 index 00000000000..b77287d430c --- /dev/null +++ b/chromium/gpu/command_buffer/service/scheduler.cc @@ -0,0 +1,499 @@ +// Copyright (c) 2017 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/scheduler.h" + +#include <algorithm> + +#include "base/callback.h" +#include "base/memory/ptr_util.h" +#include "base/stl_util.h" +#include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_argument.h" +#include "gpu/command_buffer/service/sync_point_manager.h" + +namespace gpu { + +class Scheduler::Sequence { + public: + Sequence(SequenceId sequence_id, + SchedulingPriority priority, + scoped_refptr<SyncPointOrderData> order_data); + + ~Sequence(); + + SequenceId sequence_id() const { return sequence_id_; } + + const SchedulingState& scheduling_state() const { return scheduling_state_; } + + bool enabled() const { return enabled_; } + + bool scheduled() const { return running_state_ == SCHEDULED; } + + bool running() const { return running_state_ == RUNNING; } + + // The sequence is runnable if its enabled and has tasks which are not blocked + // by wait fences. + bool IsRunnable() const; + + bool NeedsRescheduling() const; + + void UpdateSchedulingState(); + + // If this sequence runs before the other sequence. + bool RunsBefore(const Sequence* other) const; + + void SetEnabled(bool enabled); + + // Sets running state to SCHEDULED. + void SetScheduled(); + + // Called before running the next task on the sequence. Returns the closure + // for the task. Sets running state to RUNNING. + base::OnceClosure BeginTask(); + + // Called after running the closure returned by BeginTask. Sets running state + // to IDLE. + void FinishTask(); + + // Enqueues a task in the sequence and returns the generated order number. + uint32_t ScheduleTask(base::OnceClosure closure); + + // Continue running the current task with the given closure. Must be called in + // between |BeginTask| and |FinishTask|. + void ContinueTask(base::OnceClosure closure); + + // Add a sync token fence that this sequence should wait on. + void AddWaitFence(const SyncToken& sync_token, uint32_t order_num); + + // Remove a waiting sync token fence. + void RemoveWaitFence(const SyncToken& sync_token, uint32_t order_num); + + // Add a sync token fence that this sequence is expected to release. + void AddReleaseFence(const SyncToken& sync_token, uint32_t order_num); + + // Remove a release sync token fence. + void RemoveReleaseFence(const SyncToken& sync_token, uint32_t order_num); + + private: + enum RunningState { IDLE, SCHEDULED, RUNNING }; + + struct Fence { + SyncToken sync_token; + uint32_t order_num; + + bool operator==(const Fence& other) const { + return std::tie(sync_token, order_num) == + std::tie(other.sync_token, other.order_num); + } + }; + + struct Task { + base::OnceClosure closure; + uint32_t order_num; + }; + + SchedulingPriority GetSchedulingPriority() const; + + // If the sequence is enabled. Sequences are disabled/enabled based on when + // the command buffer is descheduled/scheduled. + bool enabled_ = true; + + RunningState running_state_ = IDLE; + + // Cached scheduling state used for comparison with other sequences using + // |RunsBefore|. Updated in |UpdateSchedulingState|. + SchedulingState scheduling_state_; + + const SequenceId sequence_id_; + + const SchedulingPriority priority_; + + scoped_refptr<SyncPointOrderData> order_data_; + + // Deque of tasks. Tasks are inserted at the back with increasing order number + // generated from SyncPointOrderData. If a running task needs to be continued, + // it is inserted at the front with the same order number. + std::deque<Task> tasks_; + + // List of fences that this sequence is waiting on. Fences are inserted in + // increasing order number but may be removed out of order. Tasks are blocked + // if there's a wait fence with order number less than or equal to the task's + // order number. + std::vector<Fence> wait_fences_; + + // List of fences that this sequence is expected to release. If this list is + // non-empty, the priority of the sequence is raised. + std::vector<Fence> release_fences_; + + DISALLOW_COPY_AND_ASSIGN(Sequence); +}; + +Scheduler::SchedulingState::SchedulingState() = default; +Scheduler::SchedulingState::SchedulingState(const SchedulingState& other) = + default; +Scheduler::SchedulingState::~SchedulingState() = default; + +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> +Scheduler::SchedulingState::AsValue() const { + std::unique_ptr<base::trace_event::TracedValue> state( + new base::trace_event::TracedValue()); + state->SetInteger("sequence_id", sequence_id.GetUnsafeValue()); + state->SetString("priority", SchedulingPriorityToString(priority)); + state->SetInteger("order_num", order_num); + return std::move(state); +} + +Scheduler::Sequence::Sequence(SequenceId sequence_id, + SchedulingPriority priority, + scoped_refptr<SyncPointOrderData> order_data) + : sequence_id_(sequence_id), + priority_(priority), + order_data_(std::move(order_data)) {} + +Scheduler::Sequence::~Sequence() { + order_data_->Destroy(); +} + +bool Scheduler::Sequence::NeedsRescheduling() const { + return running_state_ != IDLE && + scheduling_state_.priority != GetSchedulingPriority(); +} + +bool Scheduler::Sequence::IsRunnable() const { + return enabled_ && !tasks_.empty() && + (wait_fences_.empty() || + wait_fences_.front().order_num > tasks_.front().order_num); +} + +SchedulingPriority Scheduler::Sequence::GetSchedulingPriority() const { + if (!release_fences_.empty()) + return std::min(priority_, SchedulingPriority::kHigh); + return priority_; +} + +bool Scheduler::Sequence::RunsBefore(const Scheduler::Sequence* other) const { + return scheduling_state_.RunsBefore(other->scheduling_state()); +} + +void Scheduler::Sequence::SetEnabled(bool enabled) { + if (enabled_ == enabled) + return; + DCHECK_EQ(running_state_, enabled ? IDLE : RUNNING); + enabled_ = enabled; +} + +void Scheduler::Sequence::SetScheduled() { + DCHECK_NE(running_state_, RUNNING); + running_state_ = SCHEDULED; + UpdateSchedulingState(); +} + +void Scheduler::Sequence::UpdateSchedulingState() { + scheduling_state_.sequence_id = sequence_id_; + scheduling_state_.priority = GetSchedulingPriority(); + + uint32_t order_num = UINT32_MAX; // IDLE + if (running_state_ == SCHEDULED) { + DCHECK(!tasks_.empty()); + order_num = tasks_.front().order_num; + } else if (running_state_ == RUNNING) { + order_num = order_data_->current_order_num(); + } + scheduling_state_.order_num = order_num; +} + +void Scheduler::Sequence::ContinueTask(base::OnceClosure closure) { + DCHECK_EQ(running_state_, RUNNING); + tasks_.push_front({std::move(closure), order_data_->current_order_num()}); +} + +uint32_t Scheduler::Sequence::ScheduleTask(base::OnceClosure closure) { + uint32_t order_num = order_data_->GenerateUnprocessedOrderNumber(); + tasks_.push_back({std::move(closure), order_num}); + return order_num; +} + +base::OnceClosure Scheduler::Sequence::BeginTask() { + DCHECK(!tasks_.empty()); + + DCHECK_EQ(running_state_, SCHEDULED); + running_state_ = RUNNING; + + base::OnceClosure closure = std::move(tasks_.front().closure); + uint32_t order_num = tasks_.front().order_num; + tasks_.pop_front(); + + order_data_->BeginProcessingOrderNumber(order_num); + + UpdateSchedulingState(); + + return closure; +} + +void Scheduler::Sequence::FinishTask() { + DCHECK_EQ(running_state_, RUNNING); + running_state_ = IDLE; + uint32_t order_num = order_data_->current_order_num(); + if (!tasks_.empty() && tasks_.front().order_num == order_num) { + order_data_->PauseProcessingOrderNumber(order_num); + } else { + order_data_->FinishProcessingOrderNumber(order_num); + } + UpdateSchedulingState(); +} + +void Scheduler::Sequence::AddWaitFence(const SyncToken& sync_token, + uint32_t order_num) { + wait_fences_.push_back({sync_token, order_num}); +} + +void Scheduler::Sequence::RemoveWaitFence(const SyncToken& sync_token, + uint32_t order_num) { + base::Erase(wait_fences_, Fence{sync_token, order_num}); +} + +void Scheduler::Sequence::AddReleaseFence(const SyncToken& sync_token, + uint32_t order_num) { + release_fences_.push_back({sync_token, order_num}); +} + +void Scheduler::Sequence::RemoveReleaseFence(const SyncToken& sync_token, + uint32_t order_num) { + base::Erase(release_fences_, Fence{sync_token, order_num}); +} + +Scheduler::Scheduler(scoped_refptr<base::SingleThreadTaskRunner> task_runner, + SyncPointManager* sync_point_manager) + : task_runner_(std::move(task_runner)), + sync_point_manager_(sync_point_manager), + weak_factory_(this) { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +Scheduler::~Scheduler() { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +SequenceId Scheduler::CreateSequence(SchedulingPriority priority) { + DCHECK(thread_checker_.CalledOnValidThread()); + base::AutoLock auto_lock(lock_); + scoped_refptr<SyncPointOrderData> order_data = + sync_point_manager_->CreateSyncPointOrderData(); + SequenceId sequence_id = order_data->sequence_id(); + auto sequence = + base::MakeUnique<Sequence>(sequence_id, priority, std::move(order_data)); + sequences_.emplace(sequence_id, std::move(sequence)); + return sequence_id; +} + +void Scheduler::DestroySequence(SequenceId sequence_id) { + DCHECK(thread_checker_.CalledOnValidThread()); + base::AutoLock auto_lock(lock_); + + Sequence* sequence = GetSequence(sequence_id); + DCHECK(sequence); + if (sequence->scheduled()) + rebuild_scheduling_queue_ = true; + + sequences_.erase(sequence_id); +} + +Scheduler::Sequence* Scheduler::GetSequence(SequenceId sequence_id) { + lock_.AssertAcquired(); + auto it = sequences_.find(sequence_id); + if (it != sequences_.end()) + return it->second.get(); + return nullptr; +} + +void Scheduler::EnableSequence(SequenceId sequence_id) { + DCHECK(thread_checker_.CalledOnValidThread()); + base::AutoLock auto_lock(lock_); + Sequence* sequence = GetSequence(sequence_id); + DCHECK(sequence); + sequence->SetEnabled(true); + TryScheduleSequence(sequence); +} + +void Scheduler::DisableSequence(SequenceId sequence_id) { + DCHECK(thread_checker_.CalledOnValidThread()); + base::AutoLock auto_lock(lock_); + Sequence* sequence = GetSequence(sequence_id); + DCHECK(sequence); + sequence->SetEnabled(false); +} + +void Scheduler::ScheduleTask(SequenceId sequence_id, + base::OnceClosure closure, + const std::vector<SyncToken>& sync_token_fences) { + base::AutoLock auto_lock(lock_); + Sequence* sequence = GetSequence(sequence_id); + DCHECK(sequence); + + uint32_t order_num = sequence->ScheduleTask(std::move(closure)); + + for (const SyncToken& sync_token : sync_token_fences) { + SequenceId release_id = + sync_point_manager_->GetSyncTokenReleaseSequenceId(sync_token); + Sequence* release_sequence = GetSequence(release_id); + if (!release_sequence) + continue; + if (sync_point_manager_->Wait( + sync_token, order_num, + base::Bind(&Scheduler::SyncTokenFenceReleased, + weak_factory_.GetWeakPtr(), sync_token, order_num, + release_id, sequence_id))) { + sequence->AddWaitFence(sync_token, order_num); + release_sequence->AddReleaseFence(sync_token, order_num); + TryScheduleSequence(release_sequence); + } + } + + TryScheduleSequence(sequence); +} + +void Scheduler::ContinueTask(SequenceId sequence_id, + base::OnceClosure closure) { + DCHECK(thread_checker_.CalledOnValidThread()); + base::AutoLock auto_lock(lock_); + Sequence* sequence = GetSequence(sequence_id); + DCHECK(sequence); + sequence->ContinueTask(std::move(closure)); +} + +bool Scheduler::ShouldYield(SequenceId sequence_id) { + DCHECK(thread_checker_.CalledOnValidThread()); + base::AutoLock auto_lock(lock_); + + Sequence* sequence = GetSequence(sequence_id); + DCHECK(sequence); + DCHECK(sequence->running()); + + if (should_yield_) + return true; + + RebuildSchedulingQueue(); + + sequence->UpdateSchedulingState(); + + if (!scheduling_queue_.empty()) { + Sequence* next_sequence = + GetSequence(scheduling_queue_.front().sequence_id); + DCHECK(next_sequence); + if (next_sequence->RunsBefore(sequence)) + should_yield_ = true; + } + + return should_yield_; +} + +void Scheduler::SyncTokenFenceReleased(const SyncToken& sync_token, + uint32_t order_num, + SequenceId release_sequence_id, + SequenceId waiting_sequence_id) { + base::AutoLock auto_lock(lock_); + Sequence* sequence = GetSequence(waiting_sequence_id); + if (sequence) { + sequence->RemoveWaitFence(sync_token, order_num); + TryScheduleSequence(sequence); + } + Sequence* release_sequence = GetSequence(release_sequence_id); + if (release_sequence) { + release_sequence->RemoveReleaseFence(sync_token, order_num); + TryScheduleSequence(release_sequence); + } +} + +void Scheduler::TryScheduleSequence(Sequence* sequence) { + lock_.AssertAcquired(); + + if (sequence->running()) + return; + + if (sequence->NeedsRescheduling()) { + DCHECK(sequence->IsRunnable()); + rebuild_scheduling_queue_ = true; + } else if (!sequence->scheduled() && sequence->IsRunnable()) { + sequence->SetScheduled(); + scheduling_queue_.push_back(sequence->scheduling_state()); + std::push_heap(scheduling_queue_.begin(), scheduling_queue_.end(), + &SchedulingState::Comparator); + } + + if (!running_) { + TRACE_EVENT_ASYNC_BEGIN0("gpu", "Scheduler::Running", this); + running_ = true; + task_runner_->PostTask(FROM_HERE, base::Bind(&Scheduler::RunNextTask, + weak_factory_.GetWeakPtr())); + } +} + +void Scheduler::RebuildSchedulingQueue() { + DCHECK(thread_checker_.CalledOnValidThread()); + lock_.AssertAcquired(); + + if (!rebuild_scheduling_queue_) + return; + rebuild_scheduling_queue_ = false; + + scheduling_queue_.clear(); + for (const auto& kv : sequences_) { + Sequence* sequence = kv.second.get(); + if (!sequence->IsRunnable() || sequence->running()) + continue; + sequence->SetScheduled(); + scheduling_queue_.push_back(sequence->scheduling_state()); + } + + std::make_heap(scheduling_queue_.begin(), scheduling_queue_.end(), + &SchedulingState::Comparator); +} + +void Scheduler::RunNextTask() { + DCHECK(thread_checker_.CalledOnValidThread()); + base::AutoLock auto_lock(lock_); + + should_yield_ = false; + + RebuildSchedulingQueue(); + + if (scheduling_queue_.empty()) { + TRACE_EVENT_ASYNC_END0("gpu", "Scheduler::Running", this); + running_ = false; + return; + } + + std::pop_heap(scheduling_queue_.begin(), scheduling_queue_.end(), + &SchedulingState::Comparator); + SchedulingState state = scheduling_queue_.back(); + scheduling_queue_.pop_back(); + + TRACE_EVENT1("gpu", "Scheduler::RunNextTask", "state", state.AsValue()); + + DCHECK(GetSequence(state.sequence_id)); + base::OnceClosure closure = GetSequence(state.sequence_id)->BeginTask(); + + { + base::AutoUnlock auto_unlock(lock_); + std::move(closure).Run(); + } + + // Check if sequence hasn't been destroyed. + Sequence* sequence = GetSequence(state.sequence_id); + if (sequence) { + sequence->FinishTask(); + if (sequence->IsRunnable()) { + sequence->SetScheduled(); + scheduling_queue_.push_back(sequence->scheduling_state()); + std::push_heap(scheduling_queue_.begin(), scheduling_queue_.end(), + &SchedulingState::Comparator); + } + } + + task_runner_->PostTask(FROM_HERE, base::Bind(&Scheduler::RunNextTask, + weak_factory_.GetWeakPtr())); +} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/scheduler.h b/chromium/gpu/command_buffer/service/scheduler.h new file mode 100644 index 00000000000..c6dab1cf58e --- /dev/null +++ b/chromium/gpu/command_buffer/service/scheduler.h @@ -0,0 +1,138 @@ +// Copyright (c) 2017 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_SERVICE_SCHEDULER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_SCHEDULER_H_ + +#include <queue> +#include <vector> + +#include "base/callback.h" +#include "base/containers/flat_map.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/synchronization/lock.h" +#include "base/threading/thread_checker.h" +#include "gpu/command_buffer/common/scheduling_priority.h" +#include "gpu/command_buffer/common/sync_token.h" +#include "gpu/command_buffer/service/sequence_id.h" +#include "gpu/gpu_export.h" + +namespace base { +class SingleThreadTaskRunner; +namespace trace_event { +class ConvertableToTraceFormat; +} +} + +namespace gpu { +class SyncPointManager; + +class GPU_EXPORT Scheduler { + public: + Scheduler(scoped_refptr<base::SingleThreadTaskRunner> task_runner, + SyncPointManager* sync_point_manager); + + virtual ~Scheduler(); + + // Create a sequence with given priority. Returns an identifier for the + // sequence that can be used with SyncPonintManager for creating sync point + // release clients. Sequences start off as enabled (see |EnableSequence|). + SequenceId CreateSequence(SchedulingPriority priority); + + // Destroy the sequence and run any scheduled tasks immediately. + void DestroySequence(SequenceId sequence_id); + + // Enables the sequence so that its tasks may be scheduled. + void EnableSequence(SequenceId sequence_id); + + // Disables the sequence. + void DisableSequence(SequenceId sequence_id); + + // Schedules task (closure) to run on the sequence. The task is blocked until + // the sync token fences are released or determined to be invalid. Tasks are + // run in the order in which they are submitted. + void ScheduleTask(SequenceId sequence_id, + base::OnceClosure closure, + const std::vector<SyncToken>& sync_token_fences); + + // Continue running task on the sequence with the closure. This must be called + // while running a previously scheduled task. + void ContinueTask(SequenceId sequence_id, base::OnceClosure closure); + + // If the sequence should yield so that a higher priority sequence may run. + bool ShouldYield(SequenceId sequence_id); + + private: + class Sequence; + + struct SchedulingState { + static bool Comparator(const SchedulingState& lhs, + const SchedulingState& rhs) { + return rhs.RunsBefore(lhs); + } + + SchedulingState(); + SchedulingState(const SchedulingState& other); + ~SchedulingState(); + + bool RunsBefore(const SchedulingState& other) const { + return std::tie(priority, order_num) < + std::tie(other.priority, other.order_num); + } + + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() + const; + + SequenceId sequence_id; + SchedulingPriority priority = SchedulingPriority::kLowest; + uint32_t order_num = 0; + }; + + void SyncTokenFenceReleased(const SyncToken& sync_token, + uint32_t order_num, + SequenceId release_sequence_id, + SequenceId waiting_sequence_id); + + void TryScheduleSequence(Sequence* sequence); + + void RebuildSchedulingQueue(); + + Sequence* GetSequence(SequenceId sequence_id); + + void RunNextTask(); + + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + SyncPointManager* const sync_point_manager_; + + mutable base::Lock lock_; + + // The following are protected by |lock_|. + bool running_ = false; + + base::flat_map<SequenceId, std::unique_ptr<Sequence>> sequences_; + + // Used as a priority queue for scheduling sequences. Min heap of + // SchedulingState with highest priority (lowest order) in front. + std::vector<SchedulingState> scheduling_queue_; + + // If the running sequence should yield so that a higher priority sequence can + // run. + bool should_yield_ = false; + + // If the scheduling queue needs to be rebuild because a sequence changed + // priority. + bool rebuild_scheduling_queue_ = false; + + base::ThreadChecker thread_checker_; + + base::WeakPtrFactory<Scheduler> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(Scheduler); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_SCHEDULER_H_ diff --git a/chromium/gpu/command_buffer/service/scheduler_unittest.cc b/chromium/gpu/command_buffer/service/scheduler_unittest.cc new file mode 100644 index 00000000000..43328b33577 --- /dev/null +++ b/chromium/gpu/command_buffer/service/scheduler_unittest.cc @@ -0,0 +1,335 @@ +// Copyright (c) 2017 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/scheduler.h" + +#include <algorithm> + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/test/test_simple_task_runner.h" +#include "gpu/command_buffer/service/sync_point_manager.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { +namespace { + +template <typename T> +void RunFunctor(T functor) { + functor(); +} + +template <typename T> +base::OnceClosure GetClosure(T functor) { + return base::BindOnce(&RunFunctor<T>, functor); +} + +class SchedulerTest : public testing::Test { + public: + SchedulerTest() + : task_runner_(new base::TestSimpleTaskRunner()), + sync_point_manager_(new SyncPointManager), + scheduler_(new Scheduler(task_runner_, sync_point_manager_.get())) {} + + protected: + base::TestSimpleTaskRunner* task_runner() const { return task_runner_.get(); } + + SyncPointManager* sync_point_manager() const { + return sync_point_manager_.get(); + } + + Scheduler* scheduler() const { return scheduler_.get(); } + + private: + scoped_refptr<base::TestSimpleTaskRunner> task_runner_; + std::unique_ptr<SyncPointManager> sync_point_manager_; + std::unique_ptr<Scheduler> scheduler_; +}; + +TEST_F(SchedulerTest, ScheduledTasksRunInOrder) { + SequenceId sequence_id = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + + bool ran1 = false; + scheduler()->ScheduleTask(sequence_id, GetClosure([&] { ran1 = true; }), + std::vector<SyncToken>()); + + bool ran2 = false; + scheduler()->ScheduleTask(sequence_id, GetClosure([&] { ran2 = true; }), + std::vector<SyncToken>()); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran1); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran2); +} + +TEST_F(SchedulerTest, ContinuedTasksRunFirst) { + SequenceId sequence_id = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + + bool ran1 = false; + bool continued1 = false; + scheduler()->ScheduleTask(sequence_id, GetClosure([&] { + scheduler()->ContinueTask( + sequence_id, + GetClosure([&] { continued1 = true; })); + ran1 = true; + }), + std::vector<SyncToken>()); + + bool ran2 = false; + scheduler()->ScheduleTask(sequence_id, GetClosure([&] { ran2 = true; }), + std::vector<SyncToken>()); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran1); + EXPECT_FALSE(continued1); + EXPECT_FALSE(ran2); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(continued1); + EXPECT_FALSE(ran2); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran2); +} + +TEST_F(SchedulerTest, SequencesRunInPriorityOrder) { + SequenceId sequence_id1 = + scheduler()->CreateSequence(SchedulingPriority::kLowest); + bool ran1 = false; + scheduler()->ScheduleTask(sequence_id1, GetClosure([&] { ran1 = true; }), + std::vector<SyncToken>()); + + SequenceId sequence_id2 = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + bool ran2 = false; + scheduler()->ScheduleTask(sequence_id2, GetClosure([&] { ran2 = true; }), + std::vector<SyncToken>()); + + SequenceId sequence_id3 = + scheduler()->CreateSequence(SchedulingPriority::kHighest); + bool ran3 = false; + scheduler()->ScheduleTask(sequence_id3, GetClosure([&] { ran3 = true; }), + std::vector<SyncToken>()); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran3); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran2); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran1); +} + +TEST_F(SchedulerTest, SequencesOfSamePriorityRunInOrder) { + SequenceId sequence_id1 = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + bool ran1 = false; + scheduler()->ScheduleTask(sequence_id1, GetClosure([&] { ran1 = true; }), + std::vector<SyncToken>()); + + SequenceId sequence_id2 = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + bool ran2 = false; + scheduler()->ScheduleTask(sequence_id2, GetClosure([&] { ran2 = true; }), + std::vector<SyncToken>()); + + SequenceId sequence_id3 = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + bool ran3 = false; + scheduler()->ScheduleTask(sequence_id3, GetClosure([&] { ran3 = true; }), + std::vector<SyncToken>()); + + SequenceId sequence_id4 = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + bool ran4 = false; + scheduler()->ScheduleTask(sequence_id4, GetClosure([&] { ran4 = true; }), + std::vector<SyncToken>()); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran1); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran2); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran3); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran4); +} + +TEST_F(SchedulerTest, SequenceWaitsForFence) { + SequenceId sequence_id1 = + scheduler()->CreateSequence(SchedulingPriority::kHighest); + SequenceId sequence_id2 = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + + CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO; + CommandBufferId command_buffer_id = CommandBufferId::FromUnsafeValue(1); + + scoped_refptr<SyncPointClientState> release_state = + sync_point_manager()->CreateSyncPointClientState( + namespace_id, command_buffer_id, sequence_id2); + + uint64_t release = 1; + bool ran2 = false; + scheduler()->ScheduleTask(sequence_id2, GetClosure([&] { + release_state->ReleaseFenceSync(release); + ran2 = true; + }), + std::vector<SyncToken>()); + + SyncToken sync_token(namespace_id, 0 /* extra_data_field */, + command_buffer_id, release); + + bool ran1 = false; + scheduler()->ScheduleTask(sequence_id1, GetClosure([&] { ran1 = true; }), + {sync_token}); + + task_runner()->RunPendingTasks(); + EXPECT_FALSE(ran1); + EXPECT_TRUE(ran2); + EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(sync_token)); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran1); + + release_state->Destroy(); +} + +TEST_F(SchedulerTest, SequenceDoesNotWaitForInvalidFence) { + SequenceId sequence_id1 = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + + SequenceId sequence_id2 = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO; + CommandBufferId command_buffer_id = CommandBufferId::FromUnsafeValue(1); + scoped_refptr<SyncPointClientState> release_state = + sync_point_manager()->CreateSyncPointClientState( + namespace_id, command_buffer_id, sequence_id2); + + uint64_t release = 1; + SyncToken sync_token(namespace_id, 0 /* extra_data_field */, + command_buffer_id, release); + + bool ran1 = false; + scheduler()->ScheduleTask(sequence_id1, GetClosure([&] { ran1 = true; }), + {sync_token}); + + // Release task is scheduled after wait task so release is treated as non- + // existent. + bool ran2 = false; + scheduler()->ScheduleTask(sequence_id2, GetClosure([&] { + release_state->ReleaseFenceSync(release); + ran2 = true; + }), + std::vector<SyncToken>()); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran1); + EXPECT_FALSE(ran2); + EXPECT_FALSE(sync_point_manager()->IsSyncTokenReleased(sync_token)); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran2); + EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(sync_token)); + + release_state->Destroy(); +} + +TEST_F(SchedulerTest, ReleaseSequenceIsPrioritized) { + SequenceId sequence_id1 = + scheduler()->CreateSequence(SchedulingPriority::kNormal); + + bool ran1 = false; + scheduler()->ScheduleTask(sequence_id1, GetClosure([&] { ran1 = true; }), + std::vector<SyncToken>()); + + SequenceId sequence_id2 = + scheduler()->CreateSequence(SchedulingPriority::kLowest); + CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO; + CommandBufferId command_buffer_id = CommandBufferId::FromUnsafeValue(1); + scoped_refptr<SyncPointClientState> release_state = + sync_point_manager()->CreateSyncPointClientState( + namespace_id, command_buffer_id, sequence_id2); + + uint64_t release = 1; + bool ran2 = false; + scheduler()->ScheduleTask(sequence_id2, GetClosure([&] { + release_state->ReleaseFenceSync(release); + ran2 = true; + }), + std::vector<SyncToken>()); + + bool ran3 = false; + SyncToken sync_token(namespace_id, 0 /* extra_data_field */, + command_buffer_id, release); + SequenceId sequence_id3 = + scheduler()->CreateSequence(SchedulingPriority::kHighest); + scheduler()->ScheduleTask(sequence_id3, GetClosure([&] { ran3 = true; }), + {sync_token}); + + task_runner()->RunPendingTasks(); + EXPECT_FALSE(ran1); + EXPECT_TRUE(ran2); + EXPECT_FALSE(ran3); + EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(sync_token)); + + task_runner()->RunPendingTasks(); + EXPECT_FALSE(ran1); + EXPECT_TRUE(ran3); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran1); + + release_state->Destroy(); +} + +TEST_F(SchedulerTest, ReleaseSequenceShouldYield) { + SequenceId sequence_id1 = + scheduler()->CreateSequence(SchedulingPriority::kLowest); + CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO; + CommandBufferId command_buffer_id = CommandBufferId::FromUnsafeValue(1); + scoped_refptr<SyncPointClientState> release_state = + sync_point_manager()->CreateSyncPointClientState( + namespace_id, command_buffer_id, sequence_id1); + + uint64_t release = 1; + bool ran1 = false; + scheduler()->ScheduleTask( + sequence_id1, GetClosure([&] { + EXPECT_FALSE(scheduler()->ShouldYield(sequence_id1)); + release_state->ReleaseFenceSync(release); + EXPECT_TRUE(scheduler()->ShouldYield(sequence_id1)); + ran1 = true; + }), + std::vector<SyncToken>()); + + bool ran2 = false; + SyncToken sync_token(namespace_id, 0 /* extra_data_field */, + command_buffer_id, release); + SequenceId sequence_id2 = + scheduler()->CreateSequence(SchedulingPriority::kHighest); + scheduler()->ScheduleTask(sequence_id2, GetClosure([&] { ran2 = true; }), + {sync_token}); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran1); + EXPECT_FALSE(ran2); + EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(sync_token)); + + task_runner()->RunPendingTasks(); + EXPECT_TRUE(ran2); + + release_state->Destroy(); +} + +} // namespace +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/service_discardable_manager.cc b/chromium/gpu/command_buffer/service/service_discardable_manager.cc new file mode 100644 index 00000000000..18810e6cef5 --- /dev/null +++ b/chromium/gpu/command_buffer/service/service_discardable_manager.cc @@ -0,0 +1,177 @@ +// Copyright (c) 2017 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/service_discardable_manager.h" + +#include "base/memory/singleton.h" +#include "gpu/command_buffer/service/texture_manager.h" + +namespace gpu { + +const size_t ServiceDiscardableManager::kMaxSize; + +ServiceDiscardableManager::GpuDiscardableEntry::GpuDiscardableEntry( + ServiceDiscardableHandle handle, + size_t size) + : handle(handle), size(size) {} +ServiceDiscardableManager::GpuDiscardableEntry::GpuDiscardableEntry( + const GpuDiscardableEntry& other) = default; +ServiceDiscardableManager::GpuDiscardableEntry::GpuDiscardableEntry( + GpuDiscardableEntry&& other) = default; +ServiceDiscardableManager::GpuDiscardableEntry::~GpuDiscardableEntry() = + default; + +ServiceDiscardableManager::ServiceDiscardableManager() + : entries_(EntryCache::NO_AUTO_EVICT) {} +ServiceDiscardableManager::~ServiceDiscardableManager() { +#if DCHECK_IS_ON() + for (const auto& entry : entries_) { + DCHECK(nullptr == entry.second.unlocked_texture_ref); + } +#endif +} + +void ServiceDiscardableManager::InsertLockedTexture( + uint32_t texture_id, + size_t texture_size, + gles2::TextureManager* texture_manager, + ServiceDiscardableHandle handle) { + auto found = entries_.Get({texture_id, texture_manager}); + if (found != entries_.end()) { + // We have somehow initialized a texture twice. The client *shouldn't* send + // this command, but if it does, we will clean up the old entry and use + // the new one. + total_size_ -= found->second.size; + if (found->second.unlocked_texture_ref) { + texture_manager->ReturnTexture( + std::move(found->second.unlocked_texture_ref)); + } + entries_.Erase(found); + } + + total_size_ += texture_size; + entries_.Put({texture_id, texture_manager}, + GpuDiscardableEntry{handle, texture_size}); + EnforceLimits(); +} + +bool ServiceDiscardableManager::UnlockTexture( + uint32_t texture_id, + gles2::TextureManager* texture_manager, + gles2::TextureRef** texture_to_unbind) { + *texture_to_unbind = nullptr; + + auto found = entries_.Get({texture_id, texture_manager}); + if (found == entries_.end()) + return false; + + found->second.handle.Unlock(); + if (--found->second.service_ref_count_ == 0) { + found->second.unlocked_texture_ref = + texture_manager->TakeTexture(texture_id); + *texture_to_unbind = found->second.unlocked_texture_ref.get(); + } + + return true; +} + +bool ServiceDiscardableManager::LockTexture( + uint32_t texture_id, + gles2::TextureManager* texture_manager) { + auto found = entries_.Peek({texture_id, texture_manager}); + if (found == entries_.end()) + return false; + + ++found->second.service_ref_count_; + if (found->second.unlocked_texture_ref) { + texture_manager->ReturnTexture( + std::move(found->second.unlocked_texture_ref)); + } + + return true; +} + +void ServiceDiscardableManager::OnTextureManagerDestruction( + gles2::TextureManager* texture_manager) { + for (auto& entry : entries_) { + if (entry.first.texture_manager == texture_manager && + entry.second.unlocked_texture_ref) { + texture_manager->ReturnTexture( + std::move(entry.second.unlocked_texture_ref)); + } + } +} + +void ServiceDiscardableManager::OnTextureDeleted( + uint32_t texture_id, + gles2::TextureManager* texture_manager) { + auto found = entries_.Get({texture_id, texture_manager}); + if (found == entries_.end()) + return; + + found->second.handle.ForceDelete(); + total_size_ -= found->second.size; + entries_.Erase(found); +} + +void ServiceDiscardableManager::OnTextureSizeChanged( + uint32_t texture_id, + gles2::TextureManager* texture_manager, + size_t new_size) { + auto found = entries_.Get({texture_id, texture_manager}); + if (found == entries_.end()) + return; + + total_size_ -= found->second.size; + found->second.size = new_size; + total_size_ += found->second.size; + + EnforceLimits(); +} + +void ServiceDiscardableManager::EnforceLimits() { + for (auto it = entries_.rbegin(); it != entries_.rend();) { + if (total_size_ <= kMaxSize) { + return; + } + if (!it->second.handle.Delete()) { + ++it; + continue; + } + + total_size_ -= it->second.size; + + gles2::TextureManager* texture_manager = it->first.texture_manager; + uint32_t texture_id = it->first.texture_id; + + // While unlocked, we hold the texture ref. Return this to the texture + // manager for cleanup. + texture_manager->ReturnTexture(std::move(it->second.unlocked_texture_ref)); + + // Erase before calling texture_manager->RemoveTexture, to avoid attempting + // to remove the texture from entries_ twice. + it = entries_.Erase(it); + texture_manager->RemoveTexture(texture_id); + } +} + +bool ServiceDiscardableManager::IsEntryLockedForTesting( + uint32_t texture_id, + gles2::TextureManager* texture_manager) const { + auto found = entries_.Peek({texture_id, texture_manager}); + DCHECK(found != entries_.end()); + + return found->second.handle.IsLockedForTesting(); +} + +gles2::TextureRef* ServiceDiscardableManager::UnlockedTextureRefForTesting( + uint32_t texture_id, + gles2::TextureManager* texture_manager) const { + auto found = entries_.Peek({texture_id, texture_manager}); + DCHECK(found != entries_.end()); + + return found->second.unlocked_texture_ref.get(); +} + +} // namespace gpu diff --git a/chromium/gpu/command_buffer/service/service_discardable_manager.h b/chromium/gpu/command_buffer/service/service_discardable_manager.h new file mode 100644 index 00000000000..d8fe6f46479 --- /dev/null +++ b/chromium/gpu/command_buffer/service/service_discardable_manager.h @@ -0,0 +1,114 @@ +// Copyright (c) 2017 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_SERVICE_SERVICE_DISCARDABLE_MANAGER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_SERVICE_DISCARDABLE_MANAGER_H_ + +#include <vector> + +#include "base/containers/mru_cache.h" +#include "gpu/command_buffer/common/discardable_handle.h" +#include "gpu/command_buffer/service/context_group.h" +#include "gpu/gpu_export.h" + +namespace gpu { +namespace gles2 { +class TextureManager; +class TextureRef; +} + +class GPU_EXPORT ServiceDiscardableManager { + public: + ServiceDiscardableManager(); + ~ServiceDiscardableManager(); + + void InsertLockedTexture(uint32_t texture_id, + size_t texture_size, + gles2::TextureManager* texture_manager, + ServiceDiscardableHandle handle); + + // Unlocks the indicated texture. If *|texture_to_unbind| is not nullptr, + // ServiceDiscardableManager has taken ownership of the given texture, and + // it is the callers responsibility to unbind it from any other objects. + // Returns false if the given texture_id has not been initialized for use + // with discardable. + bool UnlockTexture(uint32_t texture_id, + gles2::TextureManager* texture_manager, + gles2::TextureRef** texture_to_unbind); + // Locks the indicated texture, allowing it to be used in future GL commands. + // Returns false if the given texture_id has not been initialized for use + // with discardable. + bool LockTexture(uint32_t texture_id, gles2::TextureManager* texture_manager); + + // Returns all unlocked texture refs to the texture_manager for deletion. + // After this point, this class will have no references to the given + // |texture_manager|. + void OnTextureManagerDestruction(gles2::TextureManager* texture_manager); + + // Called when a texture is deleted, to clean up state. + void OnTextureDeleted(uint32_t texture_id, + gles2::TextureManager* texture_manager); + + // Called by the TextureManager when a texture's size changes. + void OnTextureSizeChanged(uint32_t texture_id, + gles2::TextureManager* texture_manager, + size_t new_size); + + // Test only functions: + size_t NumCacheEntriesForTesting() const { return entries_.size(); } + bool IsEntryLockedForTesting(uint32_t texture_id, + gles2::TextureManager* texture_manager) const; + size_t TotalSizeForTesting() const { return total_size_; } + gles2::TextureRef* UnlockedTextureRefForTesting( + uint32_t texture_id, + gles2::TextureManager* texture_manager) const; + + // TODO(ericrk): Arbitrary limit, refine this once we actually use this class + // in production. crbug.com/706456 + static const size_t kMaxSize = 256 * 1024 * 1024; + + private: + void EnforceLimits(); + + struct GpuDiscardableEntry { + public: + GpuDiscardableEntry(ServiceDiscardableHandle handle, size_t size); + GpuDiscardableEntry(const GpuDiscardableEntry& other); + GpuDiscardableEntry(GpuDiscardableEntry&& other); + ~GpuDiscardableEntry(); + + ServiceDiscardableHandle handle; + scoped_refptr<gles2::TextureRef> unlocked_texture_ref; + // The current ref count of this object with regards to command buffer + // execution. May be out of sync with the handle's refcount, as the handle + // can be locked out of band with the command buffer. + uint32_t service_ref_count_ = 1; + size_t size; + }; + struct GpuDiscardableEntryKey { + uint32_t texture_id; + gles2::TextureManager* texture_manager; + }; + struct GpuDiscardableEntryKeyCompare { + bool operator()(const GpuDiscardableEntryKey& lhs, + const GpuDiscardableEntryKey& rhs) const { + return std::tie(lhs.texture_manager, lhs.texture_id) < + std::tie(rhs.texture_manager, rhs.texture_id); + } + }; + using EntryCache = base::MRUCache<GpuDiscardableEntryKey, + GpuDiscardableEntry, + GpuDiscardableEntryKeyCompare>; + EntryCache entries_; + + // Total size of all |entries_|. The same as summing + // GpuDiscardableEntry::size for each entry. + size_t total_size_ = 0; + + DISALLOW_COPY_AND_ASSIGN(ServiceDiscardableManager); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_SERVICE_DISCARDABLE_MANAGER_H_ diff --git a/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc b/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc new file mode 100644 index 00000000000..b09a3596119 --- /dev/null +++ b/chromium/gpu/command_buffer/service/service_discardable_manager_unittest.cc @@ -0,0 +1,455 @@ +// Copyright (c) 2017 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/service_discardable_manager.h" + +#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" +#include "gpu/command_buffer/service/gpu_service_test.h" +#include "gpu/command_buffer/service/mailbox_manager.h" +#include "gpu/command_buffer/service/memory_tracking.h" +#include "gpu/command_buffer/service/mocks.h" +#include "gpu/command_buffer/service/test_helper.h" +#include "gpu/command_buffer/service/texture_manager.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gl/gl_image_stub.h" +#include "ui/gl/gl_mock.h" +#include "ui/gl/gl_switches.h" + +using ::testing::Pointee; +using ::testing::_; +using ::testing::Invoke; +using ::testing::Mock; +using ::testing::InSequence; + +namespace gpu { +namespace gles2 { +namespace { + +void CreateLockedHandlesForTesting( + std::unique_ptr<ServiceDiscardableHandle>* service_handle, + std::unique_ptr<ClientDiscardableHandle>* client_handle) { + std::unique_ptr<base::SharedMemory> shared_mem(new base::SharedMemory); + shared_mem->CreateAndMapAnonymous(sizeof(uint32_t)); + scoped_refptr<gpu::Buffer> buffer = + MakeBufferFromSharedMemory(std::move(shared_mem), sizeof(uint32_t)); + + client_handle->reset(new ClientDiscardableHandle(buffer, 0, 0)); + service_handle->reset(new ServiceDiscardableHandle(buffer, 0, 0)); +} + +ServiceDiscardableHandle CreateLockedServiceHandleForTesting() { + std::unique_ptr<ServiceDiscardableHandle> service_handle; + std::unique_ptr<ClientDiscardableHandle> client_handle; + CreateLockedHandlesForTesting(&service_handle, &client_handle); + return *service_handle; +} + +class MockDestructionObserver : public TextureManager::DestructionObserver { + public: + MOCK_METHOD1(OnTextureManagerDestroying, void(TextureManager* manager)); + MOCK_METHOD1(OnTextureRefDestroying, void(TextureRef* ref)); +}; + +// A small texture that should never run up against our limits. +static const uint32_t kSmallTextureDim = 16; +static const size_t kSmallTextureSize = 4 * kSmallTextureDim * kSmallTextureDim; + +} // namespace + +class ServiceDiscardableManagerTest : public GpuServiceTest { + public: + ServiceDiscardableManagerTest() {} + ~ServiceDiscardableManagerTest() override {} + + protected: + void SetUp() override { + GpuServiceTest::SetUp(); + decoder_.reset(new MockGLES2Decoder()); + feature_info_ = new FeatureInfo(); + context_group_ = scoped_refptr<ContextGroup>(new ContextGroup( + gpu_preferences_, nullptr, nullptr, nullptr, nullptr, feature_info_, + false, nullptr, nullptr, GpuFeatureInfo(), &discardable_manager_)); + TestHelper::SetupContextGroupInitExpectations( + gl_.get(), DisallowedFeatures(), "", "", CONTEXT_TYPE_OPENGLES2, false); + context_group_->Initialize(decoder_.get(), CONTEXT_TYPE_OPENGLES2, + DisallowedFeatures()); + texture_manager_ = context_group_->texture_manager(); + texture_manager_->AddObserver(&destruction_observer_); + } + + void TearDown() override { + EXPECT_CALL(destruction_observer_, OnTextureManagerDestroying(_)) + .RetiresOnSaturation(); + // Texture manager will destroy the 6 black/default textures. + EXPECT_CALL(*gl_, DeleteTextures(TextureManager::kNumDefaultTextures, _)); + + context_group_->Destroy(decoder_.get(), true); + context_group_ = nullptr; + EXPECT_EQ(0u, discardable_manager_.NumCacheEntriesForTesting()); + GpuServiceTest::TearDown(); + } + + void ExpectUnlockedTextureDeletion(uint32_t client_id) { + TextureRef* ref = discardable_manager_.UnlockedTextureRefForTesting( + client_id, texture_manager_); + ExpectTextureRefDeletion(ref); + } + + void ExpectTextureDeletion(uint32_t client_id) { + TextureRef* ref = texture_manager_->GetTexture(client_id); + ExpectTextureRefDeletion(ref); + } + + void ExpectTextureRefDeletion(TextureRef* ref) { + EXPECT_NE(nullptr, ref); + ref->AddObserver(); + EXPECT_CALL(destruction_observer_, OnTextureRefDestroying(ref)) + .WillOnce(Invoke([](TextureRef* ref) { ref->RemoveObserver(); })); + EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(ref->service_id()))) + .RetiresOnSaturation(); + } + + ServiceDiscardableManager discardable_manager_; + GpuPreferences gpu_preferences_; + scoped_refptr<FeatureInfo> feature_info_; + MockDestructionObserver destruction_observer_; + TextureManager* texture_manager_; + std::unique_ptr<MockGLES2Decoder> decoder_; + scoped_refptr<gles2::ContextGroup> context_group_; +}; + +TEST_F(ServiceDiscardableManagerTest, BasicUsage) { + const GLuint kClientId = 1; + const GLuint kServiceId = 2; + + // Create and insert a new texture. + texture_manager_->CreateTexture(kClientId, kServiceId); + auto handle = CreateLockedServiceHandleForTesting(); + discardable_manager_.InsertLockedTexture(kClientId, kSmallTextureSize, + texture_manager_, handle); + EXPECT_EQ(1u, discardable_manager_.NumCacheEntriesForTesting()); + EXPECT_TRUE(discardable_manager_.IsEntryLockedForTesting(kClientId, + texture_manager_)); + EXPECT_NE(nullptr, texture_manager_->GetTexture(kClientId)); + + // Unlock the texture, ServiceDiscardableManager should take ownership of the + // TextureRef. + gles2::TextureRef* texture_to_unbind; + EXPECT_TRUE(discardable_manager_.UnlockTexture(kClientId, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_FALSE(discardable_manager_.IsEntryLockedForTesting(kClientId, + texture_manager_)); + EXPECT_EQ(nullptr, texture_manager_->GetTexture(kClientId)); + + // Re-lock the texture, the TextureManager should now resume ownership of + // the TextureRef. + discardable_manager_.LockTexture(kClientId, texture_manager_); + EXPECT_NE(nullptr, texture_manager_->GetTexture(kClientId)); + + // Delete the texture from the TextureManager, it should also be removed from + // the ServiceDiscardableManager. + ExpectTextureDeletion(kClientId); + texture_manager_->RemoveTexture(kClientId); + EXPECT_EQ(0u, discardable_manager_.NumCacheEntriesForTesting()); +} + +TEST_F(ServiceDiscardableManagerTest, DeleteAtShutdown) { + // Create 8 small textures (which will not hit memory limits), leaving every + // other one unlocked. + for (int i = 1; i <= 8; ++i) { + texture_manager_->CreateTexture(i, i); + auto handle = CreateLockedServiceHandleForTesting(); + discardable_manager_.InsertLockedTexture(i, kSmallTextureSize, + texture_manager_, handle); + if (i % 2) { + TextureRef* texture_to_unbind; + EXPECT_TRUE(discardable_manager_.UnlockTexture(i, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + } + } + + // Expect that all 8 will be deleted at shutdown, regardless of + // locked/unlocked state. + for (int i = 1; i <= 8; ++i) { + if (i % 2) { + ExpectUnlockedTextureDeletion(i); + } else { + ExpectTextureDeletion(i); + } + } + + // Let the test shut down, the expectations should be fulfilled. +} + +TEST_F(ServiceDiscardableManagerTest, UnlockInvalid) { + const GLuint kClientId = 1; + gles2::TextureRef* texture_to_unbind; + EXPECT_FALSE(discardable_manager_.UnlockTexture(kClientId, texture_manager_, + &texture_to_unbind)); + EXPECT_EQ(nullptr, texture_to_unbind); +} + +TEST_F(ServiceDiscardableManagerTest, Limits) { + // Size textures so that four fit in the discardable manager. + const size_t texture_size = ServiceDiscardableManager::kMaxSize / 4; + const size_t large_texture_size = 3 * texture_size; + + // Create 4 textures, this should fill up the discardable cache. + for (int i = 1; i < 5; ++i) { + texture_manager_->CreateTexture(i, i); + auto handle = CreateLockedServiceHandleForTesting(); + discardable_manager_.InsertLockedTexture(i, texture_size, texture_manager_, + handle); + } + + gles2::TextureRef* texture_to_unbind; + EXPECT_TRUE(discardable_manager_.UnlockTexture(3, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_TRUE(discardable_manager_.UnlockTexture(1, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_TRUE(discardable_manager_.UnlockTexture(2, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_TRUE(discardable_manager_.UnlockTexture(4, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + + // Allocate four more textures - the previous 4 should be evicted / deleted in + // LRU order. + { + InSequence s; + ExpectUnlockedTextureDeletion(3); + ExpectUnlockedTextureDeletion(1); + ExpectUnlockedTextureDeletion(2); + ExpectUnlockedTextureDeletion(4); + } + + for (int i = 5; i < 9; ++i) { + texture_manager_->CreateTexture(i, i); + auto handle = CreateLockedServiceHandleForTesting(); + discardable_manager_.InsertLockedTexture(i, texture_size, texture_manager_, + handle); + } + + // Ensure that the above expectations are handled by this point. + Mock::VerifyAndClearExpectations(gl_.get()); + Mock::VerifyAndClearExpectations(&destruction_observer_); + + // Unlock the next four textures: + EXPECT_TRUE(discardable_manager_.UnlockTexture(5, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_TRUE(discardable_manager_.UnlockTexture(6, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_TRUE(discardable_manager_.UnlockTexture(8, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_TRUE(discardable_manager_.UnlockTexture(7, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + + // Allocate one more *large* texture, it should evict the LRU 3 textures. + { + InSequence s; + ExpectUnlockedTextureDeletion(5); + ExpectUnlockedTextureDeletion(6); + ExpectUnlockedTextureDeletion(8); + } + + texture_manager_->CreateTexture(9, 9); + auto handle = CreateLockedServiceHandleForTesting(); + discardable_manager_.InsertLockedTexture(9, large_texture_size, + texture_manager_, handle); + + // Expect the two remaining textures to clean up. + ExpectTextureDeletion(9); + ExpectUnlockedTextureDeletion(7); +} + +TEST_F(ServiceDiscardableManagerTest, TextureSizeChanged) { + const GLuint kClientId = 1; + const GLuint kServiceId = 2; + + texture_manager_->CreateTexture(kClientId, kServiceId); + TextureRef* texture_ref = texture_manager_->GetTexture(kClientId); + auto handle = CreateLockedServiceHandleForTesting(); + discardable_manager_.InsertLockedTexture(kClientId, 0, texture_manager_, + handle); + EXPECT_EQ(0u, discardable_manager_.TotalSizeForTesting()); + texture_manager_->SetTarget(texture_ref, GL_TEXTURE_2D); + texture_manager_->SetLevelInfo(texture_ref, GL_TEXTURE_2D, 0, GL_RGBA, + kSmallTextureDim, kSmallTextureDim, 1, 0, + GL_RGBA, GL_UNSIGNED_BYTE, + gfx::Rect(kSmallTextureDim, kSmallTextureDim)); + EXPECT_EQ(kSmallTextureSize, discardable_manager_.TotalSizeForTesting()); + + ExpectTextureDeletion(kClientId); +} + +TEST_F(ServiceDiscardableManagerTest, OwnershipOnUnlock) { + const GLuint kClientId = 1; + const GLuint kServiceId = 2; + + std::unique_ptr<ServiceDiscardableHandle> service_handle; + std::unique_ptr<ClientDiscardableHandle> client_handle; + CreateLockedHandlesForTesting(&service_handle, &client_handle); + texture_manager_->CreateTexture(kClientId, kServiceId); + discardable_manager_.InsertLockedTexture(kClientId, kSmallTextureSize, + texture_manager_, *service_handle); + + // Ensure that the service ref count is used to determine ownership changes. + client_handle->Lock(); + TextureRef* texture_to_unbind; + discardable_manager_.UnlockTexture(kClientId, texture_manager_, + &texture_to_unbind); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_TRUE(discardable_manager_.IsEntryLockedForTesting(kClientId, + texture_manager_)); + + // Get the counts back in sync. + discardable_manager_.LockTexture(kClientId, texture_manager_); + discardable_manager_.UnlockTexture(kClientId, texture_manager_, + &texture_to_unbind); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_FALSE(discardable_manager_.IsEntryLockedForTesting(kClientId, + texture_manager_)); + + // Re-lock the texture twice. + client_handle->Lock(); + discardable_manager_.LockTexture(kClientId, texture_manager_); + client_handle->Lock(); + discardable_manager_.LockTexture(kClientId, texture_manager_); + + // Ensure that unlocking once doesn't cause us to unbind the texture. + discardable_manager_.UnlockTexture(kClientId, texture_manager_, + &texture_to_unbind); + EXPECT_EQ(nullptr, texture_to_unbind); + EXPECT_TRUE(discardable_manager_.IsEntryLockedForTesting(kClientId, + texture_manager_)); + + // The second unlock should unbind/unlock the texture. + discardable_manager_.UnlockTexture(kClientId, texture_manager_, + &texture_to_unbind); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_FALSE(discardable_manager_.IsEntryLockedForTesting(kClientId, + texture_manager_)); + + ExpectUnlockedTextureDeletion(kClientId); +} + +TEST_F(ServiceDiscardableManagerTest, BindGeneratedTextureLock) { + const GLuint kClientId = 1; + const GLuint kServiceId = 2; + const GLuint kGeneratedServiceId = 3; + + // Create and insert a new texture. + texture_manager_->CreateTexture(kClientId, kServiceId); + auto handle = CreateLockedServiceHandleForTesting(); + discardable_manager_.InsertLockedTexture(kClientId, kSmallTextureSize, + texture_manager_, handle); + + // Unlock the texture, ServiceDiscardableManager should take ownership of the + // TextureRef. + gles2::TextureRef* texture_to_unbind; + EXPECT_TRUE(discardable_manager_.UnlockTexture(kClientId, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_EQ(nullptr, texture_manager_->GetTexture(kClientId)); + + // Generate a new texture for the given client id, similar to "bind generates + // resource" behavior. + texture_manager_->CreateTexture(kClientId, kGeneratedServiceId); + TextureRef* generated_texture_ref = texture_manager_->GetTexture(kClientId); + + // Re-lock the texture, the TextureManager should delete the returned + // texture and keep the generated one. + ExpectUnlockedTextureDeletion(kClientId); + discardable_manager_.LockTexture(kClientId, texture_manager_); + EXPECT_EQ(generated_texture_ref, texture_manager_->GetTexture(kClientId)); + + // Delete the texture from the TextureManager, it should also be removed from + // the ServiceDiscardableManager. + ExpectTextureDeletion(kClientId); + texture_manager_->RemoveTexture(kClientId); + EXPECT_EQ(0u, discardable_manager_.NumCacheEntriesForTesting()); +} + +TEST_F(ServiceDiscardableManagerTest, BindGeneratedTextureInitialization) { + const GLuint kClientId = 1; + const GLuint kServiceId = 2; + const GLuint kGeneratedServiceId = 3; + + // Create and insert a new texture. + texture_manager_->CreateTexture(kClientId, kServiceId); + auto handle = CreateLockedServiceHandleForTesting(); + discardable_manager_.InsertLockedTexture(kClientId, kSmallTextureSize, + texture_manager_, handle); + + // Unlock the texture, ServiceDiscardableManager should take ownership of the + // TextureRef. + gles2::TextureRef* texture_to_unbind; + EXPECT_TRUE(discardable_manager_.UnlockTexture(kClientId, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_EQ(nullptr, texture_manager_->GetTexture(kClientId)); + + // Generate a new texture for the given client id, similar to "bind generates + // resource" behavior. + texture_manager_->CreateTexture(kClientId, kGeneratedServiceId); + TextureRef* generated_texture_ref = texture_manager_->GetTexture(kClientId); + + // Re-initialize the texture, the TextureManager should delete the old + // texture and keep the generated one. + ExpectUnlockedTextureDeletion(kClientId); + discardable_manager_.InsertLockedTexture(kClientId, kSmallTextureSize, + texture_manager_, handle); + EXPECT_EQ(generated_texture_ref, texture_manager_->GetTexture(kClientId)); + + ExpectTextureDeletion(kClientId); +} + +TEST_F(ServiceDiscardableManagerTest, BindGeneratedTextureSizeChange) { + const GLuint kClientId = 1; + const GLuint kServiceId = 2; + const GLuint kGeneratedServiceId = 3; + + // Create and insert a new texture. + texture_manager_->CreateTexture(kClientId, kServiceId); + auto handle = CreateLockedServiceHandleForTesting(); + discardable_manager_.InsertLockedTexture(kClientId, 0, texture_manager_, + handle); + + // Unlock the texture, ServiceDiscardableManager should take ownership of the + // TextureRef. + gles2::TextureRef* texture_to_unbind; + EXPECT_TRUE(discardable_manager_.UnlockTexture(kClientId, texture_manager_, + &texture_to_unbind)); + EXPECT_NE(nullptr, texture_to_unbind); + EXPECT_EQ(nullptr, texture_manager_->GetTexture(kClientId)); + + // Generate a new texture for the given client id, similar to "bind generates + // resource" behavior. + texture_manager_->CreateTexture(kClientId, kGeneratedServiceId); + TextureRef* generated_texture_ref = texture_manager_->GetTexture(kClientId); + + // Re-size the generated texture. The tracked size should update. + EXPECT_EQ(0u, discardable_manager_.TotalSizeForTesting()); + texture_manager_->SetTarget(generated_texture_ref, GL_TEXTURE_2D); + texture_manager_->SetLevelInfo(generated_texture_ref, GL_TEXTURE_2D, 0, + GL_RGBA, kSmallTextureDim, kSmallTextureDim, 1, + 0, GL_RGBA, GL_UNSIGNED_BYTE, + gfx::Rect(kSmallTextureDim, kSmallTextureDim)); + EXPECT_EQ(kSmallTextureSize, discardable_manager_.TotalSizeForTesting()); + + ExpectUnlockedTextureDeletion(kClientId); + ExpectTextureDeletion(kClientId); +} + +} // namespace gles2 +} // namespace gpu
\ No newline at end of file diff --git a/chromium/gpu/command_buffer/service/shader_manager.cc b/chromium/gpu/command_buffer/service/shader_manager.cc index 38f371764a7..8a77b519998 100644 --- a/chromium/gpu/command_buffer/service/shader_manager.cc +++ b/chromium/gpu/command_buffer/service/shader_manager.cc @@ -75,7 +75,7 @@ void Shader::DoCompile() { bool success = translator->Translate( last_compiled_source_, &log_info_, &translated_source_, &shader_version_, &attrib_map_, &uniform_map_, &varying_map_, - &interface_block_map_, &output_variable_list_, &name_map_); + &interface_block_map_, &output_variable_list_); if (!success) { return; } @@ -224,19 +224,22 @@ const std::string* Shader::GetOutputVariableMappedName( const std::string* Shader::GetOriginalNameFromHashedName( const std::string& hashed_name) const { - NameMap::const_iterator it = name_map_.find(hashed_name); - if (it != name_map_.end()) - return &(it->second); - return NULL; -} - -const std::string* Shader::GetMappedName( - const std::string& original_name) const { - for (const auto& key_value : name_map_) { - if (key_value.second == original_name) - return &(key_value.first); + if (const auto* info = GetAttribInfo(hashed_name)) { + return &info->name; } - return NULL; + if (const auto* info = GetUniformInfo(hashed_name)) { + return &info->name; + } + if (const auto* info = GetVaryingInfo(hashed_name)) { + return &info->name; + } + if (const auto* info = GetInterfaceBlockInfo(hashed_name)) { + return &info->name; + } + if (const auto* info = GetOutputVariableInfo(hashed_name)) { + return &info->name; + } + return nullptr; } const sh::Uniform* Shader::GetUniformInfo(const std::string& name) const { diff --git a/chromium/gpu/command_buffer/service/shader_manager.h b/chromium/gpu/command_buffer/service/shader_manager.h index 29d50660a24..c9c2df3a469 100644 --- a/chromium/gpu/command_buffer/service/shader_manager.h +++ b/chromium/gpu/command_buffer/service/shader_manager.h @@ -121,12 +121,10 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { const std::string& original_name) const; // If the hashed_name is not found, return NULL. + // Use this only when one of the more specific Get*Info methods can't be used. const std::string* GetOriginalNameFromHashedName( const std::string& hashed_name) const; - const std::string* GetMappedName( - const std::string& original_name) const; - const std::string& log_info() const { return log_info_; } @@ -259,9 +257,7 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { VaryingMap varying_map_; InterfaceBlockMap interface_block_map_; OutputVariableList output_variable_list_; - - // The name hashing info when the shader was last compiled. - NameMap name_map_; + // If a new info type is added, add it to GetOriginalNameFromHashedName. }; // Tracks the Shaders. diff --git a/chromium/gpu/command_buffer/service/shader_manager_unittest.cc b/chromium/gpu/command_buffer/service/shader_manager_unittest.cc index 64b61852f02..bbf14703316 100644 --- a/chromium/gpu/command_buffer/service/shader_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/shader_manager_unittest.cc @@ -130,6 +130,18 @@ TEST_F(ShaderManagerTest, DoCompile) { const char* kOutputVariable1Name = "gl_FragColor"; const bool kOutputVariable1StaticUse = true; + const GLint kInterfaceBlock1Size = 1; + const sh::BlockLayoutType kInterfaceBlock1Layout = sh::BLOCKLAYOUT_STANDARD; + const bool kInterfaceBlock1RowMajor = false; + const bool kInterfaceBlock1StaticUse = false; + const char* kInterfaceBlock1Name = "block1"; + const char* kInterfaceBlock1InstanceName = "block1instance"; + const GLenum kInterfaceBlock1Field1Type = GL_FLOAT_VEC4; + const GLint kInterfaceBlock1Field1Size = 1; + const GLenum kInterfaceBlock1Field1Precision = GL_MEDIUM_FLOAT; + const char* kInterfaceBlock1Field1Name = "field1"; + const bool kInterfaceBlock1Field1StaticUse = false; + // Check we can create shader. Shader* shader1 = manager_.CreateShader( kClient1Id, kService1Id, kShader1Type); @@ -194,9 +206,24 @@ TEST_F(ShaderManagerTest, DoCompile) { output_variable_list.push_back(TestHelper::ConstructOutputVariable( kOutputVariable1Type, kOutputVariable1Size, kOutputVariable1Precision, kOutputVariable1StaticUse, kOutputVariable1Name)); + + InterfaceBlockMap interface_block_map; + std::vector<sh::InterfaceBlockField> interface_block1_fields; + interface_block1_fields.push_back(TestHelper::ConstructInterfaceBlockField( + kInterfaceBlock1Field1Type, kInterfaceBlock1Field1Size, + kInterfaceBlock1Field1Precision, kInterfaceBlock1Field1StaticUse, + kInterfaceBlock1Field1Name)); + interface_block_map[kInterfaceBlock1Name] = + TestHelper::ConstructInterfaceBlock( + kInterfaceBlock1Size, kInterfaceBlock1Layout, + kInterfaceBlock1RowMajor, kInterfaceBlock1StaticUse, + kInterfaceBlock1Name, kInterfaceBlock1InstanceName, + interface_block1_fields); + TestHelper::SetShaderStates( gl_.get(), shader1, true, &kLog, &kTranslatedSource, nullptr, &attrib_map, - &uniform_map, &varying_map, nullptr, &output_variable_list, nullptr); + &uniform_map, &varying_map, &interface_block_map, &output_variable_list); + EXPECT_TRUE(shader1->valid()); // When compilation succeeds, no log is recorded. EXPECT_STREQ("", shader1->log_info().c_str()); @@ -214,6 +241,8 @@ TEST_F(ShaderManagerTest, DoCompile) { EXPECT_EQ(it->second.precision, variable_info->precision); EXPECT_EQ(it->second.staticUse, variable_info->staticUse); EXPECT_STREQ(it->second.name.c_str(), variable_info->name.c_str()); + EXPECT_STREQ(it->second.name.c_str(), + shader1->GetOriginalNameFromHashedName(it->first)->c_str()); } // Check uniform infos got copied. EXPECT_EQ(uniform_map.size(), shader1->uniform_map().size()); @@ -226,6 +255,8 @@ TEST_F(ShaderManagerTest, DoCompile) { EXPECT_EQ(it->second.precision, variable_info->precision); EXPECT_EQ(it->second.staticUse, variable_info->staticUse); EXPECT_STREQ(it->second.name.c_str(), variable_info->name.c_str()); + EXPECT_STREQ(it->second.name.c_str(), + shader1->GetOriginalNameFromHashedName(it->first)->c_str()); } // Check varying infos got copied. EXPECT_EQ(varying_map.size(), shader1->varying_map().size()); @@ -238,6 +269,42 @@ TEST_F(ShaderManagerTest, DoCompile) { EXPECT_EQ(it->second.precision, variable_info->precision); EXPECT_EQ(it->second.staticUse, variable_info->staticUse); EXPECT_STREQ(it->second.name.c_str(), variable_info->name.c_str()); + EXPECT_STREQ(it->second.name.c_str(), + shader1->GetOriginalNameFromHashedName(it->first)->c_str()); + } + // Check interface block infos got copied. + EXPECT_EQ(interface_block_map.size(), shader1->interface_block_map().size()); + for (const auto& it : interface_block_map) { + const sh::InterfaceBlock* block_info = + shader1->GetInterfaceBlockInfo(it.first); + ASSERT_TRUE(block_info != NULL); + EXPECT_EQ(it.second.arraySize, block_info->arraySize); + EXPECT_EQ(it.second.layout, block_info->layout); + EXPECT_EQ(it.second.isRowMajorLayout, block_info->isRowMajorLayout); + EXPECT_EQ(it.second.staticUse, block_info->staticUse); + EXPECT_STREQ(it.second.name.c_str(), block_info->name.c_str()); + EXPECT_STREQ(it.second.name.c_str(), + shader1->GetOriginalNameFromHashedName(it.first)->c_str()); + EXPECT_STREQ(it.second.instanceName.c_str(), + block_info->instanceName.c_str()); + } + // Check interface block field infos got copied. + const sh::InterfaceBlock* interface_block1_info = + shader1->GetInterfaceBlockInfo(kInterfaceBlock1Name); + EXPECT_EQ(interface_block1_fields.size(), + interface_block1_info->fields.size()); + for (size_t f = 0; f < interface_block1_fields.size(); ++f) { + const auto& exp = interface_block1_fields[f]; + const auto& act = interface_block1_info->fields[f]; + EXPECT_EQ(exp.type, act.type); + EXPECT_EQ(exp.arraySize, act.arraySize); + EXPECT_EQ(exp.precision, act.precision); + EXPECT_EQ(exp.staticUse, act.staticUse); + EXPECT_STREQ(exp.name.c_str(), act.name.c_str()); + std::string full_name = interface_block1_info->name + "." + act.name; + auto* original_basename = shader1->GetOriginalNameFromHashedName(full_name); + ASSERT_TRUE(original_basename != nullptr); + EXPECT_STREQ(kInterfaceBlock1Name, original_basename->c_str()); } // Check output variable infos got copied. EXPECT_EQ(output_variable_list.size(), @@ -252,13 +319,15 @@ TEST_F(ShaderManagerTest, DoCompile) { EXPECT_EQ(it->precision, variable_info->precision); EXPECT_EQ(it->staticUse, variable_info->staticUse); EXPECT_STREQ(it->name.c_str(), variable_info->name.c_str()); + EXPECT_STREQ( + it->name.c_str(), + shader1->GetOriginalNameFromHashedName(it->mappedName)->c_str()); } // Compile failure case. - TestHelper::SetShaderStates(gl_.get(), shader1, false, &kLog, - &kTranslatedSource, nullptr, &attrib_map, - &uniform_map, &varying_map, nullptr, - &output_variable_list, nullptr); + TestHelper::SetShaderStates( + gl_.get(), shader1, false, &kLog, &kTranslatedSource, nullptr, + &attrib_map, &uniform_map, &varying_map, nullptr, &output_variable_list); EXPECT_FALSE(shader1->valid()); EXPECT_STREQ(kLog.c_str(), shader1->log_info().c_str()); EXPECT_STREQ("", shader1->translated_source().c_str()); diff --git a/chromium/gpu/command_buffer/service/shader_translator.cc b/chromium/gpu/command_buffer/service/shader_translator.cc index 3d3012de0fc..40f45e8d104 100644 --- a/chromium/gpu/command_buffer/service/shader_translator.cc +++ b/chromium/gpu/command_buffer/service/shader_translator.cc @@ -90,23 +90,6 @@ void GetInterfaceBlocks(ShHandle compiler, InterfaceBlockMap* var_map) { } } -void GetNameHashingInfo(ShHandle compiler, NameMap* name_map) { - if (!name_map) - return; - name_map->clear(); - - typedef std::map<std::string, std::string> NameMapANGLE; - const NameMapANGLE* angle_map = sh::GetNameHashingMap(compiler); - DCHECK(angle_map); - - for (NameMapANGLE::const_iterator iter = angle_map->begin(); - iter != angle_map->end(); ++iter) { - // Note that in ANGLE, the map is (original_name, hash); - // here, we want (hash, original_name). - (*name_map)[iter->second] = iter->first; - } -} - } // namespace ShShaderOutput ShaderTranslator::GetShaderOutputLanguageForContext( @@ -209,16 +192,16 @@ ShCompileOptions ShaderTranslator::GetCompileOptions() const { return compile_options_; } -bool ShaderTranslator::Translate(const std::string& shader_source, - std::string* info_log, - std::string* translated_source, - int* shader_version, - AttributeMap* attrib_map, - UniformMap* uniform_map, - VaryingMap* varying_map, - InterfaceBlockMap* interface_block_map, - OutputVariableList* output_variable_list, - NameMap* name_map) const { +bool ShaderTranslator::Translate( + const std::string& shader_source, + std::string* info_log, + std::string* translated_source, + int* shader_version, + AttributeMap* attrib_map, + UniformMap* uniform_map, + VaryingMap* varying_map, + InterfaceBlockMap* interface_block_map, + OutputVariableList* output_variable_list) const { // Make sure this instance is initialized. DCHECK(compiler_ != NULL); @@ -241,8 +224,6 @@ bool ShaderTranslator::Translate(const std::string& shader_source, GetVaryings(compiler_, varying_map); GetInterfaceBlocks(compiler_, interface_block_map); GetOutputVariables(compiler_, output_variable_list); - // Get info for name hashing. - GetNameHashingInfo(compiler_, name_map); } // Get info log. diff --git a/chromium/gpu/command_buffer/service/shader_translator.h b/chromium/gpu/command_buffer/service/shader_translator.h index a4732d8de54..43ae7df7289 100644 --- a/chromium/gpu/command_buffer/service/shader_translator.h +++ b/chromium/gpu/command_buffer/service/shader_translator.h @@ -27,8 +27,6 @@ typedef std::vector<sh::OutputVariable> OutputVariableList; typedef base::hash_map<std::string, sh::Uniform> UniformMap; typedef base::hash_map<std::string, sh::Varying> VaryingMap; typedef base::hash_map<std::string, sh::InterfaceBlock> InterfaceBlockMap; -// Mapping between hashed name and original name. -typedef base::hash_map<std::string, std::string> NameMap; // Translates a GLSL ES 2.0 shader to desktop GLSL shader, or just // validates GLSL ES 2.0 shaders on a true GLSL ES implementation. @@ -59,8 +57,7 @@ class ShaderTranslatorInterface UniformMap* uniform_map, VaryingMap* varying_map, InterfaceBlockMap* interface_block_map, - OutputVariableList* output_variable_list, - NameMap* name_map) const = 0; + OutputVariableList* output_variable_list) const = 0; // Return a string that is unique for a specfic set of options that would // possibly affect compilation. @@ -112,8 +109,7 @@ class GPU_EXPORT ShaderTranslator UniformMap* uniform_map, VaryingMap* varying_map, InterfaceBlockMap* interface_block_map, - OutputVariableList* output_variable_list, - NameMap* name_map) const override; + OutputVariableList* output_variable_list) const override; std::string GetStringForOptionsThatWouldAffectCompilation() const override; diff --git a/chromium/gpu/command_buffer/service/shader_translator_unittest.cc b/chromium/gpu/command_buffer/service/shader_translator_unittest.cc index e48f6111306..d9e0a418e01 100644 --- a/chromium/gpu/command_buffer/service/shader_translator_unittest.cc +++ b/chromium/gpu/command_buffer/service/shader_translator_unittest.cc @@ -103,11 +103,9 @@ TEST_F(ShaderTranslatorTest, ValidVertexShader) { VaryingMap varying_map; InterfaceBlockMap interface_block_map; OutputVariableList output_variable_list; - NameMap name_map; EXPECT_TRUE(vertex_translator_->Translate( shader, &info_log, &translated_source, &shader_version, &attrib_map, - &uniform_map, &varying_map, &interface_block_map, &output_variable_list, - &name_map)); + &uniform_map, &varying_map, &interface_block_map, &output_variable_list)); // Info log must be NULL. EXPECT_TRUE(info_log.empty()); @@ -120,8 +118,6 @@ TEST_F(ShaderTranslatorTest, ValidVertexShader) { EXPECT_TRUE(interface_block_map.empty()); EXPECT_EQ(1u, varying_map.size()); EXPECT_TRUE(output_variable_list.empty()); - // There should be no name mapping. - EXPECT_TRUE(name_map.empty()); } TEST_F(ShaderTranslatorTest, InvalidVertexShader) { @@ -139,11 +135,9 @@ TEST_F(ShaderTranslatorTest, InvalidVertexShader) { VaryingMap varying_map; InterfaceBlockMap interface_block_map; OutputVariableList output_variable_list; - NameMap name_map; EXPECT_FALSE(vertex_translator_->Translate( bad_shader, &info_log, &translated_source, &shader_version, &attrib_map, - &uniform_map, &varying_map, &interface_block_map, &output_variable_list, - &name_map)); + &uniform_map, &varying_map, &interface_block_map, &output_variable_list)); // Info log must be valid and non-empty. ASSERT_FALSE(info_log.empty()); // Translated shader must be NULL. @@ -155,14 +149,12 @@ TEST_F(ShaderTranslatorTest, InvalidVertexShader) { EXPECT_TRUE(varying_map.empty()); EXPECT_TRUE(interface_block_map.empty()); EXPECT_TRUE(output_variable_list.empty()); - EXPECT_TRUE(name_map.empty()); // Try a good shader after bad. info_log.clear(); EXPECT_TRUE(vertex_translator_->Translate( good_shader, &info_log, &translated_source, &shader_version, &attrib_map, - &uniform_map, &varying_map, &interface_block_map, &output_variable_list, - &name_map)); + &uniform_map, &varying_map, &interface_block_map, &output_variable_list)); EXPECT_TRUE(info_log.empty()); EXPECT_FALSE(translated_source.empty()); EXPECT_TRUE(interface_block_map.empty()); @@ -182,11 +174,9 @@ TEST_F(ShaderTranslatorTest, ValidFragmentShader) { VaryingMap varying_map; InterfaceBlockMap interface_block_map; OutputVariableList output_variable_list; - NameMap name_map; EXPECT_TRUE(fragment_translator_->Translate( shader, &info_log, &translated_source, &shader_version, &attrib_map, - &uniform_map, &varying_map, &interface_block_map, &output_variable_list, - &name_map)); + &uniform_map, &varying_map, &interface_block_map, &output_variable_list)); // Info log must be NULL. EXPECT_TRUE(info_log.empty()); // Translated shader must be valid and non-empty. @@ -197,7 +187,6 @@ TEST_F(ShaderTranslatorTest, ValidFragmentShader) { EXPECT_TRUE(uniform_map.empty()); EXPECT_TRUE(varying_map.empty()); EXPECT_TRUE(interface_block_map.empty()); - EXPECT_TRUE(name_map.empty()); // gl_FragColor. EXPECT_EQ(1u, output_variable_list.size()); } @@ -212,12 +201,10 @@ TEST_F(ShaderTranslatorTest, InvalidFragmentShader) { VaryingMap varying_map; InterfaceBlockMap interface_block_map; OutputVariableList output_variable_list; - NameMap name_map; // An invalid shader should fail. EXPECT_FALSE(fragment_translator_->Translate( shader, &info_log, &translated_source, &shader_version, &attrib_map, - &uniform_map, &varying_map, &interface_block_map, &output_variable_list, - &name_map)); + &uniform_map, &varying_map, &interface_block_map, &output_variable_list)); // Info log must be valid and non-empty. EXPECT_FALSE(info_log.empty()); // Translated shader must be NULL. @@ -228,7 +215,6 @@ TEST_F(ShaderTranslatorTest, InvalidFragmentShader) { EXPECT_TRUE(uniform_map.empty()); EXPECT_TRUE(varying_map.empty()); EXPECT_TRUE(output_variable_list.empty()); - EXPECT_TRUE(name_map.empty()); } TEST_F(ShaderTranslatorTest, GetAttributes) { @@ -245,11 +231,9 @@ TEST_F(ShaderTranslatorTest, GetAttributes) { VaryingMap varying_map; InterfaceBlockMap interface_block_map; OutputVariableList output_variable_list; - NameMap name_map; EXPECT_TRUE(vertex_translator_->Translate( shader, &info_log, &translated_source, &shader_version, &attrib_map, - &uniform_map, &varying_map, &interface_block_map, &output_variable_list, - &name_map)); + &uniform_map, &varying_map, &interface_block_map, &output_variable_list)); // Info log must be NULL. EXPECT_TRUE(info_log.empty()); // Translated shader must be valid and non-empty. @@ -289,11 +273,9 @@ TEST_F(ShaderTranslatorTest, GetUniforms) { VaryingMap varying_map; InterfaceBlockMap interface_block_map; OutputVariableList output_variable_list; - NameMap name_map; EXPECT_TRUE(fragment_translator_->Translate( shader, &info_log, &translated_source, &shader_version, &attrib_map, - &uniform_map, &varying_map, &interface_block_map, &output_variable_list, - &name_map)); + &uniform_map, &varying_map, &interface_block_map, &output_variable_list)); // Info log must be NULL. EXPECT_TRUE(info_log.empty()); // Translated shader must be valid and non-empty. @@ -357,11 +339,9 @@ TEST_F(ES3ShaderTranslatorTest, InvalidInterfaceBlocks) { VaryingMap varying_map; InterfaceBlockMap interface_block_map; OutputVariableList output_variable_list; - NameMap name_map; EXPECT_FALSE(fragment_translator_->Translate( shader, &info_log, &translated_source, &shader_version, &attrib_map, - &uniform_map, &varying_map, &interface_block_map, &output_variable_list, - &name_map)); + &uniform_map, &varying_map, &interface_block_map, &output_variable_list)); // Info log must be valid and non-empty. ASSERT_FALSE(info_log.empty()); // Translated shader must be NULL. @@ -372,7 +352,6 @@ TEST_F(ES3ShaderTranslatorTest, InvalidInterfaceBlocks) { EXPECT_TRUE(uniform_map.empty()); EXPECT_TRUE(varying_map.empty()); EXPECT_TRUE(interface_block_map.empty()); - EXPECT_TRUE(name_map.empty()); } TEST_F(ES3ShaderTranslatorTest, GetInterfaceBlocks) { @@ -396,11 +375,9 @@ TEST_F(ES3ShaderTranslatorTest, GetInterfaceBlocks) { VaryingMap varying_map; InterfaceBlockMap interface_block_map; OutputVariableList output_variable_list; - NameMap name_map; EXPECT_TRUE(fragment_translator_->Translate( shader, &info_log, &translated_source, &shader_version, &attrib_map, - &uniform_map, &varying_map, &interface_block_map, &output_variable_list, - &name_map)); + &uniform_map, &varying_map, &interface_block_map, &output_variable_list)); // Info log must be NULL. EXPECT_TRUE(info_log.empty()); // Translated shader must be valid and non-empty. @@ -488,7 +465,7 @@ TEST_F(ShaderTranslatorOutputVersionTest, DISABLED_CompatibilityOutput) { EXPECT_TRUE(vertex_translator->Translate( kShader, nullptr, &translated_source, &shader_version, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr)); + nullptr, nullptr, nullptr)); EXPECT_TRUE(translated_source.find("#version") == std::string::npos); if (translated_source.find("gl_Position =") == std::string::npos) { ADD_FAILURE() << "Did not find gl_Position initialization."; @@ -506,7 +483,7 @@ TEST_F(ShaderTranslatorOutputVersionTest, DISABLED_CompatibilityOutput) { EXPECT_TRUE(fragment_translator->Translate( kShader, nullptr, &translated_source, &shader_version, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr)); + nullptr, nullptr, nullptr)); EXPECT_TRUE(translated_source.find("#version 120") != std::string::npos); if (translated_source.find("#pragma STDGL invariant(all)") != std::string::npos) { @@ -544,7 +521,7 @@ TEST_P(ShaderTranslatorOutputVersionTest, HasCorrectOutputGLSLVersion) { int shader_version; EXPECT_TRUE(translator->Translate(kShader, nullptr, &translated_source, &shader_version, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr)); + nullptr, nullptr)); std::string expected_version_directive = testing::get<1>(GetParam()); if (expected_version_directive.empty()) { diff --git a/chromium/gpu/command_buffer/service/test_helper.cc b/chromium/gpu/command_buffer/service/test_helper.cc index dc4e3ac59f7..f98ca32c4a1 100644 --- a/chromium/gpu/command_buffer/service/test_helper.cc +++ b/chromium/gpu/command_buffer/service/test_helper.cc @@ -33,7 +33,7 @@ using ::testing::Pointee; using ::testing::NotNull; using ::testing::Return; using ::testing::SetArrayArgument; -using ::testing::SetArgumentPointee; +using ::testing::SetArgPointee; using ::testing::SetArgPointee; using ::testing::StrEq; using ::testing::StrictMock; @@ -351,17 +351,17 @@ void TestHelper::SetupContextGroupInitExpectations( SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", gl_version, context_type); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, _)) - .WillOnce(SetArgumentPointee<1>(kMaxRenderbufferSize)) + .WillOnce(SetArgPointee<1>(kMaxRenderbufferSize)) .RetiresOnSaturation(); if (strstr(extensions, "GL_EXT_framebuffer_multisample") || strstr(extensions, "GL_EXT_multisampled_render_to_texture") || gl_info.is_es3 || gl_info.is_desktop_core_profile) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _)) - .WillOnce(SetArgumentPointee<1>(kMaxSamples)) + .WillOnce(SetArgPointee<1>(kMaxSamples)) .RetiresOnSaturation(); } else if (strstr(extensions, "GL_IMG_multisampled_render_to_texture")) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES_IMG, _)) - .WillOnce(SetArgumentPointee<1>(kMaxSamples)) + .WillOnce(SetArgPointee<1>(kMaxSamples)) .RetiresOnSaturation(); } @@ -372,10 +372,10 @@ void TestHelper::SetupContextGroupInitExpectations( strstr(extensions, "GL_ARB_draw_buffers") || (gl_info.is_es3 && strstr(extensions, "GL_NV_draw_buffers"))))) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, _)) - .WillOnce(SetArgumentPointee<1>(8)) + .WillOnce(SetArgPointee<1>(8)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, _)) - .WillOnce(SetArgumentPointee<1>(8)) + .WillOnce(SetArgPointee<1>(8)) .RetiresOnSaturation(); } @@ -384,94 +384,94 @@ void TestHelper::SetupContextGroupInitExpectations( strstr(extensions, "GL_ARB_blend_func_extended")) || (gl_info.is_es && strstr(extensions, "GL_EXT_blend_func_extended"))) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT, _)) - .WillOnce(SetArgumentPointee<1>(8)) + .WillOnce(SetArgPointee<1>(8)) .RetiresOnSaturation(); } if (gl_info.is_es3_capable) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxTransformFeedbackSeparateAttribs)) + .WillOnce(SetArgPointee<1>(kMaxTransformFeedbackSeparateAttribs)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxUniformBufferBindings)) + .WillOnce(SetArgPointee<1>(kMaxUniformBufferBindings)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, _)) - .WillOnce(SetArgumentPointee<1>(kUniformBufferOffsetAlignment)) + .WillOnce(SetArgPointee<1>(kUniformBufferOffsetAlignment)) .RetiresOnSaturation(); } EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _)) - .WillOnce(SetArgumentPointee<1>(kNumVertexAttribs)) + .WillOnce(SetArgPointee<1>(kNumVertexAttribs)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, _)) - .WillOnce(SetArgumentPointee<1>(kNumTextureUnits)) + .WillOnce(SetArgPointee<1>(kNumTextureUnits)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TEXTURE_SIZE, _)) - .WillOnce(SetArgumentPointee<1>(kMaxTextureSize)) + .WillOnce(SetArgPointee<1>(kMaxTextureSize)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, _)) - .WillOnce(SetArgumentPointee<1>(kMaxCubeMapTextureSize)) + .WillOnce(SetArgPointee<1>(kMaxCubeMapTextureSize)) .RetiresOnSaturation(); if (gl_info.is_es3_capable) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_3D_TEXTURE_SIZE, _)) - .WillOnce(SetArgumentPointee<1>(kMax3DTextureSize)) + .WillOnce(SetArgPointee<1>(kMax3DTextureSize)) .RetiresOnSaturation(); } if (gl_info.is_es3_capable) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxArrayTextureLayers)) + .WillOnce(SetArgPointee<1>(kMaxArrayTextureLayers)) .RetiresOnSaturation(); } if (strstr(extensions, "GL_ARB_texture_rectangle") || gl_info.is_desktop_core_profile) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, _)) - .WillOnce(SetArgumentPointee<1>(kMaxRectangleTextureSize)) + .WillOnce(SetArgPointee<1>(kMaxRectangleTextureSize)) .RetiresOnSaturation(); } EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxTextureImageUnits)) + .WillOnce(SetArgPointee<1>(kMaxTextureImageUnits)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxVertexTextureImageUnits)) + .WillOnce(SetArgPointee<1>(kMaxVertexTextureImageUnits)) .RetiresOnSaturation(); if (gl_info.is_es || gl_info.is_desktop_core_profile) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformVectors)) + .WillOnce(SetArgPointee<1>(kMaxFragmentUniformVectors)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_VECTORS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxVaryingVectors)) + .WillOnce(SetArgPointee<1>(kMaxVaryingVectors)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformVectors)) + .WillOnce(SetArgPointee<1>(kMaxVertexUniformVectors)) .RetiresOnSaturation(); } else { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents)) + .WillOnce(SetArgPointee<1>(kMaxFragmentUniformComponents)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats)) + .WillOnce(SetArgPointee<1>(kMaxVaryingFloats)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents)) + .WillOnce(SetArgPointee<1>(kMaxVertexUniformComponents)) .RetiresOnSaturation(); } EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, _)) .Times(testing::Between(0, 1)) - .WillRepeatedly(SetArgumentPointee<1>(kMaxVertexOutputComponents)) + .WillRepeatedly(SetArgPointee<1>(kMaxVertexOutputComponents)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, _)) .Times(testing::Between(0, 1)) - .WillRepeatedly(SetArgumentPointee<1>(kMaxFragmentInputComponents)) + .WillRepeatedly(SetArgPointee<1>(kMaxFragmentInputComponents)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, _)) .Times(testing::Between(0, 1)) - .WillRepeatedly(SetArgumentPointee<1>(kMaxProgramTexelOffset)) + .WillRepeatedly(SetArgPointee<1>(kMaxProgramTexelOffset)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, _)) .Times(testing::Between(0, 1)) - .WillRepeatedly(SetArgumentPointee<1>(kMinProgramTexelOffset)) + .WillRepeatedly(SetArgPointee<1>(kMinProgramTexelOffset)) .RetiresOnSaturation(); bool use_default_textures = bind_generates_resource; @@ -511,7 +511,7 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( gl::GLVersionInfo gl_info(gl_version, gl_renderer, extensions); if (!gl_info.is_es && gl_info.major_version >= 3) { EXPECT_CALL(*gl, GetIntegerv(GL_NUM_EXTENSIONS, _)) - .WillOnce(SetArgumentPointee<1>(split_extensions_.size())) + .WillOnce(SetArgPointee<1>(split_extensions_.size())) .RetiresOnSaturation(); for (size_t ii = 0; ii < split_extensions_.size(); ++ii) { EXPECT_CALL(*gl, GetStringi(GL_EXTENSIONS, ii)) @@ -546,10 +546,10 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( static const GLuint fb_ids[] = {103, 104}; const GLsizei width = 16; EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _)) - .WillOnce(SetArgumentPointee<1>(fb_ids[0])) + .WillOnce(SetArgPointee<1>(fb_ids[0])) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _)) - .WillOnce(SetArgumentPointee<1>(tx_ids[0])) + .WillOnce(SetArgPointee<1>(tx_ids[0])) .RetiresOnSaturation(); EXPECT_CALL(*gl, GenTextures(1, _)) .WillOnce(SetArrayArgument<1>(tx_ids + 1, tx_ids + 2)) @@ -637,8 +637,8 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( .Times(1) .RetiresOnSaturation(); } - - if (!enable_es3 && !strstr(extensions, "GL_EXT_color_buffer_half_float")) { + if (!enable_es3 && !strstr(extensions, "GL_EXT_color_buffer_half_float") && + (gl_info.is_es || gl_info.IsAtLeastGL(3, 0))) { EXPECT_CALL( *gl, TexImage2D(GL_TEXTURE_2D, 0, GL_R16F, width, width, 0, GL_RED, _, _)) @@ -691,10 +691,10 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( strstr(extensions, "GL_ARB_draw_buffers") || (gl_info.is_es3 && strstr(extensions, "GL_NV_draw_buffers"))))) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, _)) - .WillOnce(SetArgumentPointee<1>(8)) + .WillOnce(SetArgPointee<1>(8)) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, _)) - .WillOnce(SetArgumentPointee<1>(8)) + .WillOnce(SetArgPointee<1>(8)) .RetiresOnSaturation(); } @@ -705,10 +705,10 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( static const GLuint fb_ids[] = {103, 104}; const GLsizei width = 1; EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _)) - .WillOnce(SetArgumentPointee<1>(fb_ids[0])) + .WillOnce(SetArgPointee<1>(fb_ids[0])) .RetiresOnSaturation(); EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _)) - .WillOnce(SetArgumentPointee<1>(tx_ids[0])) + .WillOnce(SetArgPointee<1>(tx_ids[0])) .RetiresOnSaturation(); EXPECT_CALL(*gl, GenTextures(1, _)) .WillOnce(SetArrayArgument<1>(tx_ids + 1, tx_ids + 2)) @@ -866,39 +866,32 @@ void TestHelper::SetupProgramSuccessExpectations( ProgramOutputInfo* program_outputs, size_t num_program_outputs, GLuint service_id) { - EXPECT_CALL(*gl, - GetProgramiv(service_id, GL_LINK_STATUS, _)) - .WillOnce(SetArgumentPointee<2>(1)) + EXPECT_CALL(*gl, GetProgramiv(service_id, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(1)) .RetiresOnSaturation(); - EXPECT_CALL(*gl, - GetProgramiv(service_id, GL_INFO_LOG_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(0)) + EXPECT_CALL(*gl, GetProgramiv(service_id, GL_INFO_LOG_LENGTH, _)) + .WillOnce(SetArgPointee<2>(0)) .RetiresOnSaturation(); - EXPECT_CALL(*gl, - GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTES, _)) - .WillOnce(SetArgumentPointee<2>(num_attribs)) + EXPECT_CALL(*gl, GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTES, _)) + .WillOnce(SetArgPointee<2>(num_attribs)) .RetiresOnSaturation(); size_t max_attrib_len = 0; for (size_t ii = 0; ii < num_attribs; ++ii) { size_t len = strlen(attribs[ii].name) + 1; max_attrib_len = std::max(max_attrib_len, len); } - EXPECT_CALL(*gl, - GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(max_attrib_len)) + EXPECT_CALL(*gl, GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) + .WillOnce(SetArgPointee<2>(max_attrib_len)) .RetiresOnSaturation(); for (size_t ii = 0; ii < num_attribs; ++ii) { const AttribInfo& info = attribs[ii]; EXPECT_CALL(*gl, - GetActiveAttrib(service_id, ii, - max_attrib_len, _, _, _, _)) + GetActiveAttrib(service_id, ii, max_attrib_len, _, _, _, _)) .WillOnce(DoAll( - SetArgumentPointee<3>(strlen(info.name)), - SetArgumentPointee<4>(info.size), - SetArgumentPointee<5>(info.type), - SetArrayArgument<6>(info.name, - info.name + strlen(info.name) + 1))) + SetArgPointee<3>(strlen(info.name)), SetArgPointee<4>(info.size), + SetArgPointee<5>(info.type), + SetArrayArgument<6>(info.name, info.name + strlen(info.name) + 1))) .RetiresOnSaturation(); if (!ProgramManager::HasBuiltInPrefix(info.name)) { EXPECT_CALL(*gl, GetAttribLocation(service_id, StrEq(info.name))) @@ -906,9 +899,8 @@ void TestHelper::SetupProgramSuccessExpectations( .RetiresOnSaturation(); } } - EXPECT_CALL(*gl, - GetProgramiv(service_id, GL_ACTIVE_UNIFORMS, _)) - .WillOnce(SetArgumentPointee<2>(num_uniforms)) + EXPECT_CALL(*gl, GetProgramiv(service_id, GL_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgPointee<2>(num_uniforms)) .RetiresOnSaturation(); if (num_uniforms > 0) { @@ -918,15 +910,15 @@ void TestHelper::SetupProgramSuccessExpectations( max_uniform_len = std::max(max_uniform_len, len); } EXPECT_CALL(*gl, GetProgramiv(service_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(max_uniform_len)) + .WillOnce(SetArgPointee<2>(max_uniform_len)) .RetiresOnSaturation(); for (size_t ii = 0; ii < num_uniforms; ++ii) { const UniformInfo& info = uniforms[ii]; EXPECT_CALL(*gl, GetActiveUniform(service_id, ii, max_uniform_len, _, _, _, _)) - .WillOnce(DoAll(SetArgumentPointee<3>(strlen(info.name)), - SetArgumentPointee<4>(info.size), - SetArgumentPointee<5>(info.type), + .WillOnce(DoAll(SetArgPointee<3>(strlen(info.name)), + SetArgPointee<4>(info.size), + SetArgPointee<5>(info.type), SetArrayArgument<6>( info.name, info.name + strlen(info.name) + 1))) .RetiresOnSaturation(); @@ -956,7 +948,7 @@ void TestHelper::SetupProgramSuccessExpectations( if (feature_info->feature_flags().chromium_path_rendering) { EXPECT_CALL(*gl, GetProgramInterfaceiv(service_id, GL_FRAGMENT_INPUT_NV, GL_ACTIVE_RESOURCES, _)) - .WillOnce(SetArgumentPointee<3>(int(num_varyings))) + .WillOnce(SetArgPointee<3>(int(num_varyings))) .RetiresOnSaturation(); size_t max_varying_len = 0; for (size_t ii = 0; ii < num_varyings; ++ii) { @@ -965,13 +957,13 @@ void TestHelper::SetupProgramSuccessExpectations( } EXPECT_CALL(*gl, GetProgramInterfaceiv(service_id, GL_FRAGMENT_INPUT_NV, GL_MAX_NAME_LENGTH, _)) - .WillOnce(SetArgumentPointee<3>(int(max_varying_len))) + .WillOnce(SetArgPointee<3>(int(max_varying_len))) .RetiresOnSaturation(); for (size_t ii = 0; ii < num_varyings; ++ii) { VaryingInfo& info = varyings[ii]; EXPECT_CALL(*gl, GetProgramResourceName(service_id, GL_FRAGMENT_INPUT_NV, ii, max_varying_len, _, _)) - .WillOnce(DoAll(SetArgumentPointee<4>(strlen(info.name)), + .WillOnce(DoAll(SetArgPointee<4>(strlen(info.name)), SetArrayArgument<5>( info.name, info.name + strlen(info.name) + 1))) .RetiresOnSaturation(); @@ -1123,8 +1115,7 @@ void TestHelper::SetShaderStates( const UniformMap* const expected_uniform_map, const VaryingMap* const expected_varying_map, const InterfaceBlockMap* const expected_interface_block_map, - const OutputVariableList* const expected_output_variable_list, - const NameMap* const expected_name_map) { + const OutputVariableList* const expected_output_variable_list) { const std::string empty_log_info; const std::string* log_info = (expected_log_info && !expected_valid) ? expected_log_info : &empty_log_info; @@ -1153,9 +1144,6 @@ void TestHelper::SetShaderStates( (expected_output_variable_list && expected_valid) ? expected_output_variable_list : &empty_output_variable_list; - const NameMap empty_name_map; - const NameMap* name_map = (expected_name_map && expected_valid) ? - expected_name_map : &empty_name_map; MockShaderTranslator* mock_translator = new MockShaderTranslator; scoped_refptr<ShaderTranslatorInterface> translator(mock_translator); @@ -1167,17 +1155,13 @@ void TestHelper::SetShaderStates( NotNull(), // uniform_map NotNull(), // varying_map NotNull(), // interface_block_map - NotNull(), // output_variable_list - NotNull())) // name_map - .WillOnce(DoAll(SetArgumentPointee<1>(*log_info), - SetArgumentPointee<2>(*translated_source), - SetArgumentPointee<3>(*shader_version), - SetArgumentPointee<4>(*attrib_map), - SetArgumentPointee<5>(*uniform_map), - SetArgumentPointee<6>(*varying_map), - SetArgumentPointee<7>(*interface_block_map), - SetArgumentPointee<8>(*output_variable_list), - SetArgumentPointee<9>(*name_map), Return(expected_valid))) + NotNull())) // output_variable_list + .WillOnce(DoAll( + SetArgPointee<1>(*log_info), SetArgPointee<2>(*translated_source), + SetArgPointee<3>(*shader_version), SetArgPointee<4>(*attrib_map), + SetArgPointee<5>(*uniform_map), SetArgPointee<6>(*varying_map), + SetArgPointee<7>(*interface_block_map), + SetArgPointee<8>(*output_variable_list), Return(expected_valid))) .RetiresOnSaturation(); if (expected_valid) { EXPECT_CALL(*gl, ShaderSource(shader->service_id(), 1, _, NULL)) @@ -1186,10 +1170,9 @@ void TestHelper::SetShaderStates( EXPECT_CALL(*gl, CompileShader(shader->service_id())) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl, GetShaderiv(shader->service_id(), - GL_COMPILE_STATUS, + EXPECT_CALL(*gl, GetShaderiv(shader->service_id(), GL_COMPILE_STATUS, NotNull())) // status - .WillOnce(SetArgumentPointee<2>(GL_TRUE)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) .RetiresOnSaturation(); } shader->RequestCompile(translator, Shader::kGL); @@ -1201,7 +1184,7 @@ void TestHelper::SetShaderStates(::gl::MockGLInterface* gl, Shader* shader, bool valid) { SetShaderStates(gl, shader, valid, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr); + nullptr, nullptr, nullptr, nullptr); } // static @@ -1228,6 +1211,38 @@ sh::Varying TestHelper::ConstructVarying( type, array_size, precision, static_use, name); } +// static +sh::InterfaceBlockField TestHelper::ConstructInterfaceBlockField( + GLenum type, + GLint array_size, + GLenum precision, + bool static_use, + const std::string& name) { + return ConstructShaderVariable<sh::InterfaceBlockField>( + type, array_size, precision, static_use, name); +} + +// static +sh::InterfaceBlock TestHelper::ConstructInterfaceBlock( + GLint array_size, + sh::BlockLayoutType layout, + bool is_row_major_layout, + bool static_use, + const std::string& name, + const std::string& instance_name, + const std::vector<sh::InterfaceBlockField>& fields) { + sh::InterfaceBlock var; + var.arraySize = array_size; + var.layout = layout; + var.isRowMajorLayout = is_row_major_layout; + var.staticUse = static_use; + var.name = name; + var.mappedName = name; // No name hashing. + var.instanceName = instance_name; + var.fields = fields; + return var; +} + sh::OutputVariable TestHelper::ConstructOutputVariable( GLenum type, GLint array_size, diff --git a/chromium/gpu/command_buffer/service/test_helper.h b/chromium/gpu/command_buffer/service/test_helper.h index 89c339cadf6..f138507c255 100644 --- a/chromium/gpu/command_buffer/service/test_helper.h +++ b/chromium/gpu/command_buffer/service/test_helper.h @@ -197,8 +197,7 @@ class TestHelper { const UniformMap* const expected_uniform_map, const VaryingMap* const expected_varying_map, const InterfaceBlockMap* const expected_interface_block_map, - const OutputVariableList* const expected_output_variable_list, - const NameMap* const expected_name_map); + const OutputVariableList* const expected_output_variable_list); static void SetShaderStates(::gl::MockGLInterface* gl, Shader* shader, @@ -213,6 +212,20 @@ class TestHelper { static sh::Varying ConstructVarying( GLenum type, GLint array_size, GLenum precision, bool static_use, const std::string& name); + static sh::InterfaceBlockField ConstructInterfaceBlockField( + GLenum type, + GLint array_size, + GLenum precision, + bool static_use, + const std::string& name); + static sh::InterfaceBlock ConstructInterfaceBlock( + GLint array_size, + sh::BlockLayoutType layout, + bool is_row_major_layout, + bool static_use, + const std::string& name, + const std::string& instance_name, + const std::vector<sh::InterfaceBlockField>& fields); static sh::OutputVariable ConstructOutputVariable(GLenum type, GLint array_size, GLenum precision, diff --git a/chromium/gpu/command_buffer/service/texture_manager.cc b/chromium/gpu/command_buffer/service/texture_manager.cc index 68cd6bf3e18..abfd3bf5452 100644 --- a/chromium/gpu/command_buffer/service/texture_manager.cc +++ b/chromium/gpu/command_buffer/service/texture_manager.cc @@ -28,6 +28,7 @@ #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/command_buffer/service/progress_reporter.h" +#include "gpu/command_buffer/service/service_discardable_manager.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_state_restorer.h" @@ -216,6 +217,9 @@ class FormatTypeValidator { // Exposed by GL_APPLE_texture_format_BGRA8888 and // GL_EXT_texture_format_BGRA8888 {GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE}, + + // Exposed by GL_EXT_texture_norm16 + {GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT}, }; static const FormatType kSupportedFormatTypesES2Only[] = { @@ -395,6 +399,23 @@ class ScopedResetPixelUnpackBuffer{ } // namespace anonymous +DecoderTextureState::DecoderTextureState( + const GpuDriverBugWorkarounds& workarounds) + : tex_image_failed(false), + texsubimage_faster_than_teximage( + workarounds.texsubimage_faster_than_teximage), + force_cube_map_positive_x_allocation( + workarounds.force_cube_map_positive_x_allocation), + force_cube_complete(workarounds.force_cube_complete), + force_int_or_srgb_cube_texture_complete( + workarounds.force_int_or_srgb_cube_texture_complete), + unpack_alignment_workaround_with_unpack_buffer( + workarounds.unpack_alignment_workaround_with_unpack_buffer), + unpack_overlapping_rows_separately_unpack_buffer( + workarounds.unpack_overlapping_rows_separately_unpack_buffer), + unpack_image_height_workaround_with_unpack_buffer( + workarounds.unpack_image_height_workaround_with_unpack_buffer) {} + TextureManager::DestructionObserver::DestructionObserver() {} TextureManager::DestructionObserver::~DestructionObserver() {} @@ -420,6 +441,10 @@ TextureManager::~TextureManager() { void TextureManager::Destroy(bool have_context) { have_context_ = have_context; + // Retreive any outstanding unlocked textures from the discardable manager so + // we can clean them up here. + discardable_manager_->OnTextureManagerDestruction(this); + while (!textures_.empty()) { textures_.erase(textures_.begin()); if (progress_reporter_) @@ -494,8 +519,8 @@ Texture::Texture(GLuint service_id) swizzle_a_(GL_ALPHA), max_level_set_(-1), texture_complete_(false), - texture_mips_dirty_(false), cube_complete_(false), + completeness_dirty_(false), npot_(false), has_been_bound_(false), framebuffer_attachment_count_(0), @@ -810,7 +835,7 @@ bool Texture::CanGenerateMipmaps(const FeatureInfo* feature_info) const { return false; } } - if (face_infos_.size() == 6 && !cube_complete_) { + if (face_infos_.size() == 6 && !cube_complete()) { return false; } return true; @@ -1046,19 +1071,31 @@ void Texture::UpdateNumMipLevels() { if (face_infos_.empty()) return; + GLint base_level = base_level_; + GLint max_level = max_level_; + if (immutable_) { + GLint levels = GetImmutableLevels(); + DCHECK_LE(1, levels); + DCHECK_LE(0, base_level_); + base_level = std::min(base_level_, levels - 1); + max_level = std::max(base_level, max_level_); + max_level = std::min(max_level, levels - 1); + } + GLint max_num_mip_levels = std::max(0, max_level - base_level + 1); for (size_t ii = 0; ii < face_infos_.size(); ++ii) { Texture::FaceInfo& face_info = face_infos_[ii]; - if (static_cast<size_t>(base_level_) >= face_info.level_infos.size()) + if (static_cast<size_t>(base_level) >= face_info.level_infos.size()) continue; - const Texture::LevelInfo& info = face_info.level_infos[base_level_]; + const Texture::LevelInfo& info = face_info.level_infos[base_level]; face_info.num_mip_levels = std::min( - std::max(0, max_level_ - base_level_ + 1), - TextureManager::ComputeMipMapCount( - target_, info.width, info.height, info.depth)); + max_num_mip_levels, TextureManager::ComputeMipMapCount( + target_, info.width, info.height, info.depth)); } // mipmap-completeness needs to be re-evaluated. - texture_mips_dirty_ = true; + completeness_dirty_ = true; + Update(); + UpdateCanRenderCondition(); } void Texture::SetLevelInfo(GLenum target, @@ -1086,13 +1123,9 @@ void Texture::SetLevelInfo(GLenum target, // Update counters only if any attributes have changed. Counters are // comparisons between the old and new values so it must be done before any // assignment has been done to the LevelInfo. - if (info.target != target || - info.internal_format != internal_format || - info.width != width || - info.height != height || - info.depth != depth || - info.format != format || - info.type != type) { + if (info.target != target || info.internal_format != internal_format || + info.width != width || info.height != height || info.depth != depth || + info.format != format || info.type != type || info.internal_workaround) { if (level == base_level_) { // Calculate the mip level count. face_infos_[face_index].num_mip_levels = std::min( @@ -1107,7 +1140,7 @@ void Texture::SetLevelInfo(GLenum target, } // Signify that at least one of the mips has changed. - texture_mips_dirty_ = true; + completeness_dirty_ = true; } info.target = target; @@ -1172,6 +1205,9 @@ void Texture::MarkLevelAsInternalWorkaround(GLenum target, GLint level) { Texture::LevelInfo& info = face_infos_[face_index].level_infos[level]; info.internal_workaround = true; + completeness_dirty_ = true; + Update(); + UpdateCanRenderCondition(); } bool Texture::ValidForTexture( @@ -1417,6 +1453,9 @@ void Texture::Update() { // Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others npot_ = (target_ == GL_TEXTURE_EXTERNAL_OES) || (num_npot_faces_ > 0); + if (!completeness_dirty_) + return; + if (face_infos_.empty() || static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size()) { texture_complete_ = false; @@ -1462,7 +1501,7 @@ void Texture::Update() { cube_complete_ &= texture_level0_complete; bool texture_mips_complete = true; - if (texture_complete_ && texture_mips_dirty_) { + if (texture_complete_) { for (size_t ii = 0; ii < face_infos_.size() && texture_mips_complete; ++ii) { const Texture::FaceInfo& face_info = face_infos_[ii]; @@ -1485,9 +1524,9 @@ void Texture::Update() { } } } - texture_mips_dirty_ = false; } texture_complete_ &= texture_mips_complete; + completeness_dirty_ = false; } bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { @@ -1512,17 +1551,23 @@ bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { return true; } +void Texture::SetImmutable(bool immutable) { + if (immutable_ == immutable) + return; + immutable_ = immutable; + + UpdateNumMipLevels(); +} + GLint Texture::GetImmutableLevels() const { if (!immutable_) return 0; GLint levels = 0; - if (immutable_) { - DCHECK(face_infos_.size() > 0); - for (size_t ii = 0; ii < face_infos_[0].level_infos.size(); ++ii) { - const Texture::LevelInfo& info = face_infos_[0].level_infos[ii]; - if (info.target != 0) - levels++; - } + DCHECK(face_infos_.size() > 0); + for (size_t ii = 0; ii < face_infos_[0].level_infos.size(); ++ii) { + const Texture::LevelInfo& info = face_infos_[0].level_infos[ii]; + if (info.target != 0) + levels++; } return levels; } @@ -1784,10 +1829,13 @@ bool Texture::CanRenderTo(const FeatureInfo* feature_info, GLint level) const { // recent OpenGL core versions or OpenGL ES 3.0+. Therefore, for consistency, // it is better to deviate from ES2 spec and require cube completeness all // the time. - if (face_infos_.size() == 6 && !cube_complete_) + if (face_infos_.size() == 6 && !cube_complete()) return false; DCHECK(level >= 0 && level < static_cast<GLint>(face_infos_[0].level_infos.size())); + if (level > base_level_ && !texture_complete()) { + return false; + } GLenum internal_format = face_infos_[0].level_infos[level].internal_format; bool color_renderable = ColorRenderable(feature_info, internal_format, immutable_); @@ -1869,11 +1917,11 @@ TextureManager::TextureManager(MemoryTracker* memory_tracker, GLint max_3d_texture_size, GLint max_array_texture_layers, bool use_default_textures, - ProgressReporter* progress_reporter) + ProgressReporter* progress_reporter, + ServiceDiscardableManager* discardable_manager) : memory_type_tracker_(new MemoryTypeTracker(memory_tracker)), memory_tracker_(memory_tracker), feature_info_(feature_info), - framebuffer_manager_(NULL), max_texture_size_(max_texture_size), max_cube_map_texture_size_(max_cube_map_texture_size), max_rectangle_texture_size_(max_rectangle_texture_size), @@ -1898,12 +1946,30 @@ TextureManager::TextureManager(MemoryTracker* memory_tracker, texture_count_(0), have_context_(true), current_service_id_generation_(0), - progress_reporter_(progress_reporter) { + progress_reporter_(progress_reporter), + discardable_manager_(discardable_manager) { for (int ii = 0; ii < kNumDefaultTextures; ++ii) { black_texture_ids_[ii] = 0; } } +void TextureManager::AddFramebufferManager( + FramebufferManager* framebuffer_manager) { + framebuffer_managers_.push_back(framebuffer_manager); +} + +void TextureManager::RemoveFramebufferManager( + FramebufferManager* framebuffer_manager) { + for (unsigned int i = 0; i < framebuffer_managers_.size(); ++i) { + if (framebuffer_managers_[i] == framebuffer_manager) { + std::swap(framebuffer_managers_[i], framebuffer_managers_.back()); + framebuffer_managers_.pop_back(); + return; + } + } + NOTREACHED(); +} + bool TextureManager::Initialize() { // Reset PIXEL_UNPACK_BUFFER to avoid unrelated GL error on some GL drivers. if (feature_info_->gl_version_info().is_es3_capable) { @@ -2090,6 +2156,8 @@ void TextureManager::SetLevelInfo(TextureRef* ref, texture->SetLevelInfo(target, level, internal_format, width, height, depth, border, format, type, cleared_rect); texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size()); + discardable_manager_->OnTextureSizeChanged(ref->client_id(), this, + texture->estimated_size()); } Texture* TextureManager::Produce(TextureRef* ref) { @@ -2183,9 +2251,34 @@ TextureRef* TextureManager::GetTexture( return it != textures_.end() ? it->second.get() : NULL; } +scoped_refptr<TextureRef> TextureManager::TakeTexture(GLuint client_id) { + auto it = textures_.find(client_id); + if (it == textures_.end()) + return nullptr; + + scoped_refptr<TextureRef> ref = it->second; + textures_.erase(it); + return ref; +} + +void TextureManager::ReturnTexture(scoped_refptr<TextureRef> texture_ref) { + GLuint client_id = texture_ref->client_id(); + // If we've generated a replacement texture due to "bind generates resource", + // behavior, just delete the resource being returned. + TextureMap::iterator it = textures_.find(client_id); + if (it != textures_.end()) { + // Reset the client id so it doesn't interfere with the generated resource. + texture_ref->reset_client_id(); + return; + } + + textures_.emplace(client_id, std::move(texture_ref)); +} + void TextureManager::RemoveTexture(GLuint client_id) { TextureMap::iterator it = textures_.find(client_id); if (it != textures_.end()) { + discardable_manager_->OnTextureDeleted(client_id, this); it->second->reset_client_id(); textures_.erase(it); } @@ -2222,6 +2315,9 @@ void TextureManager::StopTracking(TextureRef* ref) { } num_uncleared_mips_ -= texture->num_uncleared_mips(); DCHECK_GE(num_uncleared_mips_, 0); + + if (ref->client_id()) + discardable_manager_->OnTextureDeleted(ref->client_id(), this); } MemoryTypeTracker* TextureManager::GetMemTracker() { @@ -2312,8 +2408,9 @@ void TextureManager::UpdateNumImages(int delta) { } void TextureManager::IncFramebufferStateChangeCount() { - if (framebuffer_manager_) - framebuffer_manager_->IncFramebufferStateChangeCount(); + for (unsigned int i = 0; i < framebuffer_managers_.size(); ++i) { + framebuffer_managers_[i]->IncFramebufferStateChangeCount(); + } } bool TextureManager::ValidateTextureParameters( @@ -2434,6 +2531,21 @@ bool TextureManager::ValidateTexImage( error_state, function_name, args.target, "target"); return false; } + if (feature_info_->IsWebGL1OrES2Context()) { + switch (args.format) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL: + if (args.target != GL_TEXTURE_2D) { + ERRORSTATE_SET_GL_ERROR( + error_state, GL_INVALID_OPERATION, function_name, + "invalid target for depth/stencil textures"); + return false; + } + break; + default: + break; + } + } if (!ValidateTextureParameters( error_state, function_name, true, args.format, args.type, args.internal_format, args.level)) { @@ -2527,7 +2639,8 @@ void TextureManager::DoCubeMapWorkaround( std::vector<GLenum> undefined_faces; Texture* texture = texture_ref->texture(); - if (texture_state->force_cube_complete) { + if (texture_state->force_cube_complete || + texture_state->force_int_or_srgb_cube_texture_complete) { int width = 0; int height = 0; for (unsigned i = 0; i < 6; i++) { @@ -2585,6 +2698,15 @@ void TextureManager::ValidateAndDoTexImage( (texture_state->force_cube_complete || (texture_state->force_cube_map_positive_x_allocation && args.target != GL_TEXTURE_CUBE_MAP_POSITIVE_X)); + // Force integer or srgb cube map texture complete, see crbug.com/712117. + need_cube_map_workaround = + need_cube_map_workaround || + (texture->target() == GL_TEXTURE_CUBE_MAP && + texture_state->force_int_or_srgb_cube_texture_complete && + (GLES2Util::IsIntegerFormat(args.internal_format) || + GLES2Util::GetColorEncodingFromInternalFormat(args.internal_format) == + GL_SRGB)); + if (need_cube_map_workaround && !buffer) { DoCubeMapWorkaround(texture_state, state, framebuffer_state, texture_ref, function_name, args); @@ -2883,7 +3005,6 @@ void TextureManager::ValidateAndDoTexSubImage( if (full_image && !texture_state->texsubimage_faster_than_teximage && !texture->IsImmutable() && !texture->HasImages()) { - ScopedTextureUploadTimer timer(texture_state); GLenum internal_format; GLenum tex_type; texture->GetLevelType(args.target, args.level, &tex_type, &internal_format); @@ -2905,7 +3026,6 @@ void TextureManager::ValidateAndDoTexSubImage( args.pixels); } } else { - ScopedTextureUploadTimer timer(texture_state); if (args.command_type == DoTexSubImageArguments::kTexSubImage3D) { glTexSubImage3D(args.target, args.level, args.xoffset, args.yoffset, args.zoffset, args.width, args.height, args.depth, @@ -2927,7 +3047,6 @@ void TextureManager::DoTexSubImageWithAlignmentWorkaround( DCHECK(state->bound_pixel_unpack_buffer.get()); DCHECK(args.width > 0 && args.height > 0 && args.depth > 0); - ScopedTextureUploadTimer timer(texture_state); uint32_t offset = ToGLuint(args.pixels); if (args.command_type == DoTexSubImageArguments::kTexSubImage2D) { PixelStoreParams params = state->GetUnpackParams(ContextState::k2D); @@ -3203,7 +3322,6 @@ void TextureManager::DoTexImage( if (texture_state->texsubimage_faster_than_teximage && level_is_same && args.pixels && !unpack_buffer_bound) { { - ScopedTextureUploadTimer timer(texture_state); if (args.command_type == DoTexImageArguments::kTexImage3D) { glTexSubImage3D(args.target, args.level, 0, 0, 0, args.width, args.height, args.depth, @@ -3224,7 +3342,6 @@ void TextureManager::DoTexImage( ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state, function_name); { - ScopedTextureUploadTimer timer(texture_state); if (args.command_type == DoTexImageArguments::kTexImage3D) { glTexImage3D( args.target, args.level, @@ -3285,18 +3402,6 @@ bool TextureManager::CombineAdjacentRects(const gfx::Rect& rect1, return false; } -ScopedTextureUploadTimer::ScopedTextureUploadTimer( - DecoderTextureState* texture_state) - : texture_state_(texture_state), - begin_time_(base::TimeTicks::Now()) { -} - -ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { - texture_state_->texture_upload_count++; - texture_state_->total_texture_upload_time += - base::TimeTicks::Now() - begin_time_; -} - bool TextureManager::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd) { if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) { diff --git a/chromium/gpu/command_buffer/service/texture_manager.h b/chromium/gpu/command_buffer/service/texture_manager.h index 8cf2edb1548..02c5c1119c7 100644 --- a/chromium/gpu/command_buffer/service/texture_manager.h +++ b/chromium/gpu/command_buffer/service/texture_manager.h @@ -27,8 +27,9 @@ #include "ui/gl/gl_image.h" namespace gpu { -namespace gles2 { +class ServiceDiscardableManager; +namespace gles2 { class GLES2Decoder; class GLStreamTextureImage; struct ContextState; @@ -289,9 +290,7 @@ class GPU_EXPORT Texture final : public TextureBase { --framebuffer_attachment_count_; } - void SetImmutable(bool immutable) { - immutable_ = immutable; - } + void SetImmutable(bool immutable); bool IsImmutable() const { return immutable_; @@ -325,6 +324,14 @@ class GPU_EXPORT Texture final : public TextureBase { bool EmulatingRGB(); + // In GLES2 "texture complete" means it has all required mips for filtering + // down to a 1x1 pixel texture, they are in the correct order, they are all + // the same format. + bool texture_complete() const { + DCHECK(!completeness_dirty_); + return texture_complete_; + } + static bool ColorRenderable(const FeatureInfo* feature_info, GLenum internal_format, bool immutable); @@ -418,16 +425,10 @@ class GPU_EXPORT Texture final : public TextureBase { void MarkLevelAsInternalWorkaround(GLenum target, GLint level); - // In GLES2 "texture complete" means it has all required mips for filtering - // down to a 1x1 pixel texture, they are in the correct order, they are all - // the same format. - bool texture_complete() const { - return texture_complete_; - } - // In GLES2 "cube complete" means all 6 faces level 0 are defined, all the // same format, all the same dimensions and all width = height. bool cube_complete() const { + DCHECK(!completeness_dirty_); return cube_complete_; } @@ -612,12 +613,13 @@ class GPU_EXPORT Texture final : public TextureBase { // Whether or not this texture is "texture complete" bool texture_complete_; - // Whether mip levels have changed and should be reverified. - bool texture_mips_dirty_; - // Whether or not this texture is "cube complete" bool cube_complete_; + // Whether mip levels, base_level, or max_level have changed and + // texture_completeness_ and cube_completeness_ should be reverified. + bool completeness_dirty_; + // Whether or not this texture is non-power-of-two bool npot_; @@ -698,20 +700,7 @@ class GPU_EXPORT TextureRef : public base::RefCounted<TextureRef> { struct DecoderTextureState { // total_texture_upload_time automatically initialized to 0 in default // constructor. - explicit DecoderTextureState(const GpuDriverBugWorkarounds& workarounds) - : tex_image_failed(false), - texture_upload_count(0), - texsubimage_faster_than_teximage( - workarounds.texsubimage_faster_than_teximage), - force_cube_map_positive_x_allocation( - workarounds.force_cube_map_positive_x_allocation), - force_cube_complete(workarounds.force_cube_complete), - unpack_alignment_workaround_with_unpack_buffer( - workarounds.unpack_alignment_workaround_with_unpack_buffer), - unpack_overlapping_rows_separately_unpack_buffer( - workarounds.unpack_overlapping_rows_separately_unpack_buffer), - unpack_image_height_workaround_with_unpack_buffer( - workarounds.unpack_image_height_workaround_with_unpack_buffer) {} + explicit DecoderTextureState(const GpuDriverBugWorkarounds& workarounds); // This indicates all the following texSubImage*D calls that are part of the // failed texImage*D call should be ignored. The client calls have a lock @@ -719,13 +708,10 @@ struct DecoderTextureState { // group. bool tex_image_failed; - // Command buffer stats. - int texture_upload_count; - base::TimeDelta total_texture_upload_time; - bool texsubimage_faster_than_teximage; bool force_cube_map_positive_x_allocation; bool force_cube_complete; + bool force_int_or_srgb_cube_texture_complete; bool unpack_alignment_workaround_with_unpack_buffer; bool unpack_overlapping_rows_separately_unpack_buffer; bool unpack_image_height_workaround_with_unpack_buffer; @@ -771,12 +757,12 @@ class GPU_EXPORT TextureManager : public base::trace_event::MemoryDumpProvider { GLsizei max_3d_texture_size, GLsizei max_array_texture_layers, bool use_default_textures, - ProgressReporter* progress_reporter); + ProgressReporter* progress_reporter, + ServiceDiscardableManager* discardable_manager); ~TextureManager() override; - void set_framebuffer_manager(FramebufferManager* manager) { - framebuffer_manager_ = manager; - } + void AddFramebufferManager(FramebufferManager* framebuffer_manager); + void RemoveFramebufferManager(FramebufferManager* framebuffer_manager); // Init the texture manager. bool Initialize(); @@ -914,6 +900,12 @@ class GPU_EXPORT TextureManager : public base::trace_event::MemoryDumpProvider { // Gets the texture info for the given texture. TextureRef* GetTexture(GLuint client_id) const; + // Takes the TextureRef for the given texture out of the texture manager. + scoped_refptr<TextureRef> TakeTexture(GLuint client_id); + + // Returns a TextureRef to the texture manager. + void ReturnTexture(scoped_refptr<TextureRef> texture_ref); + // Removes a texture info. void RemoveTexture(GLuint client_id); @@ -1208,7 +1200,7 @@ class GPU_EXPORT TextureManager : public base::trace_event::MemoryDumpProvider { scoped_refptr<FeatureInfo> feature_info_; - FramebufferManager* framebuffer_manager_; + std::vector<FramebufferManager*> framebuffer_managers_; // Info for each texture in the system. typedef base::hash_map<GLuint, scoped_refptr<TextureRef> > TextureMap; @@ -1252,19 +1244,9 @@ class GPU_EXPORT TextureManager : public base::trace_event::MemoryDumpProvider { // using in-process command buffer. ProgressReporter* progress_reporter_; - DISALLOW_COPY_AND_ASSIGN(TextureManager); -}; + ServiceDiscardableManager* discardable_manager_; -// This class records texture upload time when in scope. -class ScopedTextureUploadTimer { - public: - explicit ScopedTextureUploadTimer(DecoderTextureState* texture_state); - ~ScopedTextureUploadTimer(); - - private: - DecoderTextureState* texture_state_; - base::TimeTicks begin_time_; - DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer); + DISALLOW_COPY_AND_ASSIGN(TextureManager); }; } // namespace gles2 diff --git a/chromium/gpu/command_buffer/service/texture_manager_unittest.cc b/chromium/gpu/command_buffer/service/texture_manager_unittest.cc index 471ec773cbd..242a73f3826 100644 --- a/chromium/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/texture_manager_unittest.cc @@ -21,6 +21,7 @@ #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/command_buffer/service/mocks.h" +#include "gpu/command_buffer/service/service_discardable_manager.h" #include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_image_stub.h" @@ -80,7 +81,7 @@ class TextureManagerTest : public GpuServiceTest { manager_.reset(new TextureManager( NULL, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr)); + kUseDefaultTextures, nullptr, &discardable_manager_)); SetupFeatureInfo("", "OpenGL ES 2.0", CONTEXT_TYPE_OPENGLES2); TestHelper::SetupTextureManagerInitExpectations( gl_.get(), false, false, false, "", kUseDefaultTextures); @@ -120,6 +121,7 @@ class TextureManagerTest : public GpuServiceTest { } scoped_refptr<FeatureInfo> feature_info_; + ServiceDiscardableManager discardable_manager_; std::unique_ptr<TextureManager> manager_; std::unique_ptr<MockErrorState> error_state_; }; @@ -242,7 +244,7 @@ TEST_F(TextureManagerTest, UseDefaultTexturesTrue) { TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - use_default_textures, nullptr); + use_default_textures, nullptr, &discardable_manager_); manager.Initialize(); EXPECT_TRUE(manager.GetDefaultTextureInfo(GL_TEXTURE_2D) != NULL); @@ -260,7 +262,7 @@ TEST_F(TextureManagerTest, UseDefaultTexturesFalse) { TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - use_default_textures, nullptr); + use_default_textures, nullptr, &discardable_manager_); manager.Initialize(); EXPECT_TRUE(manager.GetDefaultTextureInfo(GL_TEXTURE_2D) == NULL); @@ -279,7 +281,7 @@ TEST_F(TextureManagerTest, UseDefaultTexturesTrueES3) { TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - use_default_textures, nullptr); + use_default_textures, nullptr, &discardable_manager_); manager.Initialize(); EXPECT_TRUE(manager.GetDefaultTextureInfo(GL_TEXTURE_3D) != NULL); @@ -296,7 +298,7 @@ TEST_F(TextureManagerTest, UseDefaultTexturesFalseES3) { TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - use_default_textures, nullptr); + use_default_textures, nullptr, &discardable_manager_); manager.Initialize(); EXPECT_TRUE(manager.GetDefaultTextureInfo(GL_TEXTURE_3D) == NULL); @@ -312,7 +314,7 @@ TEST_F(TextureManagerTest, TextureUsageExt) { TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.Initialize(); const GLuint kClient1Id = 1; const GLuint kService1Id = 11; @@ -337,7 +339,7 @@ TEST_F(TextureManagerTest, Destroy) { TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.Initialize(); // Check we can create texture. manager.CreateTexture(kClient1Id, kService1Id); @@ -492,7 +494,7 @@ TEST_F(TextureManagerTest, ValidForTargetNPOT) { TextureManager manager(nullptr, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); // Check NPOT width on level 0 EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 0, 5, 2, 1)); // Check NPOT height on level 0 @@ -514,7 +516,7 @@ TEST_F(TextureManagerTest, AlphaLuminanceCompatibilityProfile) { TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.Initialize(); // Create a texture. @@ -555,7 +557,7 @@ TEST_F(TextureManagerTest, AlphaLuminanceCoreProfileEmulation) { TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.Initialize(); // Create a texture. @@ -670,7 +672,8 @@ class TextureTestBase : public GpuServiceTest { manager_.reset(new TextureManager( memory_tracker, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, - kMaxArrayTextureLayers, kUseDefaultTextures, nullptr)); + kMaxArrayTextureLayers, kUseDefaultTextures, nullptr, + &discardable_manager_)); decoder_.reset(new ::testing::StrictMock<gles2::MockGLES2Decoder>()); error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>()); manager_->CreateTexture(kClient1Id, kService1Id); @@ -706,6 +709,7 @@ class TextureTestBase : public GpuServiceTest { std::unique_ptr<MockGLES2Decoder> decoder_; std::unique_ptr<MockErrorState> error_state_; scoped_refptr<FeatureInfo> feature_info_; + ServiceDiscardableManager discardable_manager_; std::unique_ptr<TextureManager> manager_; scoped_refptr<TextureRef> texture_ref_; }; @@ -1000,7 +1004,7 @@ TEST_F(TextureTest, NPOT2DNPOTOK) { TextureManager manager(nullptr, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); ASSERT_TRUE(texture_ref != NULL); @@ -1298,7 +1302,7 @@ TEST_F(TextureTest, FloatNotLinear) { TextureManager manager(nullptr, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); ASSERT_TRUE(texture_ref != NULL); @@ -1327,7 +1331,7 @@ TEST_F(TextureTest, FloatLinear) { TextureManager manager(nullptr, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); ASSERT_TRUE(texture_ref != NULL); @@ -1348,7 +1352,7 @@ TEST_F(TextureTest, HalfFloatNotLinear) { TextureManager manager(nullptr, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); ASSERT_TRUE(texture_ref != NULL); @@ -1377,7 +1381,7 @@ TEST_F(TextureTest, HalfFloatLinear) { TextureManager manager(nullptr, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); ASSERT_TRUE(texture_ref != NULL); @@ -1398,7 +1402,7 @@ TEST_F(TextureTest, EGLImageExternal) { TextureManager manager(nullptr, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); ASSERT_TRUE(texture_ref != NULL); @@ -1417,7 +1421,7 @@ TEST_F(TextureTest, DepthTexture) { TextureManager manager(nullptr, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize, kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr); + kUseDefaultTextures, nullptr, &discardable_manager_); manager.CreateTexture(kClient1Id, kService1Id); TextureRef* texture_ref = manager.GetTexture(kClient1Id); ASSERT_TRUE(texture_ref != NULL); @@ -2186,23 +2190,23 @@ class SharedTextureTest : public GpuServiceTest { void SetUp() override { GpuServiceTest::SetUp(); memory_tracker1_ = new CountingMemoryTracker; - texture_manager1_.reset( - new TextureManager(memory_tracker1_.get(), feature_info_.get(), - TextureManagerTest::kMaxTextureSize, - TextureManagerTest::kMaxCubeMapTextureSize, - TextureManagerTest::kMaxRectangleTextureSize, - TextureManagerTest::kMax3DTextureSize, - TextureManagerTest::kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr)); + texture_manager1_.reset(new TextureManager( + memory_tracker1_.get(), feature_info_.get(), + TextureManagerTest::kMaxTextureSize, + TextureManagerTest::kMaxCubeMapTextureSize, + TextureManagerTest::kMaxRectangleTextureSize, + TextureManagerTest::kMax3DTextureSize, + TextureManagerTest::kMaxArrayTextureLayers, kUseDefaultTextures, + nullptr, &discardable_manager_)); memory_tracker2_ = new CountingMemoryTracker; - texture_manager2_.reset( - new TextureManager(memory_tracker2_.get(), feature_info_.get(), - TextureManagerTest::kMaxTextureSize, - TextureManagerTest::kMaxCubeMapTextureSize, - TextureManagerTest::kMaxRectangleTextureSize, - TextureManagerTest::kMax3DTextureSize, - TextureManagerTest::kMaxArrayTextureLayers, - kUseDefaultTextures, nullptr)); + texture_manager2_.reset(new TextureManager( + memory_tracker2_.get(), feature_info_.get(), + TextureManagerTest::kMaxTextureSize, + TextureManagerTest::kMaxCubeMapTextureSize, + TextureManagerTest::kMaxRectangleTextureSize, + TextureManagerTest::kMax3DTextureSize, + TextureManagerTest::kMaxArrayTextureLayers, kUseDefaultTextures, + nullptr, &discardable_manager_)); SetupFeatureInfo("", "OpenGL ES 2.0", CONTEXT_TYPE_OPENGLES2); TestHelper::SetupTextureManagerInitExpectations( gl_.get(), false, false, false, "", kUseDefaultTextures); @@ -2240,6 +2244,7 @@ class SharedTextureTest : public GpuServiceTest { } scoped_refptr<FeatureInfo> feature_info_; + ServiceDiscardableManager discardable_manager_; scoped_refptr<CountingMemoryTracker> memory_tracker1_; std::unique_ptr<TextureManager> texture_manager1_; scoped_refptr<CountingMemoryTracker> memory_tracker2_; @@ -2314,9 +2319,9 @@ TEST_F(SharedTextureTest, TextureSafetyAccounting) { TEST_F(SharedTextureTest, FBOCompletenessCheck) { const GLenum kCompleteValue = GL_FRAMEBUFFER_COMPLETE; FramebufferManager framebuffer_manager1(1, 1, nullptr); - texture_manager1_->set_framebuffer_manager(&framebuffer_manager1); + texture_manager1_->AddFramebufferManager(&framebuffer_manager1); FramebufferManager framebuffer_manager2(1, 1, nullptr); - texture_manager2_->set_framebuffer_manager(&framebuffer_manager2); + texture_manager2_->AddFramebufferManager(&framebuffer_manager2); scoped_refptr<TextureRef> ref1 = texture_manager1_->CreateTexture(10, 10); framebuffer_manager1.CreateFramebuffer(10, 10); diff --git a/chromium/gpu/command_buffer/service/transfer_buffer_manager.cc b/chromium/gpu/command_buffer/service/transfer_buffer_manager.cc index 8fd4050d04b..02adf6a2265 100644 --- a/chromium/gpu/command_buffer/service/transfer_buffer_manager.cc +++ b/chromium/gpu/command_buffer/service/transfer_buffer_manager.cc @@ -25,12 +25,17 @@ using ::base::SharedMemory; namespace gpu { -TransferBufferManagerInterface::~TransferBufferManagerInterface() { -} - TransferBufferManager::TransferBufferManager( gles2::MemoryTracker* memory_tracker) - : shared_memory_bytes_allocated_(0), memory_tracker_(memory_tracker) {} + : shared_memory_bytes_allocated_(0), memory_tracker_(memory_tracker) { + // When created from InProcessCommandBuffer, we won't have a |memory_tracker_| + // so don't register a dump provider. + if (memory_tracker_) { + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( + this, "gpu::TransferBufferManager", + base::ThreadTaskRunnerHandle::Get()); + } +} TransferBufferManager::~TransferBufferManager() { while (!registered_buffers_.empty()) { @@ -47,17 +52,6 @@ TransferBufferManager::~TransferBufferManager() { this); } -bool TransferBufferManager::Initialize() { - // When created from InProcessCommandBuffer, we won't have a |memory_tracker_| - // so don't register a dump provider. - if (memory_tracker_) { - base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( - this, "gpu::TransferBufferManager", - base::ThreadTaskRunnerHandle::Get()); - } - return true; -} - bool TransferBufferManager::RegisterTransferBuffer( int32_t id, std::unique_ptr<BufferBacking> buffer_backing) { diff --git a/chromium/gpu/command_buffer/service/transfer_buffer_manager.h b/chromium/gpu/command_buffer/service/transfer_buffer_manager.h index 31489785881..6239f1b777b 100644 --- a/chromium/gpu/command_buffer/service/transfer_buffer_manager.h +++ b/chromium/gpu/command_buffer/service/transfer_buffer_manager.h @@ -13,7 +13,7 @@ #include <vector> #include "base/compiler_specific.h" -#include "base/containers/hash_tables.h" +#include "base/containers/flat_map.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/trace_event/memory_dump_provider.h" @@ -24,42 +24,23 @@ namespace gles2 { class MemoryTracker; } -class GPU_EXPORT TransferBufferManagerInterface : - public base::RefCounted<TransferBufferManagerInterface> { - public: - virtual bool RegisterTransferBuffer( - int32_t id, - std::unique_ptr<BufferBacking> buffer) = 0; - virtual void DestroyTransferBuffer(int32_t id) = 0; - virtual scoped_refptr<Buffer> GetTransferBuffer(int32_t id) = 0; - - protected: - friend class base::RefCounted<TransferBufferManagerInterface>; - - virtual ~TransferBufferManagerInterface(); -}; - class GPU_EXPORT TransferBufferManager - : public TransferBufferManagerInterface, - public base::trace_event::MemoryDumpProvider { + : public base::trace_event::MemoryDumpProvider { public: explicit TransferBufferManager(gles2::MemoryTracker* memory_tracker); + ~TransferBufferManager() override; // Overridden from base::trace_event::MemoryDumpProvider: bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd) override; - bool Initialize(); - bool RegisterTransferBuffer( - int32_t id, - std::unique_ptr<BufferBacking> buffer_backing) override; - void DestroyTransferBuffer(int32_t id) override; - scoped_refptr<Buffer> GetTransferBuffer(int32_t id) override; + bool RegisterTransferBuffer(int32_t id, + std::unique_ptr<BufferBacking> buffer_backing); + void DestroyTransferBuffer(int32_t id); + scoped_refptr<Buffer> GetTransferBuffer(int32_t id); private: - ~TransferBufferManager() override; - - typedef base::hash_map<int32_t, scoped_refptr<Buffer>> BufferMap; + typedef base::flat_map<int32_t, scoped_refptr<Buffer>> BufferMap; BufferMap registered_buffers_; size_t shared_memory_bytes_allocated_; gles2::MemoryTracker* memory_tracker_; diff --git a/chromium/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc b/chromium/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc index 1e12ae68a64..1f654277e7d 100644 --- a/chromium/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc @@ -8,6 +8,7 @@ #include <memory> +#include "base/memory/ptr_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -20,12 +21,10 @@ const static size_t kBufferSize = 1024; class TransferBufferManagerTest : public testing::Test { protected: void SetUp() override { - TransferBufferManager* manager = new TransferBufferManager(nullptr); - transfer_buffer_manager_ = manager; - ASSERT_TRUE(manager->Initialize()); + transfer_buffer_manager_ = base::MakeUnique<TransferBufferManager>(nullptr); } - scoped_refptr<TransferBufferManagerInterface> transfer_buffer_manager_; + std::unique_ptr<TransferBufferManager> transfer_buffer_manager_; }; TEST_F(TransferBufferManagerTest, ZeroHandleMapsToNull) { |