Skip to content

Commit

Permalink
[gfx] Many improvements to texture filter processes and to message bu…
Browse files Browse the repository at this point in the history
…sses for GPU processes
  • Loading branch information
jcelerier committed Nov 21, 2023
1 parent 95268ea commit 89130fb
Show file tree
Hide file tree
Showing 15 changed files with 123 additions and 36 deletions.
8 changes: 8 additions & 0 deletions src/plugins/score-plugin-avnd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,14 @@ avnd_make_score(
NAMESPACE ao
)

avnd_make_score(
SOURCES "${AVND_FOLDER}/examples/Advanced/Utilities/LightnessSampler.hpp"
TARGET lightness_sampler
MAIN_CLASS LightnessSampler
NAMESPACE vo
)


avnd_make_score(
SOURCES "${AVND_FOLDER}/examples/Gpu/SolidColor.hpp"
TARGET gpu_solid_color
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/score-plugin-avnd/Crousti/CpuAnalysisNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,12 @@ template <typename Node_T>
&& avnd::texture_output_introspection<Node_T>::size == 0)
struct GfxNode<Node_T> final : CustomGpuOutputNodeBase
{
oscr::ProcessModel<Node_T>& processModel;
GfxNode(
oscr::ProcessModel<Node_T>& element,
std::weak_ptr<Execution::ExecutionCommandQueue> q, Gfx::exec_controls ctls, int id)
: CustomGpuOutputNodeBase{std::move(q), std::move(ctls)}
, processModel{element}
{
this->instance = id;

Expand Down
4 changes: 3 additions & 1 deletion src/plugins/score-plugin-avnd/Crousti/CpuFilterNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,12 @@ struct GfxNode<Node_T> final
: CustomGfxNodeBase
, GpuControlOuts
{
oscr::ProcessModel<Node_T>& processModel;
GfxNode(
oscr::ProcessModel<Node_T>& element,
std::weak_ptr<Execution::ExecutionCommandQueue> q, Gfx::exec_controls ctls, int id)
: GpuControlOuts{std::move(q), std::move(ctls)}
, processModel{element}
{
this->instance = id;

Expand All @@ -325,6 +328,5 @@ struct GfxNode<Node_T> final
return new GfxRenderer<Node_T>{*this};
}
};

}
#endif
4 changes: 3 additions & 1 deletion src/plugins/score-plugin-avnd/Crousti/CpuGeneratorNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,12 @@ struct GfxNode<Node_T> final
: CustomGfxNodeBase
, GpuControlOuts
{
oscr::ProcessModel<Node_T>& processModel;
GfxNode(
oscr::ProcessModel<Node_T>& element,
std::weak_ptr<Execution::ExecutionCommandQueue> q, Gfx::exec_controls ctls, int id)
: GpuControlOuts{std::move(q), std::move(ctls)}
, processModel{element}
{
this->instance = id;

Expand All @@ -227,6 +230,5 @@ struct GfxNode<Node_T> final
return new GfxRenderer<Node_T>{*this};
}
};

}
#endif
29 changes: 16 additions & 13 deletions src/plugins/score-plugin-avnd/Crousti/Executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,15 +615,18 @@ class Executor final
std::unique_ptr<score::gfx::Node> ptr;
if constexpr(GpuGraphicsNode2<Node>)
{
ptr.reset(new CustomGpuNode<Node>(qex_ptr, node->control_outs, id));
auto gpu_node = new CustomGpuNode<Node>(qex_ptr, node->control_outs, id);
ptr.reset(gpu_node);
}
else if constexpr(GpuComputeNode2<Node>)
{
ptr.reset(new GpuComputeNode<Node>(qex_ptr, node->control_outs, id));
auto gpu_node = new GpuComputeNode<Node>(qex_ptr, node->control_outs, id);
ptr.reset(gpu_node);
}
else if constexpr(GpuNode<Node>)
{
ptr.reset(new GfxNode<Node>(qex_ptr, node->control_outs, id));
auto gpu_node = new GfxNode<Node>(element, qex_ptr, node->control_outs, id);
ptr.reset(gpu_node);
}
node->id = gfx_exec.ui->register_node(std::move(ptr));
node_id = node->id;
Expand All @@ -640,7 +643,9 @@ class Executor final
ptr.reset(node);
this->node = ptr;

connect_message_bus(element, ctx, ptr);
if constexpr(requires { ptr->impl.effect; })
if constexpr(std::is_same_v<std::decay_t<decltype(ptr->impl.effect)>, Node>)
connect_message_bus(element, ctx, ptr->impl.effect);
connect_worker(element, ctx, ptr);

node->finish_init();
Expand Down Expand Up @@ -722,41 +727,39 @@ class Executor final
}

void connect_message_bus(
ProcessModel<Node>& element, const ::Execution::Context& ctx,
std::shared_ptr<safe_node<Node>>& ptr)
ProcessModel<Node>& element, const ::Execution::Context& ctx, Node& eff)
{
// Custom UI messages to engine
avnd::effect_container<Node>& eff = ptr->impl;
if constexpr(avnd::has_gui_to_processor_bus<Node>)
{
element.from_ui = [p = QPointer{this}, &eff](QByteArray b) {
if(!p)
return;

p->in_exec([mess = std::move(b), &eff] {
p->in_exec([mess = std::move(b), &eff]() mutable {
using refl = avnd::function_reflection<&Node::process_message>;
static_assert(refl::count <= 1);

if constexpr(refl::count == 0)
{
// no arguments, just call it
eff.effect.process_message();
eff.process_message();
}
else if constexpr(refl::count == 1)
{
using arg_type = avnd::first_argument<&Node::process_message>;
std::decay_t<arg_type> arg;
MessageBusReader b{mess};
b(arg);
eff.effect.process_message(std::move(arg));
MessageBusReader reader{mess};
reader(arg);
eff.process_message(std::move(arg));
}
});
};
}

if constexpr(avnd::has_processor_to_gui_bus<Node>)
{
eff.effect.send_message = [this](auto b) mutable {
eff.send_message = [this](auto b) mutable {
this->in_edit([this, bb = std::move(b)]() mutable {
MessageBusSender{this->process().to_ui}(std::move(bb));
});
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/score-plugin-avnd/Crousti/GfxNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@

#include <avnd/binding/ossia/port_run_preprocess.hpp>
#include <avnd/common/for_nth.hpp>

namespace oscr
{
template <typename Info>
class ProcessModel;
static const constexpr auto generic_texgen_vs = R"_(#version 450
layout(location = 0) in vec2 position;
layout(location = 1) in vec2 texcoord;
Expand Down
12 changes: 7 additions & 5 deletions src/plugins/score-plugin-avnd/Crousti/GpuUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,16 @@ CustomGpuOutputNodeBase::CustomGpuOutputNodeBase(
m_renderState->rhi = QRhi::create(QRhi::OpenGLES2, &params);
}

m_renderState->renderSize = QSize(1000, 1000);
m_renderState->outputSize = QSize(1000, 1000);
m_renderState->renderSize = QSize(200, 200);
m_renderState->outputSize = QSize(200, 200);
m_renderState->api = score::gfx::GraphicsApi::OpenGL;
m_renderState->version = caps.qShaderVersion;
}
CustomGpuOutputNodeBase::~CustomGpuOutputNodeBase() = default;

CustomGpuOutputNodeBase::~CustomGpuOutputNodeBase()
{
m_renderState->destroy();
}

void CustomGpuOutputNodeBase::process(score::gfx::Message&& msg)
{
Expand All @@ -66,7 +70,6 @@ void CustomGpuOutputNodeBase::process(score::gfx::Message&& msg)

void CustomGpuOutputNodeBase::setRenderer(std::shared_ptr<score::gfx::RenderList> r)
{

m_renderer = r;
}

Expand All @@ -79,7 +82,6 @@ void CustomGpuOutputNodeBase::startRendering() { }

void CustomGpuOutputNodeBase::render()
{

if(m_update)
m_update();

Expand Down
19 changes: 16 additions & 3 deletions src/plugins/score-plugin-avnd/Crousti/GpuUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#if SCORE_PLUGIN_GFX
#include <Process/ExecutionContext.hpp>

#include <Crousti/MessageBus.hpp>
#include <Gfx/GfxExecNode.hpp>
#include <Gfx/Graph/Node.hpp>
#include <Gfx/Graph/OutputNode.hpp>
Expand Down Expand Up @@ -916,17 +917,29 @@ struct SCORE_PLUGIN_AVND_EXPORT CustomGpuOutputNodeBase
};

template <typename Node_T, typename Node>
void prepareNewState(Node_T& node, const Node& parent)
void prepareNewState(Node_T& eff, const Node& parent)
{
if constexpr(avnd::has_processor_to_gui_bus<Node_T>)
{
auto& process = parent.processModel;
eff.send_message = [&process](auto&& b) mutable {
// FIXME right now all the rendering is done in the UI thread, which is very MEH
// this->in_edit([&process, bb = std::move(b)]() mutable {
MessageBusSender{process.to_ui}(std::move(b));
// });
};

// FIXME GUI -> engine. See executor.hpp
}

if constexpr(avnd::can_prepare<Node_T>)
{
using prepare_type = avnd::first_argument<&Node_T::prepare>;
prepare_type t;
if_possible(t.instance = parent.instance);
node.prepare(t);
eff.prepare(t);
}
}

}

#endif
8 changes: 6 additions & 2 deletions src/plugins/score-plugin-avnd/Crousti/Layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,11 @@ class LayerFactory final : public Process::LayerFactory
if constexpr(avnd::has_processor_to_gui_bus<Info>)
{
// engine -> ui
proc.to_ui = [ptr](QByteArray mess) {
proc.to_ui = [ptr = QPointer{ptr}](QByteArray mess) {
// FIXME this is not enough as the message may be sent from another thread?
if(!ptr)
return;

if constexpr(requires { ptr->bus.process_message(); })
{
ptr->bus.process_message();
Expand All @@ -350,7 +354,7 @@ class LayerFactory final : public Process::LayerFactory
}
else if constexpr(requires { ptr->bus.process_message(ptr->ui, {}); })
{
avnd::second_argument<&Info::ui::bus::process_message> arg;
std::decay_t<avnd::second_argument<&Info::ui::bus::process_message>> arg;
MessageBusReader b{mess};
b(arg);
ptr->bus.process_message(ptr->ui, std::move(arg));
Expand Down
43 changes: 39 additions & 4 deletions src/plugins/score-plugin-avnd/Crousti/MessageBus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

#include <boost/pfr.hpp>

#include <avnd/common/tag.hpp>
#include <avnd/concepts/message_bus.hpp>

namespace oscr
{

Expand Down Expand Up @@ -43,15 +46,38 @@ struct MessageBusSender
}

template <typename T>
requires(!std::is_trivial_v<T>) void operator()(const T& msg)
requires(!std::is_trivial_v<T> && avnd::relocatable<T>)
void operator()(const T& msg)
{
QByteArray b(msg.size(), Qt::Uninitialized);
auto dst = reinterpret_cast<T*>(b.data());
new(dst) T(msg);

this->bus(std::move(b));
}

template <typename T>
requires(!std::is_trivial_v<T> && avnd::relocatable<T>)
void operator()(T&& msg)
{
QByteArray b(sizeof(msg), Qt::Uninitialized);
auto dst = reinterpret_cast<T*>(b.data());
std::construct_at(dst, std::move(msg));

this->bus(std::move(b));
}

template <typename T>
requires(!std::is_trivial_v<T> && !avnd::relocatable<T>)
void operator()(const T& msg)
{
// Here we gotta serialize... :D
QByteArray buf;

DataStreamReader str{&buf};
Serializer{str}(msg);

this->bus(buf);
this->bus(std::move(buf));
}
};

Expand Down Expand Up @@ -92,7 +118,7 @@ struct Deserializer

struct MessageBusReader
{
const QByteArray& mess;
QByteArray& mess;

template <typename T>
requires std::is_trivial_v<T>
Expand All @@ -101,9 +127,18 @@ struct MessageBusReader
// Here we can just do a memcpy
memcpy(&msg, mess.data(), mess.size());
}
template <typename T>
requires(!std::is_trivial_v<T> && avnd::relocatable<T>)
void operator()(T& msg)
{
auto src = reinterpret_cast<T*>(mess.data());
msg = std::move(*src);
std::destroy_at(src);
}

template <typename T>
requires(!std::is_trivial_v<T>) void operator()(T& msg)
requires(!std::is_trivial_v<T> && !avnd::relocatable<T>)
void operator()(T& msg)
{
// Deserialize... :D

Expand Down
6 changes: 6 additions & 0 deletions src/plugins/score-plugin-avnd/Crousti/Painter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ struct QPainterAdapter
}
path.addPolygon(poly);
}

void draw_bytes(int x, int y, int w, int h, unsigned char* image, int img_w, int img_h)
{
auto img = QImage(image, img_w, img_h, QImage::Format_RGB32);
painter.drawImage(QRect(x, y, w, h), img, QRect(0, 0, img_w, img_h));
}
};
static_assert(avnd::painter<QPainterAdapter>);

Expand Down
10 changes: 10 additions & 0 deletions src/plugins/score-plugin-gfx/Gfx/Graph/RenderState.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <QOffscreenSurface>
#include <QtGui/private/qrhi_p.h>

#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
Expand Down Expand Up @@ -44,5 +45,14 @@ struct RenderState
int samples{1};
GraphicsApi api{};
QShaderVersion version{};

void destroy()
{
delete rhi;
rhi = nullptr;

delete surface;
surface = nullptr;
}
};
}
6 changes: 1 addition & 5 deletions src/plugins/score-plugin-gfx/Gfx/Graph/ScreenNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,11 +420,7 @@ void ScreenNode::destroyOutput()

if(auto s = m_window->state)
{
delete s->rhi;
s->rhi = nullptr;

delete s->surface;
s->surface = nullptr;
s->destroy();
}

if(m_ownsWindow)
Expand Down

0 comments on commit 89130fb

Please sign in to comment.