[PATCH v2 5/6] modesetting: Add support for using shadow buffers
Jason Ekstrand
jason at jlekstrand.net
Wed Jan 7 15:59:10 PST 2015
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 <jason.ekstrand at intel.com>:
- 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 <jason.ekstrand at intel.com>
---
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
More information about the xorg-devel
mailing list