[PATCH 4/4] modesetting: Add support for using shadow buffers
Jason Ekstrand
jason at jlekstrand.net
Fri Dec 19 14:12:45 PST 2014
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.
Signed-off-by: Jason Ekstrand <jason.ekstrand at intel.com>
---
hw/xfree86/drivers/modesetting/drmmode_display.c | 116 ++++++++++++++++++++++-
1 file changed, 114 insertions(+), 2 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 5648d7b..8ac5c77 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -510,13 +510,124 @@ 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, drmmode->cpp)) {
+ 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;
+
+ 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->shadow_bo.gbm == NULL && drmmode->shadow_bo.dumb == NULL) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow pixmap for rotated CRTC\n");
+ return NULL;
+ }
+
+ 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,
+ NULL);
+
+ 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 = {
@@ -533,6 +644,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