blob: 5eafa9b036714c3452883ead73bcf127037a611f [file] [log] [blame] [edit]
/*
* Copyright 2023 Rive
*/
#include "gm.hpp"
#include "gmutils.hpp"
#include "common/testing_window.hpp"
#include "rive/renderer/render_context.hpp"
using namespace rivegm;
using namespace rive;
// Ensures the PLS render target does not get cleared when using
// LoadAction::preserveRenderTarget.
class PreserveRenderTargetBase : public GM
{
protected:
PreserveRenderTargetBase(const char* name,
bool empty,
BlendMode blendMode) :
GM(64, 64, name), m_empty(empty), m_blendMode(blendMode)
{}
void run(std::vector<uint8_t>* pixels) override
{
Paint yellow;
yellow->color(0xffffff00);
// Set the render target to a cyan background with a yellow circle.
auto renderer =
TestingWindow::Get()->beginFrame({.clearColor = 0xff008080});
renderer->drawPath(PathBuilder::Circle(32, 32, 20), yellow);
// Don't clear to red!
if (auto* renderContext = TestingWindow::Get()->renderContext())
{
rive::gpu::RenderContext::FrameDescriptor frameDescriptor =
renderContext->frameDescriptor();
frameDescriptor.loadAction =
rive::gpu::LoadAction::preserveRenderTarget;
frameDescriptor.clearColor = 0xffff0000;
TestingWindow::Get()->flushPLSContext();
renderContext->beginFrame(std::move(frameDescriptor));
}
else
{
TestingWindow::Get()->endFrame();
renderer = TestingWindow::Get()->beginFrame({
.clearColor = 0xffff0000,
.doClear = false,
});
}
if (!m_empty)
{
// Add a black circle on top of the preserved yellow one.
Paint black;
black->color(0xff000000);
black->blendMode(m_blendMode);
renderer->drawPath(PathBuilder::Circle(32, 32, 8), black);
}
TestingWindow::Get()->endFrame(pixels);
}
void onDraw(rive::Renderer*) override { RIVE_UNREACHABLE(); }
const bool m_empty;
const BlendMode m_blendMode;
};
class PreserveRenderTargetGM : public PreserveRenderTargetBase
{
public:
PreserveRenderTargetGM() :
PreserveRenderTargetBase("preserverendertarget",
false,
BlendMode::srcOver)
{}
};
GMREGISTER(return new PreserveRenderTargetGM)
class PreserveRenderTargetBlendModeGM : public PreserveRenderTargetBase
{
public:
PreserveRenderTargetBlendModeGM() :
PreserveRenderTargetBase("preserverendertarget_blendmode",
false,
BlendMode::darken)
{}
};
GMREGISTER(return new PreserveRenderTargetBlendModeGM)
class PreserveRenderTargetEmptyGM : public PreserveRenderTargetBase
{
public:
PreserveRenderTargetEmptyGM() :
PreserveRenderTargetBase("preserverendertarget_empty",
true,
BlendMode::srcOver)
{}
};
GMREGISTER(return new PreserveRenderTargetEmptyGM)