blob: 8f9199b2969027884b1d68695ddb32747d2ae439 [file]
/*
* Copyright 2026 Rive
*/
#ifndef _RIVE_SERIALIZED_REPLAY_HPP_
#define _RIVE_SERIALIZED_REPLAY_HPP_
#include "rive/factory.hpp"
#include "rive/renderer.hpp"
#include "rive/span.hpp"
#include <cstdint>
#include <functional>
// Replays a SerializingFactory SRIV stream against a real Factory and
// Renderer. The stream records at the Factory and Renderer abstraction level
// keyed by object id, so it is renderer implementation agnostic. Frame marker
// ops invoke hooks so a host can drive begin and flush around each frame.
namespace rive
{
struct SerializedReplayHooks
{
std::function<void()> onFrame = nullptr;
std::function<void(uint32_t width, uint32_t height)> onFrameSize = nullptr;
// Cache-as-bitmap: the stream carries offscreen canvas content inline,
// bracketed by canvasContentBegin/End, and composites the canvas with an
// ordinary drawImage of its id. A host with offscreen support opens the
// canvas's frame here and returns the renderer its draws replay into,
// plus the image a later composite should sample through *image.
// Returning null drops the content and the composite, which is what a
// host with no offscreen target does -- the rest of the frame still
// replays.
std::function<Renderer*(uint64_t id,
uint32_t width,
uint32_t height,
uint32_t clearColor,
rcp<RenderImage>* image)>
onCanvasContentBegin = nullptr;
std::function<void(uint64_t id)> onCanvasContentEnd = nullptr;
};
// Returns false on a bad header, unknown opcode, or truncated stream. The
// partial replay up to that point still happened.
bool replaySerializedCommands(Span<const uint8_t> stream,
Factory* factory,
Renderer* renderer,
const SerializedReplayHooks& hooks = {});
} // namespace rive
#endif