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:
1 parent
fa883892db
commit
6e4fe589e5
18 files changed
+523
-58
No files matched your search
+32
-9
@@ -232,39 +232,62 @@ imvu::PiInternalVertexBuffer* Engine::newDynamicVertexBuffer(std::uint32_t eleme
|
||||
imvu::SharedPtr<imvu::PiPixmapRenderTarget> Engine::newPixmapRenderTarget(imvu::Vec2i size)
|
||||
{
|
||||
log::info("engine: frame {}: a {}x{} pixmap render target", frames_, size.x, size.y);
|
||||
return inner_->newPixmapRenderTarget(size);
|
||||
if (!recorder_->active() || size.x <= 0 || size.y <= 0) {
|
||||
return inner_->newPixmapRenderTarget(size);
|
||||
}
|
||||
return imvu::SharedPtr<PixmapTarget>(std::make_unique<PixmapTarget>(recorder_, size));
|
||||
}
|
||||
|
||||
imvu::SharedPtr<imvu::PiTextureRenderTarget> Engine::newTextureRenderTarget(imvu::Vec2i size)
|
||||
{
|
||||
log::info("engine: frame {}: a {}x{} texture render target", frames_, size.x, size.y);
|
||||
return inner_->newTextureRenderTarget(size);
|
||||
if (!recorder_->active() || size.x <= 0 || size.y <= 0) {
|
||||
return inner_->newTextureRenderTarget(size);
|
||||
}
|
||||
return imvu::SharedPtr<TextureTarget>(std::make_unique<TextureTarget>(recorder_, size));
|
||||
}
|
||||
|
||||
void Engine::beginRendering(imvu::PiRenderTarget* target)
|
||||
{
|
||||
inner_->beginRendering(target);
|
||||
// Decided per frame: frames into render targets, and frames while the renderer process doesn't cover the view, are
|
||||
// drawn by the client's renderer.
|
||||
const bool takenOver = target == nullptr && recorder_->covering();
|
||||
// Frames into our render targets are drawn by the renderer process only; the client's renderer doesn't know them.
|
||||
ourTarget_ = ours(target) ? target : nullptr;
|
||||
if (ourTarget_ == nullptr) {
|
||||
inner_->beginRendering(target);
|
||||
}
|
||||
// Decided per frame: frames into the client renderer's render targets, and frames while the renderer process
|
||||
// doesn't cover the view, are drawn by the client's renderer.
|
||||
const bool takenOver = ourTarget_ != nullptr || (target == nullptr && recorder_->covering());
|
||||
if (takenOver != takenOver_ && target == nullptr) {
|
||||
log::info("engine: frame {}: {}", frames_, takenOver ? "drawn by the renderer process" : "drawn by the client's renderer");
|
||||
}
|
||||
takenOver_ = takenOver;
|
||||
if (target != nullptr && foreignLogged_ < 20) {
|
||||
++foreignLogged_;
|
||||
log::info("engine: frame {}: drawing into a render target ({})", frames_, static_cast<void*>(target));
|
||||
log::info("engine: frame {}: drawing into {} render target ({})", frames_,
|
||||
ourTarget_ != nullptr ? "our" : "the client renderer's", static_cast<void*>(target));
|
||||
}
|
||||
recorder_->add(Op::BeginFrame, protocol::BeginFrame{target != nullptr});
|
||||
protocol::BeginFrame begin{target == nullptr ? 0 : protocol::foreignTarget, 0};
|
||||
if (const auto* pixmap = dynamic_cast<const PixmapTarget*>(ourTarget_)) {
|
||||
begin = {pixmap->id(), 1};
|
||||
} else if (const auto* texture = dynamic_cast<const TextureTarget*>(ourTarget_)) {
|
||||
begin = {texture->id(), 0};
|
||||
}
|
||||
recorder_->add(Op::BeginFrame, begin);
|
||||
}
|
||||
|
||||
void Engine::endRendering()
|
||||
{
|
||||
inner_->endRendering();
|
||||
if (ourTarget_ == nullptr) {
|
||||
inner_->endRendering();
|
||||
}
|
||||
LARGE_INTEGER now;
|
||||
QueryPerformanceCounter(&now);
|
||||
recorder_->add(Op::EndFrame, protocol::EndFrame{static_cast<std::uint64_t>(now.QuadPart)});
|
||||
recorder_->flush(true);
|
||||
if (auto* pixmap = dynamic_cast<PixmapTarget*>(ourTarget_)) {
|
||||
pixmap->setPixels(recorder_->readBack());
|
||||
}
|
||||
ourTarget_ = nullptr;
|
||||
++frames_;
|
||||
if (frames_ % 300 == 0 && statsLogged_ < 6) {
|
||||
++statsLogged_;
|
||||
|
||||
Reference in new issue
Block a user