diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2021-02-17 13:36:05 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2021-02-17 13:40:08 -0800 |
commit | e20ef8bc89925bac9499595169de5ef4ff805194 (patch) | |
tree | 554f345a65e5c514aefccb8378dc0d6c056c53c1 /src/gtk_fb.c | |
parent | 68c56c156fcfe4909c65e2eea6ed5d8518c91792 (diff) |
gtk_fb: move window_{new,destroy} to fb_{init,shutdown}
Pages get allocated before fb_acquire, and when creating similar
pages to the underlying window it creates a depenency on the
window being available before acquire. So move the window
create/destroy to the fb init and shutdown, acquire/release now
operate on the image within.
This commit also switches to using:
gdk_window_create_similar_image_surface()
for allocating pages, which may be more performant on backends
like X through the use of shared memory.
Diffstat (limited to 'src/gtk_fb.c')
-rw-r--r-- | src/gtk_fb.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/src/gtk_fb.c b/src/gtk_fb.c index 0d70c0b..9cf0477 100644 --- a/src/gtk_fb.c +++ b/src/gtk_fb.c @@ -38,7 +38,9 @@ struct gtk_fb_page_t { }; -/* this doesn't really do anything significant on gtk */ +/* parse settings and get the output window realized before + * attempting to create any pages "similar" to it. + */ static int gtk_fb_init(const settings_t *settings, void **res_context) { const char *fullscreen; @@ -67,6 +69,9 @@ static int gtk_fb_init(const settings_t *settings, void **res_context) if (size) /* TODO: errors */ sscanf(size, "%u%*[xX]%u", &c->width, &c->height); + c->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_realize(c->window); + *res_context = c; return 0; @@ -77,6 +82,7 @@ static void gtk_fb_shutdown(fb_t *fb, void *context) { gtk_fb_t *c = context; + gtk_widget_destroy(c->window); free(c); } @@ -113,7 +119,6 @@ static int gtk_fb_acquire(fb_t *fb, void *context, void *page) gtk_fb_t *c = context; gtk_fb_page_t *p = page; - c->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); c->image = gtk_image_new_from_surface(p->surface); g_signal_connect(c->image, "draw", G_CALLBACK(draw_cb), fb); gtk_widget_add_tick_callback(c->image, queue_draw_cb, c, NULL); @@ -128,7 +133,7 @@ static void gtk_fb_release(fb_t *fb, void *context) { gtk_fb_t *c = context; - gtk_widget_destroy(c->window); + gtk_widget_destroy(c->image); } @@ -136,20 +141,17 @@ static void * gtk_fb_page_alloc(fb_t *fb, void *context, fb_page_t *res_page) { gtk_fb_t *c = context; gtk_fb_page_t *p; + GdkWindow *gdk_window; p = calloc(1, sizeof(gtk_fb_page_t)); if (!p) return NULL; - /* XXX: note this is a plain in-memory surface that will always work everywhere, - * but that generality prevents potential optimizations. - * With some extra effort, on backends like X, an xshm surface could be - * created instead, for a potential performance boost by having the - * surface contents accessible server-side where accelerated copies may - * be used, while also accessible client-side where rototiller draws into. - * TODO if better X performance is desired. + /* by using gdk_window_create_similar_image_surface(), we enable + * potential optimizations like XSHM use on the xlib cairo backend. */ - p->surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, c->width, c->height); + gdk_window = gtk_widget_get_window(c->window); + p->surface = gdk_window_create_similar_image_surface(gdk_window, CAIRO_FORMAT_RGB24, c->width, c->height, 0); res_page->fragment.buf = (uint32_t *)cairo_image_surface_get_data(p->surface); res_page->fragment.width = c->width; |