Hash :
6f794eab
Author :
Date :
2023-10-05T11:23:30
Change angle::FixedQueue's storage from std::array to std::vector Right now angle::FixedQueue uses std::array as the storage. In the case when queue is full, the only choice is to wait for dequeue thread to run until there is more room to enqueue. This CL try to add extra flexibility. In this CL< it switches storage to std::vector so that we could reallocate to double the storage when it is full. The trick is that before doing that, you must ensure no one is accessing the queue other than check the size. In a lot of usage cases that is easy to do by just grabbing the necessary locks. Bug: b/302739073 Change-Id: Ibefe0fd0e3e89c17dd6ee2cac6adc3368122adb9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4915811 Reviewed-by: Hailin Zhang <hailinzhang@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
//
// Copyright 2023 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SecondaryCommandPool:
// A class for allocating Command Buffers for VulkanSecondaryCommandBuffer.
//
#ifndef LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDPOOL_H_
#define LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDPOOL_H_
#include "common/FixedQueue.h"
#include "libANGLE/renderer/vulkan/vk_command_buffer_utils.h"
#include "libANGLE/renderer/vulkan/vk_wrapper.h"
namespace rx
{
namespace vk
{
class Context;
class VulkanSecondaryCommandBuffer;
// VkCommandPool must be externally synchronized when its Command Buffers are: allocated, freed,
// reset, or recorded. This class ensures that Command Buffers are freed from the thread that
// recording commands (Context thread).
class SecondaryCommandPool final : angle::NonCopyable
{
public:
SecondaryCommandPool();
~SecondaryCommandPool();
angle::Result init(Context *context, uint32_t queueFamilyIndex, ProtectionType protectionType);
void destroy(VkDevice device);
bool valid() const { return mCommandPool.valid(); }
// Call only from the Context thread that owns the SecondaryCommandPool instance.
angle::Result allocate(Context *context, VulkanSecondaryCommandBuffer *buffer);
// Single threaded - use external synchronization.
// Example threads: any Context thread or "asyncCommandQueue" thread.
void collect(VulkanSecondaryCommandBuffer *buffer);
private:
static constexpr size_t kFixedQueueLimit = 100u;
// Context thread access members.
void freeCollectedBuffers(VkDevice device);
// Use single pool for now.
CommandPool mCommandPool;
// Other thread access members.
// Fast lock free queue for processing buffers while new may be added from the other thread.
angle::FixedQueue<VkCommandBuffer> mCollectedBuffers;
// Overflow vector to use in cases when FixedQueue is filled.
std::vector<VkCommandBuffer> mCollectedBuffersOverflow;
std::mutex mOverflowMutex;
std::atomic<bool> mHasOverflow;
};
} // namespace vk
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDPOOL_H_