Files
vii 02108a9bb1 perf(input): reuse the TextBox overlay fonts across rasters
Every keystroke re-ran TTF_Init, a fontconfig sort, six TTF_OpenFont calls
and TTF_Quit on the render thread. Hold the opened fonts on the overlay and
reopen them only when the Roblox font or the point size changes, keeping the
current set when a reopen fails. Measured over 100 rasters, 1.59 ms to
0.12 ms per keystroke.
2026-09-19 00:32:31 -05:00

69 lines
2.1 KiB
C++

#ifndef MOCKTAIL_RUNTIME_ROBLOX_TEXT_SURFACE_OVERLAY_H_
#define MOCKTAIL_RUNTIME_ROBLOX_TEXT_SURFACE_OVERLAY_H_
#include <cstddef>
#include <cstdint>
#include <mutex>
#include <string>
#include <vector>
#include "mocktail/graphics/text_overlay_frame.h"
#include "mocktail/status.h"
#include "runtime/roblox_text_display_state.h"
struct TTF_Font;
namespace mocktail {
namespace runtime {
// Thread-safe bridge from Roblox's synchronous TextBox callback to the
// direct-Vulkan present path. The input callback only updates bounded state.
// SDL3_ttf rasterization is deferred to the render thread and the resulting
// RGBA frame is copied into the existing swapchain by libvulkan.so.
class RobloxTextSurfaceOverlay final {
public:
RobloxTextSurfaceOverlay() = default;
~RobloxTextSurfaceOverlay();
RobloxTextSurfaceOverlay(const RobloxTextSurfaceOverlay&) = delete;
RobloxTextSurfaceOverlay& operator=(const RobloxTextSurfaceOverlay&) = delete;
Status Initialize(RobloxTextOverlayViewport viewport);
Status UpdateViewport(RobloxTextOverlayViewport viewport);
Status Shutdown();
RobloxTextDisplaySink sink();
bool QueryFrame(MocktailTextOverlayFrameInfo* frame);
bool CopyFrame(std::uint64_t revision, void* rgba, std::size_t rgba_capacity);
private:
static void UpdateCallback(void* context,
const RobloxTextDisplayUpdate& update);
void ApplyUpdate(const RobloxTextDisplayUpdate& update);
Status RasterizeLocked();
Status OpenFontsLocked(std::int32_t font, float point_size);
void CloseFontsLocked();
void ClearFrameLocked();
void RecordFailureLocked(Status status);
std::mutex mutex_;
RobloxTextDisplayState state_;
RobloxTextOverlayViewport viewport_;
std::vector<std::uint8_t> rgba_;
std::vector<TTF_Font*> fonts_;
std::int32_t fonts_font_ = 0;
float fonts_point_size_ = 0.0F;
std::uint64_t state_revision_ = 0;
std::uint64_t raster_revision_ = 0;
Status failure_;
bool initialized_ = false;
bool ttf_initialized_ = false;
bool failure_logged_ = false;
bool ready_logged_ = false;
};
} // namespace runtime
} // namespace mocktail
#endif // MOCKTAIL_RUNTIME_ROBLOX_TEXT_SURFACE_OVERLAY_H_