static EGLBoolean dri2_x11_get_sync_values(_EGLDisplay *display, _EGLSurface *surface, EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(display); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface); xcb_dri2_get_msc_cookie_t cookie; xcb_dri2_get_msc_reply_t *reply; cookie = xcb_dri2_get_msc(dri2_dpy->conn, dri2_surf->drawable); reply = xcb_dri2_get_msc_reply(dri2_dpy->conn, cookie, NULL); if (!reply) { _eglError(EGL_BAD_ACCESS, __func__); return EGL_FALSE; } *ust = ((EGLuint64KHR) reply->ust_hi << 32) | reply->ust_lo; *msc = ((EGLuint64KHR) reply->msc_hi << 32) | reply->msc_lo; *sbc = ((EGLuint64KHR) reply->sbc_hi << 32) | reply->sbc_lo; free(reply); return EGL_TRUE; }
static EGLBoolean droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); _EGLContext *ctx; if (dri2_surf->base.Type != EGL_WINDOW_BIT) return EGL_TRUE; if (dri2_drv->glFlush) { ctx = _eglGetCurrentContext(); if (ctx && ctx->DrawSurface == &dri2_surf->base) dri2_drv->glFlush(); } (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); if (dri2_surf->buffer) droid_window_enqueue_buffer(dri2_surf); (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); return EGL_TRUE; }
static EGLBoolean dri2_drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); int i; if (dri2_dpy->swrast) { (*dri2_dpy->core->swapBuffers)(dri2_surf->dri_drawable); } else { if (dri2_surf->base.Type == EGL_WINDOW_BIT) { if (dri2_surf->current) _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers"); for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) if (dri2_surf->color_buffers[i].age > 0) dri2_surf->color_buffers[i].age++; dri2_surf->current = dri2_surf->back; dri2_surf->current->age = 1; dri2_surf->back = NULL; } (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); } return EGL_TRUE; }
static EGLBoolean dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); int i; if (!_eglPutSurface(surf)) return EGL_TRUE; (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { if (dri2_surf->color_buffers[i].bo) gbm_bo_destroy(dri2_surf->color_buffers[i].bo); } for (i = 0; i < __DRI_BUFFER_COUNT; i++) { if (dri2_surf->dri_buffers[i]) dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, dri2_surf->dri_buffers[i]); } free(surf); return EGL_TRUE; }
static EGLBoolean droid_query_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint *value) { struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); switch (attribute) { case EGL_WIDTH: if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->window) { dri2_surf->window->query(dri2_surf->window, NATIVE_WINDOW_DEFAULT_WIDTH, value); return EGL_TRUE; } break; case EGL_HEIGHT: if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->window) { dri2_surf->window->query(dri2_surf->window, NATIVE_WINDOW_DEFAULT_HEIGHT, value); return EGL_TRUE; } break; default: break; } return _eglQuerySurface(drv, dpy, surf, attribute, value); }
static EGLBoolean dri2_copy_region(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, xcb_xfixes_region_t region) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); enum xcb_dri2_attachment_t render_attachment; xcb_dri2_copy_region_cookie_t cookie; /* No-op for a pixmap or pbuffer surface */ if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT) return EGL_TRUE; if (dri2_dpy->flush) (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); if (dri2_surf->have_fake_front) render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT; else render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT; cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn, dri2_surf->drawable, region, XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT, render_attachment); free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL)); return EGL_TRUE; }
static EGLBoolean dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); (void) drv; if (!_eglPutSurface(surf)) return EGL_TRUE; (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); if (dri2_dpy->dri2) { xcb_dri2_destroy_drawable (dri2_dpy->conn, dri2_surf->drawable); } else { assert(dri2_dpy->swrast); swrastDestroyDrawable(dri2_dpy, dri2_surf); } if (surf->Type == EGL_PBUFFER_BIT) xcb_free_pixmap (dri2_dpy->conn, dri2_surf->drawable); free(surf); return EGL_TRUE; }
/** * Called via eglDestroySurface(), drv->API.DestroySurface(). */ static EGLBoolean dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); int i; (void) drv; if (!_eglPutSurface(surf)) return EGL_TRUE; (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); for (i = 0; i < WL_BUFFER_COUNT; ++i) if (dri2_surf->wl_drm_buffer[i]) wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]); for (i = 0; i < __DRI_BUFFER_COUNT; ++i) if (dri2_surf->dri_buffers[i] && !(i == __DRI_BUFFER_FRONT_LEFT && dri2_surf->base.Type == EGL_PIXMAP_BIT)) dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, dri2_surf->dri_buffers[i]); if (dri2_surf->third_buffer) { dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, dri2_surf->third_buffer); } free(surf); return EGL_TRUE; }
static EGLBoolean dri2_swap_buffers_region(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, EGLint numRects, const EGLint *rects) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); EGLBoolean ret; xcb_xfixes_region_t region; xcb_rectangle_t rectangles[16]; int i; if (numRects > (int)ARRAY_SIZE(rectangles)) return dri2_copy_region(drv, disp, draw, dri2_surf->region); for (i = 0; i < numRects; i++) { rectangles[i].x = rects[i * 4]; rectangles[i].y = dri2_surf->base.Height - rects[i * 4 + 1] - rects[i * 4 + 3]; rectangles[i].width = rects[i * 4 + 2]; rectangles[i].height = rects[i * 4 + 3]; } region = xcb_generate_id(dri2_dpy->conn); xcb_xfixes_create_region(dri2_dpy->conn, region, numRects, rectangles); ret = dri2_copy_region(drv, disp, draw, region); xcb_xfixes_destroy_region(dri2_dpy->conn, region); return ret; }
static EGLBoolean dri2_copy_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLNativePixmapType native_target) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); xcb_gcontext_t gc; xcb_pixmap_t target = (uintptr_t )native_target; (void) drv; (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); gc = xcb_generate_id(dri2_dpy->conn); xcb_create_gc(dri2_dpy->conn, gc, target, 0, NULL); xcb_copy_area(dri2_dpy->conn, dri2_surf->drawable, target, gc, 0, 0, 0, 0, dri2_surf->base.Width, dri2_surf->base.Height); xcb_free_gc(dri2_dpy->conn, gc); return EGL_TRUE; }
static EGLBoolean dri2_drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); unsigned i; if (dri2_dpy->swrast) { (*dri2_dpy->core->swapBuffers)(dri2_surf->dri_drawable); } else { if (dri2_surf->base.Type == EGL_WINDOW_BIT) { if (dri2_surf->current) _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers"); for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) if (dri2_surf->color_buffers[i].age > 0) dri2_surf->color_buffers[i].age++; /* Make sure we have a back buffer in case we're swapping without * ever rendering. */ if (get_back_bo(dri2_surf) < 0) { _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers"); return EGL_FALSE; } dri2_surf->current = dri2_surf->back; dri2_surf->current->age = 1; dri2_surf->back = NULL; } dri2_flush_drawable_for_swapbuffers(disp, draw); (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); } return EGL_TRUE; }
static EGLImageKHR dri2_get_fb_image(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, EGLint type) { struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); return (type == EGL_DRM_BUFFER_FRONT) ? dri2_surf->khr_front:dri2_surf->khr_back; }
static EGLBoolean dri2_x11_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint interval) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); if (dri2_dpy->swap_available) xcb_dri2_swap_interval(dri2_dpy->conn, dri2_surf->drawable, interval); return EGL_TRUE; }
static int64_t dri2_swap_buffers_msc(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, int64_t msc, int64_t divisor, int64_t remainder) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); uint32_t msc_hi = msc >> 32; uint32_t msc_lo = msc & 0xffffffff; uint32_t divisor_hi = divisor >> 32; uint32_t divisor_lo = divisor & 0xffffffff; uint32_t remainder_hi = remainder >> 32; uint32_t remainder_lo = remainder & 0xffffffff; xcb_dri2_swap_buffers_cookie_t cookie; xcb_dri2_swap_buffers_reply_t *reply; int64_t swap_count = -1; /* No-op for a pixmap or pbuffer surface */ if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT) return 0; if (draw->SwapBehavior == EGL_BUFFER_PRESERVED || !dri2_dpy->swap_available) return dri2_copy_region(drv, disp, draw, dri2_surf->region) ? 0 : -1; if (dri2_dpy->flush) (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); cookie = xcb_dri2_swap_buffers_unchecked(dri2_dpy->conn, dri2_surf->drawable, msc_hi, msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo); reply = xcb_dri2_swap_buffers_reply(dri2_dpy->conn, cookie, NULL); if (reply) { swap_count = (((int64_t)reply->swap_hi) << 32) | reply->swap_lo; free(reply); } /* Since we aren't watching for the server's invalidate events like we're * supposed to (due to XCB providing no mechanism for filtering the events * the way xlib does), and SwapBuffers is a common cause of invalidate * events, just shove one down to the driver, even though we haven't told * the driver that we're the kind of loader that provides reliable * invalidate events. This causes the driver to request buffers again at * its next draw, so that we get the correct buffers if a pageflip * happened. The driver should still be using the viewport hack to catch * window resizes. */ if (dri2_dpy->flush && dri2_dpy->flush->base.version >= 3 && dri2_dpy->flush->invalidate) (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); return swap_count; }
static EGLint dri2_drm_query_buffer_age(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface) { struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface); if (get_back_bo(dri2_surf) < 0) { _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age"); return 0; } return dri2_surf->back->age; }
static EGLBoolean dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); if (dri2_dpy->dri2) { return dri2_swap_buffers_msc(drv, disp, draw, 0, 0, 0) != -1; } else { assert(dri2_dpy->swrast); dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable); return EGL_TRUE; } }
static EGLBoolean surfaceless_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); if (!_eglPutSurface(surf)) return EGL_TRUE; surfaceless_free_images(dri2_surf); (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); free(dri2_surf); return EGL_TRUE; }
static EGLBoolean dri2_x11_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); if (!dri2_dpy->flush) { dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable); return EGL_TRUE; } if (dri2_x11_swap_buffers_msc(drv, disp, draw, 0, 0, 0) == -1) { /* Swap failed with a window drawable. */ return _eglError(EGL_BAD_NATIVE_WINDOW, __func__); } return EGL_TRUE; }
static EGLBoolean dri2_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint interval) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); if (interval > surf->Config->MaxSwapInterval) interval = surf->Config->MaxSwapInterval; else if (interval < surf->Config->MinSwapInterval) interval = surf->Config->MinSwapInterval; if (interval != surf->SwapInterval && dri2_dpy->swap_available) xcb_dri2_swap_interval(dri2_dpy->conn, dri2_surf->drawable, interval); surf->SwapInterval = interval; return EGL_TRUE; }
static EGLBoolean dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); if (dri2_surf->base.Type == EGL_WINDOW_BIT) { if (dri2_surf->current) _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers"); dri2_surf->current = dri2_surf->back; dri2_surf->back = NULL; } (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); return EGL_TRUE; }
static EGLBoolean droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); if (dri2_surf->base.Type != EGL_WINDOW_BIT) return EGL_TRUE; dri2_flush_drawable_for_swapbuffers(disp, draw); if (dri2_surf->buffer) droid_window_enqueue_buffer(disp, dri2_surf); (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); return EGL_TRUE; }
static EGLBoolean dri2_copy_region(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, xcb_xfixes_region_t region) { struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); _EGLContext *ctx; enum xcb_dri2_attachment_t render_attachment; xcb_dri2_copy_region_cookie_t cookie; if (dri2_drv->glFlush) { ctx = _eglGetCurrentContext(); if (ctx && ctx->DrawSurface == &dri2_surf->base) dri2_drv->glFlush(); } (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); #if 0 /* FIXME: Add support for dri swapbuffers, that'll give us swap * interval and page flipping (at least for fullscreen windows) as * well as the page flip event. Unless surface->SwapBehavior is * EGL_BUFFER_PRESERVED. */ #if __DRI2_FLUSH_VERSION >= 2 if (pdraw->psc->f) (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable); #endif #endif if (dri2_surf->have_fake_front) render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT; else render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT; cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn, dri2_surf->drawable, region, XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT, render_attachment); free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL)); return EGL_TRUE; }
static EGLBoolean dri2_x11_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); if (dri2_dpy->dri2) { if (dri2_x11_swap_buffers_msc(drv, disp, draw, 0, 0, 0) != -1) { return EGL_TRUE; } /* Swap failed with a window drawable. */ _eglError(EGL_BAD_NATIVE_WINDOW, __FUNCTION__); return EGL_FALSE; } else { assert(dri2_dpy->swrast); dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable); return EGL_TRUE; } }
static EGLBoolean droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); droid_free_local_buffers(dri2_surf); if (dri2_surf->base.Type == EGL_WINDOW_BIT) { if (dri2_surf->buffer) droid_window_cancel_buffer(disp, dri2_surf); dri2_surf->window->common.decRef(&dri2_surf->window->common); } (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); free(dri2_surf); return EGL_TRUE; }
static int64_t dri2_swap_buffers_msc(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, int64_t msc, int64_t divisor, int64_t remainder) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); uint32_t msc_hi = msc >> 32; uint32_t msc_lo = msc & 0xffffffff; uint32_t divisor_hi = divisor >> 32; uint32_t divisor_lo = divisor & 0xffffffff; uint32_t remainder_hi = remainder >> 32; uint32_t remainder_lo = remainder & 0xffffffff; xcb_dri2_swap_buffers_cookie_t cookie; xcb_dri2_swap_buffers_reply_t *reply; int64_t swap_count = -1; /* No-op for a pixmap or pbuffer surface */ if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT) return 0; if (draw->SwapBehavior == EGL_BUFFER_PRESERVED || !dri2_dpy->swap_available) return dri2_copy_region(drv, disp, draw, dri2_surf->region) ? 0 : -1; if (dri2_dpy->flush) (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); cookie = xcb_dri2_swap_buffers_unchecked(dri2_dpy->conn, dri2_surf->drawable, msc_hi, msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo); reply = xcb_dri2_swap_buffers_reply(dri2_dpy->conn, cookie, NULL); if (reply) { swap_count = (((int64_t)reply->swap_hi) << 32) | reply->swap_lo; free(reply); } return swap_count; }
/** * Function utilizes swrastGetDrawableInfo to get surface * geometry from x server and calls default query surface * implementation that returns the updated values. * * In case of errors we still return values that we currently * have. */ static EGLBoolean dri2_query_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint attribute, EGLint *value) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); int x, y, w, h; __DRIdrawable *drawable = dri2_dpy->vtbl->get_dri_drawable(surf); switch (attribute) { case EGL_WIDTH: case EGL_HEIGHT: if (x11_get_drawable_info(drawable, &x, &y, &w, &h, dri2_surf)) { surf->Width = w; surf->Height = h; } break; default: break; } return _eglQuerySurface(drv, disp, surf, attribute, value); }
/** * Called via eglSwapBuffers(), drv->API.SwapBuffers(). */ static EGLBoolean dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); struct wl_callback *callback; if (dri2_surf->block_swap_buffers) { wl_display_flush(dri2_dpy->wl_dpy); while (dri2_surf->block_swap_buffers) wl_display_iterate(dri2_dpy->wl_dpy, WL_DISPLAY_READABLE); } dri2_surf->block_swap_buffers = EGL_TRUE; callback = wl_surface_frame(dri2_surf->wl_win->surface); wl_callback_add_listener(callback, &frame_listener, dri2_surf); if (dri2_surf->base.Type == EGL_WINDOW_BIT) { pointer_swap( (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT], (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]); dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]->attachment = __DRI_BUFFER_FRONT_LEFT; dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment = __DRI_BUFFER_BACK_LEFT; swap_wl_buffers(dri2_surf, WL_BUFFER_FRONT, WL_BUFFER_BACK); if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT]) dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] = wayland_create_buffer(dri2_surf, dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]); wl_buffer_damage(dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT], 0, 0, dri2_surf->base.Width, dri2_surf->base.Height); wl_surface_attach(dri2_surf->wl_win->surface, dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT], dri2_surf->dx, dri2_surf->dy); dri2_surf->wl_buffer_lock[WL_BUFFER_FRONT] = 1; dri2_surf->wl_win->attached_width = dri2_surf->base.Width; dri2_surf->wl_win->attached_height = dri2_surf->base.Height; /* reset resize growing parameters */ dri2_surf->dx = 0; dri2_surf->dy = 0; wl_surface_damage(dri2_surf->wl_win->surface, 0, 0, dri2_surf->base.Width, dri2_surf->base.Height); } _EGLContext *ctx; if (dri2_drv->glFlush) { ctx = _eglGetCurrentContext(); if (ctx && ctx->DrawSurface == &dri2_surf->base) dri2_drv->glFlush(); } (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); return EGL_TRUE; }
static EGLBoolean dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); __DRIbuffer buffer; static bitmap_t bm; int i; if (dri2_surf->base.Type == EGL_WINDOW_BIT) { if (dri2_surf->current) _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers"); for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) if (dri2_surf->color_buffers[i].age > 0) dri2_surf->color_buffers[i].age++; #if 0 if ( (dri2_surf->back != NULL) && (dri2_surf->back->bo != NULL)) { struct gbm_dri_bo *bo; bo = (struct gbm_dri_bo *)dri2_surf->back->bo; if(bm.width == 0) { // printf("%s bo: %p handle: %d width: %d height: %d pitch %d format %x\n", // __FUNCTION__, bo, bo->base.base.handle.s32, bo->base.base.width, // bo->base.base.height, (int)bo->base.base.stride, // bo->base.base.format); bm.width = bo->base.base.width; bm.height = bo->base.base.height; bm.pitch = (int)bo->base.base.stride; bm.max_width = bo->base.base.width; bm.max_height = bo->base.base.height; bm.flags = HW_TEX_BLIT; if( blit_bitmap_from_handle(&bm, bo->base.base.handle.s32)) { printf("sna_bitmap_from_handle failed\n"); } } if( bm.handle != 0) { // printf("%s bo: %p handle: %d width: %d height: %d pitch %d format %x\n", // __FUNCTION__, bo, bo->base.base.handle.s32, bo->base.base.width, // bo->base.base.height, (int)bo->base.base.stride, // bo->base.base.format); blit_set_bo_handle(&bm, bo->base.base.handle.s32); blit_blit_tex(&bm, 0, 0, 5, 20, bm.width, bm.height, 0, 0); } } #endif dri2_surf->current = dri2_surf->back; dri2_surf->current->age = 1; dri2_surf->back = NULL; } (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); return EGL_TRUE; }