blob: a30d10fbed4defadfc96dd64b6e8fe2c48ba9afd [file]
/*
* Copyright 2026 Rive
*
* Draws the same shape immediately and via a SerializingFactory recording
* replayed against the real factory and renderer. The goldens must be byte
* identical since the recorded stream is the deferral contract.
*/
#include "gm.hpp"
#include "gmutils.hpp"
#include "utils/serializing_factory.hpp"
#include "utils/serialized_replay.hpp"
#include "rive/math/raw_path.hpp"
using namespace rivegm;
using namespace rive;
static RawPath kShape()
{
// Nonconvex polygon so winding is exercised.
RawPath p;
p.move({40, 40});
p.line({160, 70});
p.line({120, 110});
p.line({200, 200});
p.line({120, 160});
p.line({60, 210});
p.close();
return p;
}
class SerializedReplay2DGM : public GM
{
public:
SerializedReplay2DGM(bool replay) : GM(256, 256), m_replay(replay) {}
ColorInt clearColor() const override { return 0xff202028; }
void onDraw(rive::Renderer* renderer) override
{
Factory* factory = TestingWindow::Get()->factory();
if (!factory)
return;
RawPath shape = kShape();
if (m_replay)
{
SerializingFactory sf;
auto recorder = sf.makeRenderer();
auto path = sf.makeRenderPath(shape, FillRule::nonZero);
auto paint = sf.makeRenderPaint();
paint->color(0xFFFFA030);
paint->style(RenderPaintStyle::fill);
recorder->drawPath(path.get(), paint.get());
replaySerializedCommands(sf.bytes(), factory, renderer);
}
else
{
auto path = factory->makeRenderPath(shape, FillRule::nonZero);
auto paint = factory->makeRenderPaint();
paint->color(0xFFFFA030);
paint->style(RenderPaintStyle::fill);
renderer->drawPath(path.get(), paint.get());
}
}
private:
bool m_replay;
};
GMREGISTER(serialized_replay_2d_immediate,
return new SerializedReplay2DGM(false))
GMREGISTER(serialized_replay_2d, return new SerializedReplay2DGM(true))