1
2
3
4
5
6
7
8
9
10
11
12
13
14#include "qemu-common.h"
15
16#include "trace.h"
17
18#include "ui/console.h"
19#include "ui/gtk.h"
20#include "ui/egl-helpers.h"
21
22#include "sysemu/sysemu.h"
23
24
25
26void gd_egl_init(VirtualConsole *vc)
27{
28 GdkWindow *gdk_window = gtk_widget_get_window(vc->gfx.drawing_area);
29 if (!gdk_window) {
30 return;
31 }
32
33#if GTK_CHECK_VERSION(3, 0, 0)
34 Window x11_window = gdk_x11_window_get_xid(gdk_window);
35#else
36 Window x11_window = gdk_x11_drawable_get_xid(gdk_window);
37#endif
38 if (!x11_window) {
39 return;
40 }
41
42 vc->gfx.ectx = qemu_egl_init_ctx();
43 vc->gfx.esurface = qemu_egl_init_surface_x11(vc->gfx.ectx, x11_window);
44
45 assert(vc->gfx.esurface);
46}
47
48void gd_egl_draw(VirtualConsole *vc)
49{
50 GdkWindow *window;
51 int ww, wh;
52
53 if (!vc->gfx.gls || !vc->gfx.ds) {
54 return;
55 }
56
57 eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
58 vc->gfx.esurface, vc->gfx.ectx);
59
60 window = gtk_widget_get_window(vc->gfx.drawing_area);
61 gdk_drawable_get_size(window, &ww, &wh);
62 surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
63 surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
64
65 eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
66}
67
68void gd_egl_update(DisplayChangeListener *dcl,
69 int x, int y, int w, int h)
70{
71 VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
72
73 if (!vc->gfx.gls || !vc->gfx.ds) {
74 return;
75 }
76
77 eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
78 vc->gfx.esurface, vc->gfx.ectx);
79 surface_gl_update_texture(vc->gfx.gls, vc->gfx.ds, x, y, w, h);
80 vc->gfx.glupdates++;
81}
82
83void gd_egl_refresh(DisplayChangeListener *dcl)
84{
85 VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
86
87 if (!vc->gfx.esurface) {
88 gd_egl_init(vc);
89 if (!vc->gfx.esurface) {
90 return;
91 }
92 vc->gfx.gls = console_gl_init_context();
93 if (vc->gfx.ds) {
94 surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
95 }
96 }
97
98 graphic_hw_update(dcl->con);
99
100 if (vc->gfx.glupdates) {
101 vc->gfx.glupdates = 0;
102 gd_egl_draw(vc);
103 }
104}
105
106void gd_egl_switch(DisplayChangeListener *dcl,
107 DisplaySurface *surface)
108{
109 VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
110 bool resized = true;
111
112 trace_gd_switch(vc->label, surface_width(surface), surface_height(surface));
113
114 if (vc->gfx.ds &&
115 surface_width(vc->gfx.ds) == surface_width(surface) &&
116 surface_height(vc->gfx.ds) == surface_height(surface)) {
117 resized = false;
118 }
119
120 surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
121 vc->gfx.ds = surface;
122 if (vc->gfx.gls) {
123 surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
124 }
125
126 if (resized) {
127 gd_update_windowsize(vc);
128 }
129}
130
131void gtk_egl_init(void)
132{
133 GdkDisplay *gdk_display = gdk_display_get_default();
134 Display *x11_display = gdk_x11_display_get_xdisplay(gdk_display);
135
136 if (qemu_egl_init_dpy(x11_display, false, false) < 0) {
137 return;
138 }
139
140 display_opengl = 1;
141}
142