1 // 2 // Copyright 2020 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // CommandProcessor.h: 7 // A class to process and submit Vulkan command buffers that can be 8 // used in an asynchronous worker thread. 9 // 10 11 #ifndef LIBANGLE_RENDERER_VULKAN_COMMAND_PROCESSOR_H_ 12 #define LIBANGLE_RENDERER_VULKAN_COMMAND_PROCESSOR_H_ 13 14 #include <condition_variable> 15 #include <mutex> 16 #include <queue> 17 #include <thread> 18 19 #include "libANGLE/renderer/vulkan/vk_headers.h" 20 #include "libANGLE/renderer/vulkan/vk_helpers.h" 21 22 namespace rx 23 { 24 namespace vk 25 { 26 // CommandProcessorTask is used to queue a task to the worker thread when 27 // enableCommandProcessingThread feature is true. 28 // The typical task includes pointers in all values and the worker thread will 29 // process the SecondaryCommandBuffer commands in cbh into the primaryCB. 30 // There is a special task in which all of the pointers are null that will trigger 31 // the worker thread to exit, and is sent when the renderer instance shuts down. 32 struct CommandProcessorTask 33 { 34 ContextVk *contextVk; 35 // TODO: b/153666475 Removed primaryCB in threading phase2. 36 vk::PrimaryCommandBuffer *primaryCB; 37 CommandBufferHelper *commandBuffer; 38 }; 39 40 static const CommandProcessorTask kEndCommandProcessorThread = {nullptr, nullptr, nullptr}; 41 } // namespace vk 42 43 class CommandProcessor : angle::NonCopyable 44 { 45 public: 46 CommandProcessor(); 47 ~CommandProcessor() = default; 48 49 // Main worker loop that should be launched in its own thread. The 50 // loop waits for work to be submitted from a separate thread. 51 angle::Result processCommandProcessorTasks(); 52 // Called asynchronously from workLoop() thread to queue work that is 53 // then processed by the workLoop() thread 54 void queueCommands(const vk::CommandProcessorTask &commands); 55 // Used by separate thread to wait for worker thread to complete all 56 // outstanding work. 57 void waitForWorkComplete(); 58 // Stop the command processor loop 59 void shutdown(std::thread *commandProcessorThread); 60 61 private: 62 std::queue<vk::CommandProcessorTask> mCommandsQueue; 63 std::mutex mWorkerMutex; 64 // Signal worker thread when work is available 65 std::condition_variable mWorkAvailableCondition; 66 // Signal main thread when all work completed 67 std::condition_variable mWorkerIdleCondition; 68 // Track worker thread Idle state for assertion purposes 69 bool mWorkerThreadIdle; 70 }; 71 72 } // namespace rx 73 74 #endif // LIBANGLE_RENDERER_VULKAN_COMMAND_PROCESSOR_H_ 75