Пример #1
0
static cairo_surface_t *
_xcb_drm_create_surface_for_drawable (cairo_xcb_connection_t *connection,
				      cairo_xcb_screen_t *screen,
				      xcb_drawable_t drawable,
				      pixman_format_code_t pixman_format,
				      int width, int height)
{
    uint32_t attachments[] = { XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT };
    xcb_dri2_get_buffers_reply_t *buffers;
    xcb_dri2_dri2_buffer_t *buffer;
    cairo_surface_t *surface;

    if (! _cairo_drm_size_is_valid (screen->device, width, height))
	return NULL;

    xcb_dri2_create_drawable (connection->xcb_connection,
			      drawable);

    buffers = xcb_dri2_get_buffers_reply (connection->xcb_connection,
					  xcb_dri2_get_buffers (connection->xcb_connection,
								drawable, 1,
								ARRAY_LENGTH (attachments),
								attachments),
					  0);
    if (buffers == NULL) {
	xcb_dri2_destroy_drawable (connection->xcb_connection,
				   drawable);
	return NULL;
    }

    /* If the drawable is a window, we expect to receive an extra fake front,
     * which would involve copying on each flush - contrary to the user
     * expectations. But that is likely to be preferable to mixing drm/xcb
     * operations.
     */
    buffer = xcb_dri2_get_buffers_buffers (buffers);
    if (buffers->count == 1 && buffer[0].attachment == XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT) {
	assert (buffer[0].cpp == PIXMAN_FORMAT_BPP (pixman_format) / 8);
	surface = cairo_drm_surface_create_for_name (screen->device,
						     buffer[0].name,
						     _cairo_format_from_pixman_format (pixman_format),
						     width, height,
						     buffer[0].pitch);
    } else {
	xcb_dri2_destroy_drawable (connection->xcb_connection,
				   drawable);
	surface = NULL;
    }
    free (buffers);

    return surface;
}
Пример #2
0
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;
}
Пример #3
0
static cairo_status_t
_cairo_xcb_surface_finish (void *abstract_surface)
{
    cairo_xcb_surface_t *surface = abstract_surface;
    cairo_status_t status;

    if (surface->fallback != NULL) {
	cairo_surface_finish (surface->fallback);
	cairo_surface_destroy (surface->fallback);
    }

    cairo_list_del (&surface->link);

#if CAIRO_HAS_DRM_SURFACE && CAIRO_HAS_XCB_DRM_FUNCTIONS
    if (surface->drm != NULL) {
	cairo_surface_finish (surface->drm);
	cairo_surface_destroy (surface->drm);

	xcb_dri2_destroy_drawable (surface->connection->xcb_connection,
				   surface->drawable);
    }
#endif

    status = _cairo_xcb_connection_acquire (surface->connection);
    if (status == CAIRO_STATUS_SUCCESS) {
	if (_cairo_xcb_connection_take_socket (surface->connection) == CAIRO_STATUS_SUCCESS) {
	    if (surface->picture != XCB_NONE) {
		_cairo_xcb_connection_render_free_picture (surface->connection,
							   surface->picture);
	    }

	    if (surface->owns_pixmap)
		_cairo_xcb_connection_free_pixmap (surface->connection, surface->drawable);
	}
	_cairo_xcb_connection_release (surface->connection);
    }

    _cairo_xcb_connection_destroy (surface->connection);

    return status;
}