summaryrefslogtreecommitdiffstats
path: root/src/ui/widget/optglarea.h
blob: fa71afc9ba9233d96b9f0556f6452b7f96b4a378 (plain)
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
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef INKSCAPE_UI_WIDGET_OPTGLAREA_H
#define INKSCAPE_UI_WIDGET_OPTGLAREA_H

#include <gtkmm.h>
#include <epoxy/gl.h>

namespace Cairo {
class Context;
}

namespace Inkscape {
namespace UI {
namespace Widget {

/**
 * A widget that can dynamically switch between a Gtk::DrawingArea and a Gtk::GLArea.
 * Based on the GTK source code for both widgets.
 */
class OptGLArea : public Gtk::DrawingArea
{
public:
    OptGLArea();

    /**
     * Set whether OpenGL is enabled. Initially it is disabled. Upon enabling it,
     * create_context will be called as soon as the widget is realized. If
     * context creation fails, OpenGL will be disabled again.
     */
    void set_opengl_enabled(bool);
    bool get_opengl_enabled() const { return opengl_enabled; }

    /**
     * Call before doing any OpenGL operations to make the context current.
     * Automatically done before calling opengl_render.
     */
    void make_current();

    /**
     * Call before rendering to the widget to bind the widget's framebuffer.
     */
    void bind_framebuffer() const;

protected:
    void on_realize() override;
    void on_unrealize() override;
    void on_size_allocate(Gtk::Allocation&) override;
    bool on_draw(const Cairo::RefPtr<Cairo::Context>&) final;

    /**
     * Reimplement to create the desired OpenGL context. Return nullptr on error.
     */
    virtual Glib::RefPtr<Gdk::GLContext> create_context() = 0;

    /**
     * Reimplement to render the widget. The Cairo context is only for when OpenGL is disabled.
     */
    virtual void paint_widget(const Cairo::RefPtr<Cairo::Context>&) {}

private:
    void init_opengl();
    void create_framebuffer();
    void delete_framebuffer();
    void resize_framebuffer() const;

    Glib::RefPtr<Gdk::GLContext> context;

    bool opengl_enabled;
    bool need_resize;

    GLuint framebuffer;
    GLuint renderbuffer;
    GLuint stencilbuffer;
};

} // namespace Widget
} // namespace UI
} // namespace Inkscape

#endif // INKSCAPE_UI_WIDGET_OPTGLAREA_H