This replaces the stubs for shadow buffer creation/allocation with actual functions and adds a shadow_destroy function. With this, we actually get shadow buffers and RandR now works properly. Most of this is copied from the xf86-video-intel driver and modified for modesetting.
v2 Jason Ekstrand <[email protected]>: - Fix build with --disable-glamor - Set the pixel data pointer in the pixmap header for dumb shadow bo's - Call drmmode_create_bo with the right bpp Signed-off-by: Jason Ekstrand <[email protected]> --- hw/xfree86/drivers/modesetting/drmmode_display.c | 120 ++++++++++++++++++++++- 1 file changed, 118 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 5040d38..a64b312 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -521,13 +521,128 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) static void * drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) { - return NULL; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + int ret; + + if (!drmmode_create_bo(drmmode, &drmmode->shadow_bo, + width, height, crtc->scrn->bitsPerPixel)) { + xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow memory for rotated CRTC\n"); + return NULL; + } + + ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, + crtc->scrn->bitsPerPixel, + drmmode_bo_get_pitch(&drmmode->shadow_bo), + drmmode_bo_get_handle(&drmmode->shadow_bo), + &drmmode_crtc->rotate_fb_id); + + if (ret) { + ErrorF("failed to add rotate fb\n"); + drmmode_bo_destroy(drmmode, &drmmode->shadow_bo); + return NULL; + } + +#ifdef GLAMOR_HAS_GBM + if (drmmode->gbm) + return drmmode->shadow_bo.gbm; +#endif + return drmmode->shadow_bo.dumb; } static PixmapPtr +drmmode_create_pixmap_header(ScreenPtr pScreen, int width, int height, + int depth, int bitsPerPixel, int devKind, + void *pPixData) +{ + PixmapPtr pixmap; + + /* width and height of 0 means don't allocate any pixmap data */ + pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0); + + if (pixmap) { + if ((*pScreen->ModifyPixmapHeader)(pixmap, width, height, depth, + bitsPerPixel, devKind, pPixData)) + return pixmap; + (*pScreen->DestroyPixmap)(pixmap); + } + return NullPixmap; +} + +static Bool +drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo); + +static PixmapPtr drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) { - return NULL; + ScrnInfoPtr scrn = crtc->scrn; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + uint32_t shadow_pitch; + PixmapPtr shadow_pixmap; + void *pPixData = NULL; + + if (!data) { + data = drmmode_shadow_allocate(crtc, width, height); + if (!data) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow pixmap for rotated CRTC\n"); + return NULL; + } + } + + if (!drmmode_bo_has_bo(&drmmode->shadow_bo)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow pixmap for rotated CRTC\n"); + return NULL; + } + + if (!drmmode->glamor) + pPixData = drmmode_map_shadow_bo(drmmode); + + shadow_pitch = drmmode_bo_get_pitch(&drmmode->shadow_bo), + + shadow_pixmap = drmmode_create_pixmap_header(scrn->pScreen, + width, height, + scrn->depth, + scrn->bitsPerPixel, + shadow_pitch, + pPixData); + + if (shadow_pixmap == NULL) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow pixmap for rotated CRTC\n"); + return NULL; + } + + drmmode_set_pixmap_bo(drmmode, shadow_pixmap, &drmmode->shadow_bo); + + drmmode->shadow_enable = TRUE; + + return shadow_pixmap; +} + +static void +drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr shadow_pixmap, void *data) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + if (shadow_pixmap) { + drmmode_set_pixmap_bo(drmmode, shadow_pixmap, NULL); + shadow_pixmap->drawable.pScreen->DestroyPixmap(shadow_pixmap); + } + + if (data) { + drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id); + drmmode_crtc->rotate_fb_id = 0; + + drmmode_bo_destroy(drmmode, &drmmode->shadow_bo); + memset(&drmmode->shadow_bo, 0, sizeof drmmode->shadow_bo); + } + + drmmode->shadow_enable = FALSE; } static const xf86CrtcFuncsRec drmmode_crtc_funcs = { @@ -544,6 +659,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = { .set_scanout_pixmap = drmmode_set_scanout_pixmap, .shadow_allocate = drmmode_shadow_allocate, .shadow_create = drmmode_shadow_create, + .shadow_destroy = drmmode_shadow_destroy, }; static uint32_t -- 2.2.0 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
