progress
authorMateusz Majewski <m.majewski2@samsung.com>
Fri, 14 Jun 2024 09:32:39 +0000 (11:32 +0200)
committerMateusz Majewski <m.majewski2@samsung.com>
Tue, 18 Jun 2024 14:14:18 +0000 (16:14 +0200)
Change-Id: Icb8ce5e586a60b3801bdf3b489b2fff1208fc79d

12 files changed:
hw/vigs/vigs_qt5.cpp
tizen/src/ui/Makefile.objs
tizen/src/ui/displayglwidget.cpp
tizen/src/ui/displayglwidget.h
tizen/src/ui/mainwindow.cpp
tizen/src/ui/mainwindow.h
tizen/src/ui/qt5.c
tizen/src/ui/qt5.h
tizen/src/ui/qt5_supplement.cpp
tizen/src/ui/qt5_supplement.h
ui/sdl2-gl.c
vl.c

index e33817a61e9a63343a32071aca0e1657166a48b5..ca8356a1f0c5d1b41ca83808e4c3671275db9b65 100644 (file)
 #include <QOpenGLContext>
 #include <qpa/qplatformnativeinterface.h>
 #include "config-host.h"
+#include "qt5_supplement.h"
 #include "vigs_qt5.h"
 
-extern bool qt5IsOnscreen;
+extern maru_display_type display_type;
 extern QApplication *qt5App;
 extern QOpenGLContext *qt5GLContext;
 
@@ -47,7 +48,7 @@ extern void qt5_update_texture(void *dpy_item);
 
 bool vigs_qt5_onscreen_enabled(void)
 {
-    if (qt5App != NULL && qt5IsOnscreen) {
+    if (qt5App != NULL && display_type == MARU_DISPLAY_TYPE_ONSCREEN) {
         return true;
     }
     return  false;
index 8c8feecc8c24cefc99961eb2b22645bb6084902c..479b3f7a917ee49ec3faee3cc84ae83bc3461b1d 100644 (file)
@@ -35,6 +35,8 @@ $(obj)/moc_displayglwidget.cpp: $(obj)/displayglwidget.h
        moc $< -o $@
 $(obj)/moc_displayswwidget.cpp: $(obj)/displayswwidget.h
        moc $< -o $@
+$(obj)/moc_displayqemuglwidget.cpp: $(obj)/displayqemuglwidget.h
+       moc $< -o $@
 $(obj)/moc_mainwindow.cpp: $(obj)/mainwindow.h
        moc $< -o $@
 $(obj)/moc_skinkeyitem.cpp: $(obj)/skinkeyitem.h
index 9f9dc890678d3f310cd17ff6436abaacd723e375..3cd6523462136780e83cfdec3c82c8152ba6d296 100644 (file)
@@ -225,6 +225,8 @@ DisplayGLWidget::DisplayGLWidget(QWidget *parent,
     mFuncs = NULL;
     mVAO = NULL;
     mVBO = NULL;
+
+    offscreen = NULL;
 }
 
 void DisplayGLWidget::changedTexture(struct dpy_item *item)
@@ -242,6 +244,48 @@ void DisplayGLWidget::changedTexture(struct dpy_item *item)
     this->update();
 }
 
+QOpenGLContext *DisplayGLWidget::createSharedContext(int major, int minor)
+{
+    auto glob = context();
+    if (!glob)
+        return nullptr;
+
+    QSurfaceFormat fmt;
+    fmt.setVersion(major, minor);
+
+    if (!offscreen) {
+        offscreen = new(std::nothrow) QOffscreenSurface;
+        if (!offscreen)
+            return nullptr;
+
+        offscreen->create();
+
+        if (!offscreen->isValid()) {
+            offscreen->destroy();
+            offscreen = nullptr;
+            return nullptr;
+        }
+    }
+
+    auto ctx = new(std::nothrow) QOpenGLContext;
+    if (!ctx)
+        return nullptr;
+
+    ctx->setFormat(fmt);
+    ctx->setShareContext(glob);
+
+    if (!ctx->create())
+        return nullptr;
+    
+    return ctx;
+}
+
+bool DisplayGLWidget::activateSharedContext(QOpenGLContext *ctx)
+{
+    // TODO: Context loss???
+    return ctx->makeCurrent(offscreen);
+}
+
 float DisplayGLWidget::getBrightness()
 {
     if (display_off) {
@@ -478,6 +522,7 @@ void DisplayGLWidget::paintGL()
     textureListMutex.unlock();
 
     if (current) {
+        fprintf(stderr, "will show %d\n", current->tex);
         drawQuad(current->tex, false);
     }
 
@@ -576,6 +621,10 @@ DisplayGLWidget::~DisplayGLWidget()
     if (maskTexture) {
         mFuncs->glDeleteTextures(1, &maskTexture);
     }
+    if (offscreen) {
+        offscreen->destroy();
+        delete offscreen;
+    }
     mVAO->destroy();
     mVBO->destroy();
     texProgram->removeAllShaders();
index 26cf7cf96a779b96dfa2e55647b6447d37b1ef87..0ac1f4be28aa76f8e2c2feadd0400a6f5ede6bf4 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "displaybase.h"
 #include <QMutex>
+#include <QOffscreenSurface>
 #include <QOpenGLWidget>
 #include <QMatrix4x4>
 
@@ -72,6 +73,9 @@ public:
 
     void changedTexture(struct dpy_item *tex);
 
+    QOpenGLContext *createSharedContext(int major, int minor);
+    bool activateSharedContext(QOpenGLContext *ctx);
+
 protected:
     void initializeGL();
     void paintGL();
@@ -113,6 +117,7 @@ private:
     QOpenGLShaderProgram *texProgram;
     QOpenGLShaderProgram *scaleProgram;
 
+    QOffscreenSurface *offscreen;
 };
 
 #endif // DISPLAYGLWIDGET_H
index d88f61bffe86fef992d3a179ceee8c802aa9e3d7..cafadff8e58104179946284eddb2a84d9220d87a 100644 (file)
@@ -48,7 +48,7 @@ void qt5_graphic_hw_update(void);
 void qemu_system_graceful_shutdown_request(unsigned int sec);
 }
 
-MainWindow::MainWindow(UiInformation *uiInfo, bool useGL, QWidget *parent) :
+MainWindow::MainWindow(UiInformation *uiInfo, maru_display_type display_type, QWidget *parent) :
     QWidget(parent)
 {
     /* initialize */
@@ -105,7 +105,7 @@ MainWindow::MainWindow(UiInformation *uiInfo, bool useGL, QWidget *parent) :
 
     /* display */
     updateDisplayTransform();
-    createDisplay(useGL);
+    createDisplay(display_type);
 
     /* set HW Key shortcut */
     keyboardShortcut = new KeyboardShortcut(this);
@@ -118,19 +118,26 @@ MainWindow::MainWindow(UiInformation *uiInfo, bool useGL, QWidget *parent) :
         SLOT(slotContextMenu(const QPoint&)));
 }
 
-void MainWindow::createDisplay(bool useGL)
+void MainWindow::createDisplay(maru_display_type display_type)
 {
     qDebug("create a display");
+    DisplaySWWidget *widget;
 
-    if (useGL) { /* on-screen rendering */
+    switch (display_type) {
+    case MARU_DISPLAY_TYPE_ONSCREEN:
+#ifdef CONFIG_OPENGL
+    case MARU_DISPLAY_TYPE_GL:
+#endif
         this->display = new DisplayGLWidget(this,
             uiInfo->getMainFormDpyType(), uiInfo->getResolution(), getUiState()->getScaleFactor());
-    } else { /* off-screen rendering */
-        DisplaySWWidget *widget = new DisplaySWWidget(this,
+        break;
+    case MARU_DISPLAY_TYPE_OFFSCREEN:
+        widget = new DisplaySWWidget(this,
             uiInfo->getMainFormDpyType(), uiInfo->getResolution(), getUiState()->getScaleFactor());
 
         this->screenWidget = widget;
         this->display = widget;
+        break;
     }
 }
 
index 84159c7caecb568e56a6f6e113dc6734a516e53b..f66237a184c55b86ab3bde0d7553e0b6813b62d9 100644 (file)
@@ -39,6 +39,7 @@
 #include "menu/contextmenu.h"
 #include "mainview.h"
 #include "displaybase.h"
+#include "qt5_supplement.h"
 #include "rotaryview.h"
 #include "uiinformation.h"
 #include "controller/dockingcontroller.h"
@@ -54,7 +55,7 @@ public:
     bool isMovingMode;
 
     explicit MainWindow(UiInformation *uiInfo,
-                        bool useGL,
+                        maru_display_type display_type,
                         QWidget *parent = 0);
     ~MainWindow();
 
@@ -103,7 +104,7 @@ protected:
     QLabel *screenWidget;
 
 private:
-    void createDisplay(bool useGL);
+    void createDisplay(maru_display_type display_type);
     RotaryView *createRotary();
 
     UiInformation *uiInfo;
index ee84ff55983a69b6688037febad0b291e8ee84a9..90027843778addf7b42f52902d41f652fcf27dc8 100644 (file)
@@ -54,6 +54,13 @@ static struct qt5_state {
     DisplaySurface *surface;
 
     int idx;
+
+#ifdef CONFIG_OPENGL
+    uint64_t gen;
+    bool updated;
+    ConsoleGLState *gls;
+    QEMUGLContext ctx;
+#endif
 } *qt5_console;
 
 void qt5_graphic_hw_invalidate(void)
@@ -110,6 +117,67 @@ static void qt5_refresh(DisplayChangeListener *dcl)
     qt5_refresh_internal();
 }
 
+static void qt5_gl_update(DisplayChangeListener *dcl,
+                       int x, int y, int w, int h)
+{
+    struct qt5_state *con = container_of(dcl, struct qt5_state, dcl);
+    fprintf(stderr, "in %s %s:%d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__);
+    if (con->ctx)
+        qt5_gl_make_context_current_internal(con->ctx);
+    surface_gl_update_texture(con->gls, con->surface, x, y, w, h);
+    fprintf(stderr, "rendered %d\n", con->surface->texture);
+    con->updated = true;
+}
+
+static void qt5_gl_switch(DisplayChangeListener *dcl,
+                       DisplaySurface *new_surface)
+{
+    struct qt5_state *con = container_of(dcl, struct qt5_state, dcl);
+    fprintf(stderr, "in %s %s:%d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__);
+    if (con->ctx)
+        qt5_gl_make_context_current_internal(con->ctx);
+
+    surface_gl_destroy_texture(NULL, con->surface);
+
+    if (new_surface && !con->gls) {
+        con->gls = console_gl_init_context();
+    } else if (!new_surface && con->gls) {
+        console_gl_fini_context(con->gls);
+        con->gls = NULL;
+        return;
+    } else if (con->surface &&
+            (surface_width(con->surface) != surface_width(new_surface) ||
+             surface_height(con->surface) != surface_height(new_surface))) {
+        // TODO: we should adjust display size.
+        // We should warn to user since we can not adjust display size now.
+        LOG_WARNING("display size is changed.\n");
+    }
+
+    con->surface = new_surface;
+    con->gen += 1;
+    surface_gl_create_texture(con->gls, con->surface);
+    fprintf(stderr, "created %d\n", con->surface->texture);
+}
+
+static void qt5_gl_refresh(DisplayChangeListener *dcl)
+{
+    struct qt5_state *con = container_of(dcl, struct qt5_state, dcl);
+    fprintf(stderr, "in %s %s:%d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__);
+    if (con->ctx)
+        qt5_gl_make_context_current_internal(con->ctx);
+
+    graphic_hw_update(dcl->con);
+    if (con->surface && con->updated) {
+        fprintf(stderr, "sending %d\n", con->surface->texture);
+        con->surface->texture = qt5_gl_refresh_internal(con->surface->texture, surface_width(con->surface), surface_height(con->surface), con->gen);
+        if (con->surface->texture == 0) {
+            surface_gl_create_texture(con->gls, con->surface);
+            fprintf(stderr, "created %d\n", con->surface->texture);
+        }
+        con->updated = false;
+    }
+}
+
 static void qt5_mouse_warp(DisplayChangeListener *dcl,
                            int x, int y, int on)
 {
@@ -120,6 +188,50 @@ static void qt5_mouse_define(DisplayChangeListener *dcl,
 {
 }
 
+static QEMUGLContext qt5_gl_create_context(DisplayChangeListener *dcl,
+                                     QEMUGLParams *params)
+{
+    return qt5_gl_create_context_internal(params->major_ver, params->minor_ver);
+}
+
+static void qt5_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
+{
+    fprintf(stderr, "in %s %s:%d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__);
+    qt5_gl_destroy_context_internal(ctx);
+}
+
+static int qt5_gl_make_context_current(DisplayChangeListener *dcl,
+                                 QEMUGLContext ctx)
+{
+    fprintf(stderr, "in %s %s:%d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__);
+    qt5_gl_make_context_current_internal(ctx);
+}
+
+static QEMUGLContext qt5_gl_get_current_context(DisplayChangeListener *dcl)
+{
+    fprintf(stderr, "in %s %s:%d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__);
+    return qt5_gl_get_current_context_internal();
+}
+
+static void qt5_gl_scanout(DisplayChangeListener *dcl,
+                     uint32_t backing_id, bool backing_y_0_top,
+                     uint32_t backing_width, uint32_t backing_height,
+                     uint32_t x, uint32_t y,
+                     uint32_t w, uint32_t h)
+{
+    struct qt5_state *con = container_of(dcl, struct qt5_state, dcl);
+    fprintf(stderr, "in %s %s:%d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__);
+
+}
+
+static void qt5_gl_scanout_flush(DisplayChangeListener *dcl,
+                           uint32_t x, uint32_t y, uint32_t w, uint32_t h)
+{
+    struct qt5_state *con = container_of(dcl, struct qt5_state, dcl);
+    fprintf(stderr, "in %s %s:%d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__);
+
+}
+
 static const DisplayChangeListenerOps dcl_ops = {
     .dpy_name          = "qt5",
     .dpy_gfx_update    = qt5_update,
@@ -129,10 +241,27 @@ static const DisplayChangeListenerOps dcl_ops = {
     .dpy_cursor_define = qt5_mouse_define,
 };
 
-void maru_early_qt5_display_init(bool isOnscreen)
+static const DisplayChangeListenerOps dcl_gl_ops = {
+    .dpy_name             = "qt5-gl",
+    .dpy_gfx_update       = qt5_gl_update,
+    .dpy_gfx_switch       = qt5_gl_switch,
+    .dpy_gfx_check_format = console_gl_check_format,
+    .dpy_refresh          = qt5_gl_refresh,
+    .dpy_mouse_set        = qt5_mouse_warp,
+    .dpy_cursor_define    = qt5_mouse_define,
+
+    .dpy_gl_ctx_create       = qt5_gl_create_context,
+    .dpy_gl_ctx_destroy      = qt5_gl_destroy_context,
+    .dpy_gl_ctx_make_current = qt5_gl_make_context_current,
+    .dpy_gl_ctx_get_current  = qt5_gl_get_current_context,
+    .dpy_gl_scanout          = qt5_gl_scanout,
+    .dpy_gl_update           = qt5_gl_scanout_flush,
+};
+
+void maru_early_qt5_display_init(enum maru_display_type display_type)
 {
 #ifdef CONFIG_DARWIN
-    ns_run_in_event_loop_with_bool(&qt5_early_prepare, isOnscreen);
+    ns_run_in_event_loop_with_bool(&qt5_early_prepare, display_type == MARU_DISPLAY_TYPE_OFFSCREEN);
 
     /* set emulator icon */
     const int path_len = strlen(get_bin_path()) +
@@ -146,13 +275,21 @@ void maru_early_qt5_display_init(bool isOnscreen)
     set_application_icon(icon_path);
     g_free(icon_path);
 #else
-    qt5_early_prepare(isOnscreen);
+    qt5_early_prepare(display_type);
 #endif
 
-    if (isOnscreen) {
+    switch (display_type) {
+    case MARU_DISPLAY_TYPE_ONSCREEN:
         LOG_INFO("Display Type: QT5 Onscreen\n");
-    } else {
+        break;
+    case MARU_DISPLAY_TYPE_OFFSCREEN:
         LOG_INFO("Display Type: QT5 Offscreen\n");
+        break;
+#ifdef CONFIG_OPENGL
+    case MARU_DISPLAY_TYPE_GL:
+        LOG_INFO("Display Type: QT5 GL\n");
+        break;
+#endif
     }
 }
 
@@ -204,10 +341,15 @@ void maru_qt5_display_init(DisplayState *ds, int full_screen)
     qt5_console = g_new0(struct qt5_state, qt5_num_outputs);
     for (i = 0; i < qt5_num_outputs; i++) {
         QemuConsole *con = qemu_console_lookup_by_index(i);
-        qt5_console[i].dcl.ops = &dcl_ops;
+        fprintf(stderr, "opengl is %d\n", display_opengl);
+        qt5_console[i].dcl.ops = display_opengl ? &dcl_gl_ops : &dcl_ops;
         qt5_console[i].dcl.con = con;
         register_displaychangelistener(&qt5_console[i].dcl);
         qt5_console[i].idx = i;
+        qt5_console[i].gen = 0;
+        qt5_console[i].updated = false;
+        qt5_console[i].gls = NULL;
+        qt5_console[i].ctx = qt5_gl_create_context_internal(3, 3);
     }
 
     if (full_screen) {
index 226ea3759d86d60d8f2518299046144e82b379ee..f9dfdbdecb0c2c4220019704edd6a1827730ac02 100644 (file)
@@ -33,8 +33,9 @@
 
 #include "qemu/osdep.h"
 #include "sysemu/sysemu.h"
+#include "qt5_supplement.h"
 
-void maru_early_qt5_display_init(bool isOnscreen);
+void maru_early_qt5_display_init(enum maru_display_type);
 void maru_qt5_display_init(DisplayState *ds, int full_screen);
 void maru_qt5_display_fini(void);
 
index d546ea8065fb998d747490c9730dedfc28871694..375f7af086ba02d36585ef6e672514b086a7f150 100644 (file)
  *
  */
 
+#include <memory>
+
 #include <QApplication>
 #include <QOpenGLContext>
 
 #include "qt5_supplement.h"
+#include "displayglwidget.h"
 #include "propertykeyword.h"
 #include "mainwindow.h"
 #include "layout/hardwarekey.h"
@@ -40,6 +43,9 @@
 #include "resource/ui_strings.h"
 #include "displaybase.h"
 
+// TODO: Figure out the compilation
+extern int display_opengl;
+
 #include "util/new_debug_ch.h"
 // XXX: all modules in ui/* are controlled by channel name "qt5_ui"
 DECLARE_DEBUG_CHANNEL(qt5_ui);
@@ -53,7 +59,7 @@ bool is_display_off(void);
 }
 
 //using namespace std;
-bool qt5IsOnscreen;
+maru_display_type display_type;
 QApplication *qt5App = NULL;
 QOpenGLContext *qt5GLContext;
 bool isForceLegacy;
@@ -70,6 +76,10 @@ static void (*captureRequestHandler)(void *);
 static MainWindow *mainwindow;
 static UiInformation *uiInfo;
 
+#define DPY_ITEM_NO 5
+static dpy_item dpy_item_pool[DPY_ITEM_NO];
+static uint64_t dpy_item_gen[DPY_ITEM_NO];
+
 class ConFile {
 public:
     QFile *formFile;
@@ -326,7 +336,7 @@ static void qt5_gui_init(void)
     /* GUI */
     qDebug("start!");
 
-    mainwindow = new MainWindow(uiInfo, qt5IsOnscreen);
+    mainwindow = new MainWindow(uiInfo, display_type);
     mainwindow->setCaptureRequestHandler(captureRequestListener, captureRequestHandler);
 
     /* position */
@@ -440,13 +450,16 @@ void qt5_set_force_legacy(bool isLegacy)
     isForceLegacy = isLegacy;
 }
 
-void qt5_early_prepare(bool isOnscreen)
+void qt5_early_prepare(enum maru_display_type _display_type)
 {
-    qt5IsOnscreen = isOnscreen;
+    display_type = _display_type;
+#ifdef CONFIG_OPENGL
+    display_opengl = display_type == MARU_DISPLAY_TYPE_GL;
+#endif
 
     Q_INIT_RESOURCE(resource);
 
-    if (qt5IsOnscreen) {
+    if (display_type == MARU_DISPLAY_TYPE_ONSCREEN) {
         QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
         QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
 
@@ -481,7 +494,7 @@ void qt5_early_prepare(bool isOnscreen)
     eventFilter = new EventFilter();
     qt5App->installNativeEventFilter(eventFilter);
 #endif
-    if (qt5IsOnscreen) {
+    if (display_type == MARU_DISPLAY_TYPE_ONSCREEN) {
         qt5GLContext = QOpenGLContext::globalShareContext();
         qDebug("* Qt global share context: OpenGL %d.%d(Profile:%d)",
                qt5GLContext->format().majorVersion(),
@@ -600,3 +613,73 @@ void qt5_update_texture(void *dpy_item)
         mainwindow->updateTexture(dpy_item);
     }
 }
+
+uint32_t qt5_gl_refresh_internal(uint32_t tex, uint32_t width, uint32_t height, uint64_t gen)
+{
+    uint32_t ret = tex;
+
+    if (mainwindow) {
+        int item_id = 0;
+        while (true)
+        {
+            auto item = &dpy_item_pool[item_id];
+            qemu_mutex_lock(&item->mutex);
+            bool ok = dpy_item_gen[item_id] == 0 || item->available;
+            if (ok) {
+                if (dpy_item_gen[item_id] == gen) {
+                    ret = item->tex;
+                } else {
+                    // TODO: we will leak a texture soon!
+                    dpy_item_gen[item_id] = gen;
+                    ret = 0;
+                }
+                item->tex = tex;
+                item->width = width;
+                item->height = height;
+                item->available = false;
+            }
+            qemu_mutex_unlock(&item->mutex);
+            if (ok) {
+                mainwindow->updateTexture(item);
+                break;
+            }
+            item_id++;
+            if (item_id == DPY_ITEM_NO) {
+                break;
+            }
+        }
+
+    }
+    
+    return ret;
+}
+
+void *qt5_gl_create_context_internal(int major, int minor)
+{
+    if (mainwindow) {
+        return ((DisplayGLWidget *)mainwindow->getDisplay())->createSharedContext(major, minor);
+    } else {
+        return nullptr;
+    }
+}
+
+void qt5_gl_destroy_context_internal(void *_ctx)
+{
+    auto ctx = (QOpenGLContext *)_ctx;
+    delete ctx;
+}
+
+int qt5_gl_make_context_current_internal(void *_ctx)
+{
+    auto ctx = (QOpenGLContext *)_ctx;
+    if (mainwindow) {
+        return ((DisplayGLWidget *)mainwindow->getDisplay())->activateSharedContext(ctx) ? 0 : -1;
+    } else {
+        return -1;
+    }
+}
+
+void *qt5_gl_get_current_context_internal()
+{
+    return QOpenGLContext::currentContext();
+}
index dbdcd06be23a5cf7508b1deb091b7f1d1b0f287e..75362b48cd7de5c5fe6a3580a24f7260bb72f800 100644 (file)
 #ifndef __QT5_INTERNAL_H__
 #define __QT5_INTERNAL_H__
 
+#include <stdint.h>
+
+// TODO: This probably should not be included directly.
+#include "config-host.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+enum maru_display_type {
+    MARU_DISPLAY_TYPE_ONSCREEN,
+    MARU_DISPLAY_TYPE_OFFSCREEN,
+#ifdef CONFIG_OPENGL
+    MARU_DISPLAY_TYPE_GL,
+#endif
+};
+
 void qt5_graphic_hw_invalidate(void);
 void qt5_graphic_hw_update(void);
 int qt5_graphic_hw_display(void);
-void qt5_early_prepare(bool isOnscreen);
+void qt5_early_prepare(enum maru_display_type);
 void qt5_prepare(void);
 void qt5_destroy(void);
 
@@ -48,6 +62,13 @@ void qt5_refresh_internal(void);
 const char* qt5_get_version(void);
 
 void qt5_set_force_legacy(bool isLegacy);
+
+uint32_t qt5_gl_refresh_internal(uint32_t tex, uint32_t width, uint32_t height, uint64_t gen);
+void *qt5_gl_create_context_internal(int major, int minor);
+void qt5_gl_destroy_context_internal(void *);
+int qt5_gl_make_context_current_internal(void *_ctx);
+void *qt5_gl_get_current_context_internal();
+
 #ifdef __cplusplus
 }
 #endif
index 039645df3e6e44dd2647f22dd0993f02944bf5e2..2e812ba0cac11c20c30a39bc2d12e249e7717132 100644 (file)
@@ -191,59 +191,59 @@ void sdl2_gl_scanout(DisplayChangeListener *dcl,
                      uint32_t w, uint32_t h)
 {
     struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
-
-    assert(scon->opengl);
-    scon->x = x;
-    scon->y = y;
-    scon->w = w;
-    scon->h = h;
-    scon->tex_id = backing_id;
-    scon->y0_top = backing_y_0_top;
-
-    SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
-
-    if (scon->tex_id == 0 || scon->w == 0 || scon->h == 0) {
-        sdl2_set_scanout_mode(scon, false);
-        return;
-    }
-
-    sdl2_set_scanout_mode(scon, true);
-    if (!scon->fbo_id) {
-        glGenFramebuffers(1, &scon->fbo_id);
-    }
-
-    glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
-    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
-                              GL_TEXTURE_2D, scon->tex_id, 0);
+    //
+    // assert(scon->opengl);
+    // scon->x = x;
+    // scon->y = y;
+    // scon->w = w;
+    // scon->h = h;
+    // scon->tex_id = backing_id;
+    // scon->y0_top = backing_y_0_top;
+    //
+    // SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
+    //
+    // if (scon->tex_id == 0 || scon->w == 0 || scon->h == 0) {
+    //     sdl2_set_scanout_mode(scon, false);
+    //     return;
+    // }
+    //
+    // sdl2_set_scanout_mode(scon, true);
+    // if (!scon->fbo_id) {
+    //     glGenFramebuffers(1, &scon->fbo_id);
+    // }
+    //
+    // glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
+    // glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+    //                           GL_TEXTURE_2D, scon->tex_id, 0);
 }
 
 void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
                            uint32_t x, uint32_t y, uint32_t w, uint32_t h)
 {
     struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
-    int ww, wh, y1, y2;
-
-    assert(scon->opengl);
-    if (!scon->scanout_mode) {
-        return;
-    }
-    if (!scon->fbo_id) {
-        return;
-    }
-
-    SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
-
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, scon->fbo_id);
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-
-    SDL_GetWindowSize(scon->real_window, &ww, &wh);
-    glViewport(0, 0, ww, wh);
-    y1 = scon->y0_top ? 0 : scon->h;
-    y2 = scon->y0_top ? scon->h : 0;
-    glBlitFramebuffer(0, y1, scon->w, y2,
-                      0, 0, ww, wh,
-                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
-    glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
-
-    SDL_GL_SwapWindow(scon->real_window);
+    // int ww, wh, y1, y2;
+    //
+    // assert(scon->opengl);
+    // if (!scon->scanout_mode) {
+    //     return;
+    // }
+    // if (!scon->fbo_id) {
+    //     return;
+    // }
+    //
+    // SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
+    //
+    // glBindFramebuffer(GL_READ_FRAMEBUFFER, scon->fbo_id);
+    // glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+    //
+    // SDL_GetWindowSize(scon->real_window, &ww, &wh);
+    // glViewport(0, 0, ww, wh);
+    // y1 = scon->y0_top ? 0 : scon->h;
+    // y2 = scon->y0_top ? scon->h : 0;
+    // glBlitFramebuffer(0, y1, scon->w, y2,
+    //                   0, 0, ww, wh,
+    //                   GL_COLOR_BUFFER_BIT, GL_NEAREST);
+    // glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
+    //
+    // SDL_GL_SwapWindow(scon->real_window);
 }
diff --git a/vl.c b/vl.c
index 91c0f08c2c1dabc7a1a0038bc2170ac7a4d053ec..04eaea037d51db8a0adebbcd74a5176ded071360 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -2157,6 +2157,9 @@ typedef enum DisplayType {
 # ifdef CONFIG_QT
     DT_MARU_QT_ONSCREEN,
     DT_MARU_QT_OFFSCREEN,
+#  ifdef CONFIG_OPENGL
+    DT_MARU_QT_GL,
+#  endif
 # endif
 #endif
     DT_NONE,
@@ -2297,6 +2300,10 @@ static DisplayType select_display(const char *p)
                     display = DT_MARU_QT_ONSCREEN;
                 } else if (strstart(opts, "offscreen", &nextopt)) {
                     display = DT_MARU_QT_OFFSCREEN;
+#  ifdef CONFIG_OPENGL
+                } else if (strstart(opts, "gl", &nextopt)) {
+                    display = DT_MARU_QT_GL;
+#  endif
                 } else {
                     goto invalid_maru_qt_args;
                 }
@@ -4489,9 +4496,13 @@ int main(int argc, char **argv, char **envp)
 #ifdef CONFIG_MARU
 # if defined(CONFIG_QT)
     if (display_type == DT_MARU_QT_ONSCREEN) {
-        maru_early_qt5_display_init(true);
+        maru_early_qt5_display_init(MARU_DISPLAY_TYPE_ONSCREEN);
     } else if (display_type == DT_MARU_QT_OFFSCREEN) {
-        maru_early_qt5_display_init(false);
+        maru_early_qt5_display_init(MARU_DISPLAY_TYPE_OFFSCREEN);
+#  ifdef CONFIG_OPENGL
+    } else if (display_type == DT_MARU_QT_GL) {
+        maru_early_qt5_display_init(MARU_DISPLAY_TYPE_GL);
+#  endif
     }
 # endif
 #endif
@@ -4841,6 +4852,9 @@ int main(int argc, char **argv, char **envp)
  #if defined(CONFIG_QT)
     case DT_MARU_QT_ONSCREEN:
     case DT_MARU_QT_OFFSCREEN:
+  #if defined(CONFIG_OPENGL)
+    case DT_MARU_QT_GL:
+  #endif
         if (!is_maru_machine(machine_class)) {
             error_report("maru_qt can not work"
                     " without maru machine");
@@ -4938,6 +4952,9 @@ int main(int argc, char **argv, char **envp)
     switch (display_type) {
     case DT_MARU_QT_ONSCREEN:
     case DT_MARU_QT_OFFSCREEN:
+# ifdef CONFIG_OPENGL
+    case DT_MARU_QT_GL:
+# endif
         maru_qt5_display_fini();
         break;
     default: