/** * Schedule a copy swap from the back to the front buffer using the * native display's copy context. */ boolean resource_surface_copy_swap(struct resource_surface *rsurf, struct native_display *ndpy) { struct pipe_resource *ftex; struct pipe_resource *btex; struct pipe_context *pipe; struct pipe_box src_box; boolean ret = FALSE; pipe = ndpy_get_copy_context(ndpy); if (!pipe) return FALSE; ftex = resource_surface_get_single_resource(rsurf, NATIVE_ATTACHMENT_FRONT_LEFT); if (!ftex) goto out_no_ftex; btex = resource_surface_get_single_resource(rsurf, NATIVE_ATTACHMENT_BACK_LEFT); if (!btex) goto out_no_btex; u_box_origin_2d(ftex->width0, ftex->height0, &src_box); pipe->resource_copy_region(pipe, ftex, 0, 0, 0, 0, btex, 0, &src_box); ret = TRUE; out_no_btex: pipe_resource_reference(&btex, NULL); out_no_ftex: pipe_resource_reference(&ftex, NULL); return ret; }
/** * Add textures as DRM framebuffers. */ static boolean drm_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back) { struct drm_surface *drmsurf = drm_surface(nsurf); struct drm_display *drmdpy = drmsurf->drmdpy; int num_framebuffers = (need_back) ? 2 : 1; int i, err; for (i = 0; i < num_framebuffers; i++) { struct drm_framebuffer *fb; enum native_attachment natt; struct winsys_handle whandle; uint block_bits; if (i == 0) { fb = &drmsurf->front_fb; natt = NATIVE_ATTACHMENT_FRONT_LEFT; } else { fb = &drmsurf->back_fb; natt = NATIVE_ATTACHMENT_BACK_LEFT; } if (!fb->texture) { /* make sure the texture has been allocated */ resource_surface_add_resources(drmsurf->rsurf, 1 << natt); fb->texture = resource_surface_get_single_resource(drmsurf->rsurf, natt); if (!fb->texture) return FALSE; } /* already initialized */ if (fb->buffer_id) continue; /* TODO detect the real value */ fb->is_passive = TRUE; memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_KMS; if (!drmdpy->base.screen->resource_get_handle(drmdpy->base.screen, fb->texture, &whandle)) return FALSE; block_bits = util_format_get_blocksizebits(drmsurf->color_format); err = drmModeAddFB(drmdpy->fd, drmsurf->width, drmsurf->height, block_bits, block_bits, whandle.stride, whandle.handle, &fb->buffer_id); if (err) { fb->buffer_id = 0; return FALSE; } } return TRUE; }
static void wayland_pixmap_surface_initialize(struct wayland_surface *surface) { struct wayland_display *display = wayland_display(&surface->display->base); const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT; if (surface->pix->buffer != NULL) return; surface->pix->buffer = display->create_buffer(display, surface, front_natt); surface->pix->destroy = wayland_pixmap_destroy; surface->pix->driver_private = resource_surface_get_single_resource(surface->rsurf, front_natt); }
static void wayland_window_surface_handle_resize(struct wayland_surface *surface) { struct wayland_display *display = surface->display; struct pipe_resource *front_resource; const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT; int i; front_resource = resource_surface_get_single_resource(surface->rsurf, front_natt); if (resource_surface_set_size(surface->rsurf, surface->win->width, surface->win->height)) { if (surface->pending_resource) wayland_roundtrip(display); if (front_resource) { struct wl_callback *callback; surface->pending_resource = front_resource; front_resource = NULL; callback = wl_display_sync(display->dpy); wl_callback_add_listener(callback, &release_buffer_listener, surface); wl_proxy_set_queue((struct wl_proxy *) callback, display->queue); } for (i = 0; i < WL_BUFFER_COUNT; ++i) { if (surface->buffer[i]) wl_buffer_destroy(surface->buffer[i]); surface->buffer[i] = NULL; } surface->dx = surface->win->dx; surface->dy = surface->win->dy; } pipe_resource_reference(&front_resource, NULL); }
static struct wl_buffer * wayland_create_drm_buffer(struct wayland_display *display, struct wayland_surface *surface, enum native_attachment attachment) { struct wayland_drm_display *drmdpy = (struct wayland_drm_display *) display; struct pipe_screen *screen = drmdpy->base.base.screen; struct pipe_resource *resource; struct winsys_handle wsh; uint width, height; enum wl_drm_format format; resource = resource_surface_get_single_resource(surface->rsurf, attachment); resource_surface_get_size(surface->rsurf, &width, &height); wsh.type = DRM_API_HANDLE_TYPE_SHARED; screen->resource_get_handle(screen, resource, &wsh); pipe_resource_reference(&resource, NULL); switch (surface->color_format) { case PIPE_FORMAT_B8G8R8A8_UNORM: format = (surface->premultiplied_alpha) ? WL_DRM_FORMAT_PREMULTIPLIED_ARGB32 : WL_DRM_FORMAT_ARGB32; break; case PIPE_FORMAT_B8G8R8X8_UNORM: format = WL_DRM_FORMAT_XRGB32; break; default: return NULL; break; } return wl_drm_create_buffer(drmdpy->wl_drm, wsh.handle, width, height, wsh.stride, format); }