Draw render targets in the renderer process
CI / build (push) Successful in 48s

While the renderer process runs, the adapter makes the client's render targets
itself and the renderer process draws frames into them: texture targets are
drawn with like any texture, and a pixmap target's frame is read back through
the channel into its Pixmap (protocol version 4: BeginFrame names its target,
CreateRenderTarget, Channel::readSize and the -read event). Frames into render
targets are drawn even while the window is hidden.

The client uses pixmap targets for snapshots (outfit pictures, photos), checked
to look right. The render target interfaces are declared from IMVU's vtables.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
dhkatzandClaude Opus 5.5 committed 2026-10-28 19:09:48 -07:00
1 parent fa883892db
commit 6e4fe589e5
18 files changed
+523 -58

No files matched your search

+48 -2
View File
@@ -3,8 +3,12 @@
// client renderer still draws with) and mirrors it, by id, to the renderer process. The client deletes them through
// their virtual destructors.
#include <cstddef>
#include <cstdint>
#include <memory>
#include <span>
#include "pixmap.hpp"
#include "recorder.hpp"
#include "t5de/imvu/resources.hpp"
@@ -14,6 +18,9 @@ namespace t5de {
class Texture final : public imvu::PiRenderTexture {
public:
Texture(imvu::PiRenderTexture* inner, std::shared_ptr<Recorder> recorder, std::uint32_t id);
// What's been drawn into one of our texture render targets (TextureTarget): no texture of the client renderer's,
// and the id stays the target's.
Texture(std::shared_ptr<Recorder> recorder, std::uint32_t targetId, imvu::Vec2i size);
~Texture() override;
imvu::Vec2i size() const override;
@@ -28,6 +35,44 @@ private:
imvu::PiRenderTexture* inner_;
std::shared_ptr<Recorder> recorder_;
std::uint32_t id_;
imvu::Vec2i size_{};
bool ownsId_ = true;
};
// Render targets the renderer process draws (made while it runs; otherwise the client renderer makes its own).
class PixmapTarget final : public imvu::PiPixmapRenderTarget {
public:
PixmapTarget(std::shared_ptr<Recorder> recorder, imvu::Vec2i size);
~PixmapTarget() override;
imvu::Pixmap* getPixmap(imvu::Pixmap* result) const override;
// Copies a frame's pixels, read back from the renderer process (rows packed, 0xAARRGGBB), into the pixmap.
void setPixels(std::span<const std::byte> pixels);
[[nodiscard]] std::uint32_t id() const { return id_; }
private:
std::shared_ptr<Recorder> recorder_;
std::uint32_t id_;
imvu::Vec2i size_;
OwnedPixmap pixmap_;
};
class TextureTarget final : public imvu::PiTextureRenderTarget {
public:
TextureTarget(std::shared_ptr<Recorder> recorder, imvu::Vec2i size);
~TextureTarget() override;
imvu::TextureArea* area(imvu::TextureArea* result) const override;
imvu::SharedPtr<imvu::PiRenderTexture>* texture(imvu::SharedPtr<imvu::PiRenderTexture>* result) const override;
[[nodiscard]] std::uint32_t id() const { return id_; }
private:
std::shared_ptr<Recorder> recorder_;
std::uint32_t id_;
imvu::Vec2i size_;
};
class IndexBuffer final : public imvu::PiInternalIndexBuffer {
@@ -62,8 +107,9 @@ private:
std::uint32_t id_;
};
// Whether an object is one of ours (live Texture, IndexBuffer or VertexBuffer): the client can also hand the engine
// objects the client renderer made itself (render targets' textures), which must reach it unchanged.
// Whether an object is one of ours (live Texture, IndexBuffer, VertexBuffer, PixmapTarget or TextureTarget): the client
// can also hand the engine objects the client renderer made itself (its render targets, and their textures), which
// must reach it unchanged.
bool ours(const void* object);
// The client renderer's object, and our id, for what the client passes in: ours unwrapped, others unchanged (id 0).