#pragma once // The renderer process (t5de-renderer.exe, 64-bit) an engine draws through: one for the whole client, started with // the first engine; each engine sends it the command stream through a shared memory channel of its own // (include/t5de/protocol/channel.hpp), and closes the channel when it's destroyed. #include #include #include #include #include "t5de/protocol/channel.hpp" namespace t5de { class RendererProcess { public: // A channel to the renderer process (t5de-renderer.exe from this DLL's folder, started if it isn't running), // drawing into part of window; null if it can't. static std::unique_ptr start(HWND window, protocol::View view); RendererProcess(const RendererProcess&) = delete; RendererProcess& operator=(const RendererProcess&) = delete; ~RendererProcess(); // Sends commands, in as many chunks as they take; endsFrame marks the end of a frame. False if the renderer // process is gone or stopped taking them (it's then given up on). bool send(std::span commands, bool endsFrame); // After sending a frame that reads its render target back: waits for the pixels (protocol::Channel), valid until // the next send. Empty if the renderer process couldn't, or is gone. std::span readBack(); [[nodiscard]] bool alive() const { return alive_; } // Whether the renderer process covers the whole 3D view (protocol::Channel::covering). [[nodiscard]] bool covering() const { return alive_ && channel_->covering != 0; } private: RendererProcess() = default; HANDLE mapping_ = nullptr; HANDLE ready_ = nullptr; HANDLE consumed_ = nullptr; HANDLE read_ = nullptr; HANDLE process_ = nullptr; protocol::Channel* channel_ = nullptr; std::byte* data_ = nullptr; bool alive_ = true; }; } // namespace t5de