-
Notifications
You must be signed in to change notification settings - Fork 4
/
makie_viewport.cpp
116 lines (98 loc) · 2.59 KB
/
makie_viewport.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "jlcxx/functions.hpp"
#include "makie_viewport.hpp"
#include "julia_api.hpp"
#include <QOpenGLContext>
#include <QQuickWindow>
#include <julia.h>
namespace qmlwrap
{
class MakieRenderFunction : public RenderFunction
{
public:
MakieRenderFunction(jl_value_t* const & screen_ptr) : m_screen_ptr(screen_ptr)
{
}
void setRenderFunction(jlcxx::SafeCFunction f) override
{
m_render_function = jlcxx::make_function_pointer<void(jl_value_t*)>(f);
}
void render() override
{
m_render_function(m_screen_ptr);
}
private:
typedef void (*render_callback_t)(jl_value_t*);
render_callback_t m_render_function;
jl_value_t* const & m_screen_ptr;
};
jl_module_t* get_makie_support_module()
{
// MakieViewport::m_qml_mod is set when initializing the Julia module `QtMakie`,
// corresponding to `JLCXX_MODULE define_julia_module_makie` in `wrap_qml.cpp`.
jl_module_t* mod = MakieViewport::m_qml_mod;
// If `mod` is not initialized, you have not loaded the Julia module.
if(mod == nullptr)
{
throw std::runtime_error("Makie Support not initialized. Have you loaded QtMakie?");
}
return mod;
}
/// Takes care of loading the MakieSupport Julia module
struct MakieSupport
{
static MakieSupport& instance()
{
static MakieSupport m_instance;
return m_instance;
}
~MakieSupport()
{
}
private:
MakieSupport() :
m_makie_mod(get_makie_support_module()),
setup_screen(jl_get_function(m_makie_mod, "setup_screen")),
on_context_destroy(jl_get_function(m_makie_mod, "on_context_destroy"))
{
}
jl_module_t* m_makie_mod = nullptr;
public:
jlcxx::JuliaFunction setup_screen;
jlcxx::JuliaFunction on_context_destroy;
};
MakieViewport::MakieViewport(QQuickItem *parent) : OpenGLViewport(parent, new MakieRenderFunction(m_screen))
{
QObject::connect(this, &QQuickItem::windowChanged, [this] (QQuickWindow* w)
{
if (w == nullptr)
{
return;
}
connect(w, &QQuickWindow::sceneGraphInvalidated, [this] ()
{
MakieSupport::instance().on_context_destroy();
});
});
}
MakieViewport::~MakieViewport()
{
if(m_screen != nullptr)
{
jlcxx::unprotect_from_gc(m_screen);
}
}
void MakieViewport::setup_buffer(QOpenGLFramebufferObject* fbo)
{
if(m_screen == nullptr)
{
m_screen = MakieSupport::instance().setup_screen(std::forward<QOpenGLFramebufferObject*>(fbo));
jlcxx::protect_from_gc(m_screen);
}
else
{
assert(m_screen != nullptr);
MakieSupport::instance().setup_screen(m_screen, std::forward<QOpenGLFramebufferObject*>(fbo));
}
}
jl_module_t* MakieViewport::m_qml_mod = nullptr;
} // namespace qmlwrap