The adapter records everything the client draws (state, transforms, lights, fog, textures and buffers) as a command stream, sent in chunks through the shared memory channel, while IMVU's Direct3D renderer still draws the whole view. The renderer process draws it with Diligent, with shaders reproducing IMVU's Direct3D 9 fixed-function setup, over the right half of the 3D view to compare. It skips to the newest frame when it falls behind, and logs its errors and frame times. Co-Authored-By: Claude Opus 5.5 <[email protected]>
60 lines
2.2 KiB
C++
60 lines
2.2 KiB
C++
#pragma once
|
|
// Records what the client draws as commands (include/t5de/protocol/commands.hpp) and sends them to the renderer
|
|
// process. Shared by an engine and the resources it creates (which can outlive it); once the renderer process is
|
|
// gone, it records nothing.
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
|
|
#include "renderer_process.hpp"
|
|
#include "t5de/imvu/types.hpp"
|
|
#include "t5de/protocol/commands.hpp"
|
|
|
|
namespace t5de {
|
|
|
|
class Recorder {
|
|
public:
|
|
explicit Recorder(std::unique_ptr<RendererProcess> process);
|
|
|
|
[[nodiscard]] bool active() const { return process_ && process_->alive(); }
|
|
|
|
// Records a command (if active); returns its payload to fill, or null.
|
|
template <class Body>
|
|
std::byte* add(protocol::Op op, const Body& body, std::size_t payloadSize = 0)
|
|
{
|
|
if (!active()) {
|
|
return nullptr;
|
|
}
|
|
std::byte* payload = writer_.add(op, body, payloadSize);
|
|
return payload;
|
|
}
|
|
|
|
// Sends what's recorded: at the end of each frame, and between frames when a lot is waiting (resources).
|
|
void flush(bool endsFrame);
|
|
void flushIfLarge();
|
|
|
|
std::uint32_t createTexture(const imvu::Pixmap& pixmap, std::uint32_t flags);
|
|
void updateTexture(std::uint32_t id, const imvu::Pixmap& pixmap);
|
|
void destroyTexture(std::uint32_t id);
|
|
|
|
// Copies count elements of elementSize bytes, stride bytes apart (0: packed), from data (null: none yet).
|
|
std::uint32_t createBuffer(protocol::BufferKind kind, const void* data, std::uint32_t stride,
|
|
std::uint32_t elementSize, std::uint32_t count);
|
|
void updateBuffer(std::uint32_t id, const void* data, std::uint32_t stride, std::uint32_t elementSize,
|
|
std::uint32_t count);
|
|
void destroyBuffer(std::uint32_t id);
|
|
|
|
private:
|
|
void addPixels(protocol::Op op, std::uint32_t id, const imvu::Pixmap& pixmap, std::uint32_t flags);
|
|
|
|
std::unique_ptr<RendererProcess> process_;
|
|
protocol::Writer writer_;
|
|
std::uint32_t nextId_ = 1;
|
|
};
|
|
|
|
// Copies count elements of elementSize bytes, stride bytes apart (0: packed), into destination, packed.
|
|
void pack(std::byte* destination, const void* source, std::uint32_t stride, std::uint32_t elementSize,
|
|
std::uint32_t count);
|
|
|
|
} // namespace t5de
|