bool updated;
ConsoleGLState *gls;
QEMUGLContext ctx;
+ bool is_scanout;
+ uint32_t scanout_fbs[2];
+ bool backing_y_0_top;
+ uint32_t backing_width, backing_height;
#endif
} *qt5_console;
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->is_scanout)
+ return;
+
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;
}
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);
con->surface = new_surface;
con->gen += 1;
+ // TODO: con->is_scanout?
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);
+ if (con->surface && !con->is_scanout && con->updated) {
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_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();
}
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__);
+
+ if (backing_id == 0) {
+ con->is_scanout = false;
+ return;
+ }
+ con->is_scanout = true;
+
+ if (con->ctx)
+ qt5_gl_make_context_current_internal(con->ctx);
+
+ con->backing_y_0_top = backing_y_0_top;
+ con->backing_width = backing_width;
+ con->backing_height = backing_height;
+
+ if (con->scanout_fbs[0] == 0) {
+ // TODO: these leak?
+ glGenFramebuffers(2, con->scanout_fbs);
+ }
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, con->scanout_fbs[0]);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, con->scanout_fbs[1]);
+ glFramebufferTexture2DEXT(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, backing_id, 0);
}
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__);
+ if (con->ctx)
+ qt5_gl_make_context_current_internal(con->ctx);
+
+ glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, con->surface->texture, 0);
+
+ uint32_t y1 = con->backing_y_0_top ? con->backing_height : 0;
+ uint32_t y2 = con->backing_y_0_top ? 0 : con->backing_height;
+ glBlitFramebuffer(0, y1, con->backing_width, y2,
+ 0, 0, surface_width(con->surface), surface_height(con->surface),
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ 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);
+ }
}
static const DisplayChangeListenerOps dcl_ops = {
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);
- 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);
+ qt5_console[i].is_scanout = false;
+ qt5_console[i].scanout_fbs[0] = 0;
}
if (full_screen) {
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);
}