From: Mateusz Majewski Date: Fri, 14 Jun 2024 09:32:39 +0000 (+0200) Subject: progress X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=51540ffa4d8ec77c20b65165271c75c5e96f96c8;p=sdk%2Femulator%2Fqemu.git progress Change-Id: Icb8ce5e586a60b3801bdf3b489b2fff1208fc79d --- diff --git a/hw/vigs/vigs_qt5.cpp b/hw/vigs/vigs_qt5.cpp index e33817a61e..ca8356a1f0 100644 --- a/hw/vigs/vigs_qt5.cpp +++ b/hw/vigs/vigs_qt5.cpp @@ -32,9 +32,10 @@ #include #include #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; diff --git a/tizen/src/ui/Makefile.objs b/tizen/src/ui/Makefile.objs index 8c8feecc8c..479b3f7a91 100644 --- a/tizen/src/ui/Makefile.objs +++ b/tizen/src/ui/Makefile.objs @@ -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 diff --git a/tizen/src/ui/displayglwidget.cpp b/tizen/src/ui/displayglwidget.cpp index 9f9dc89067..3cd6523462 100644 --- a/tizen/src/ui/displayglwidget.cpp +++ b/tizen/src/ui/displayglwidget.cpp @@ -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(); diff --git a/tizen/src/ui/displayglwidget.h b/tizen/src/ui/displayglwidget.h index 26cf7cf96a..0ac1f4be28 100644 --- a/tizen/src/ui/displayglwidget.h +++ b/tizen/src/ui/displayglwidget.h @@ -35,6 +35,7 @@ #include "displaybase.h" #include +#include #include #include @@ -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 diff --git a/tizen/src/ui/mainwindow.cpp b/tizen/src/ui/mainwindow.cpp index d88f61bffe..cafadff8e5 100644 --- a/tizen/src/ui/mainwindow.cpp +++ b/tizen/src/ui/mainwindow.cpp @@ -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; } } diff --git a/tizen/src/ui/mainwindow.h b/tizen/src/ui/mainwindow.h index 84159c7cae..f66237a184 100644 --- a/tizen/src/ui/mainwindow.h +++ b/tizen/src/ui/mainwindow.h @@ -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; diff --git a/tizen/src/ui/qt5.c b/tizen/src/ui/qt5.c index ee84ff5598..9002784377 100644 --- a/tizen/src/ui/qt5.c +++ b/tizen/src/ui/qt5.c @@ -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) { diff --git a/tizen/src/ui/qt5.h b/tizen/src/ui/qt5.h index 226ea3759d..f9dfdbdecb 100644 --- a/tizen/src/ui/qt5.h +++ b/tizen/src/ui/qt5.h @@ -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); diff --git a/tizen/src/ui/qt5_supplement.cpp b/tizen/src/ui/qt5_supplement.cpp index d546ea8065..375f7af086 100644 --- a/tizen/src/ui/qt5_supplement.cpp +++ b/tizen/src/ui/qt5_supplement.cpp @@ -28,10 +28,13 @@ * */ +#include + #include #include #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(); +} diff --git a/tizen/src/ui/qt5_supplement.h b/tizen/src/ui/qt5_supplement.h index dbdcd06be2..75362b48cd 100644 --- a/tizen/src/ui/qt5_supplement.h +++ b/tizen/src/ui/qt5_supplement.h @@ -31,13 +31,27 @@ #ifndef __QT5_INTERNAL_H__ #define __QT5_INTERNAL_H__ +#include + +// 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 diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c index 039645df3e..2e812ba0ca 100644 --- a/ui/sdl2-gl.c +++ b/ui/sdl2-gl.c @@ -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 91c0f08c2c..04eaea037d 100644 --- 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: