modesetting: Implement DRI2InfoRec version 9 callbacks

Implement the CreateBuffer2 / DestroyBuffer2 / CopyRegion2 DRI2InfoRec
version 9 callbacks, this is necessary for being an offload source
provider with DRI2.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Hans de Goede 2016-08-15 12:02:54 +02:00 committed by Adam Jackson
parent 03a7c50202
commit 238248d67e

View File

@ -119,10 +119,9 @@ get_drawable_pixmap(DrawablePtr drawable)
} }
static DRI2Buffer2Ptr static DRI2Buffer2Ptr
ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment, ms_dri2_create_buffer2(ScreenPtr screen, DrawablePtr drawable,
unsigned int format) unsigned int attachment, unsigned int format)
{ {
ScreenPtr screen = drawable->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen); ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
DRI2Buffer2Ptr buffer; DRI2Buffer2Ptr buffer;
PixmapPtr pixmap; PixmapPtr pixmap;
@ -219,6 +218,14 @@ ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
return buffer; return buffer;
} }
static DRI2Buffer2Ptr
ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
unsigned int format)
{
return ms_dri2_create_buffer2(drawable->pScreen, drawable, attachment,
format);
}
static void static void
ms_dri2_reference_buffer(DRI2Buffer2Ptr buffer) ms_dri2_reference_buffer(DRI2Buffer2Ptr buffer)
{ {
@ -228,7 +235,8 @@ ms_dri2_reference_buffer(DRI2Buffer2Ptr buffer)
} }
} }
static void ms_dri2_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer) static void ms_dri2_destroy_buffer2(ScreenPtr unused, DrawablePtr unused2,
DRI2Buffer2Ptr buffer)
{ {
if (!buffer) if (!buffer)
return; return;
@ -246,28 +254,55 @@ static void ms_dri2_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
} }
} }
static void ms_dri2_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
{
ms_dri2_destroy_buffer2(NULL, drawable, buffer);
}
static void static void
ms_dri2_copy_region(DrawablePtr drawable, RegionPtr pRegion, ms_dri2_copy_region2(ScreenPtr screen, DrawablePtr drawable, RegionPtr pRegion,
DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer) DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer)
{ {
ms_dri2_buffer_private_ptr src_priv = sourceBuffer->driverPrivate; ms_dri2_buffer_private_ptr src_priv = sourceBuffer->driverPrivate;
ms_dri2_buffer_private_ptr dst_priv = destBuffer->driverPrivate; ms_dri2_buffer_private_ptr dst_priv = destBuffer->driverPrivate;
PixmapPtr src_pixmap = src_priv->pixmap; PixmapPtr src_pixmap = src_priv->pixmap;
PixmapPtr dst_pixmap = dst_priv->pixmap; PixmapPtr dst_pixmap = dst_priv->pixmap;
ScreenPtr screen = drawable->pScreen;
DrawablePtr src = (sourceBuffer->attachment == DRI2BufferFrontLeft) DrawablePtr src = (sourceBuffer->attachment == DRI2BufferFrontLeft)
? drawable : &src_pixmap->drawable; ? drawable : &src_pixmap->drawable;
DrawablePtr dst = (destBuffer->attachment == DRI2BufferFrontLeft) DrawablePtr dst = (destBuffer->attachment == DRI2BufferFrontLeft)
? drawable : &dst_pixmap->drawable; ? drawable : &dst_pixmap->drawable;
int off_x = 0, off_y = 0;
Bool translate = FALSE;
RegionPtr pCopyClip; RegionPtr pCopyClip;
GCPtr gc; GCPtr gc;
if (destBuffer->attachment == DRI2BufferFrontLeft &&
drawable->pScreen != screen) {
dst = DRI2UpdatePrime(drawable, destBuffer);
if (!dst)
return;
if (dst != drawable)
translate = TRUE;
}
if (translate && drawable->type == DRAWABLE_WINDOW) {
#ifdef COMPOSITE
PixmapPtr pixmap = get_drawable_pixmap(drawable);
off_x = -pixmap->screen_x;
off_y = -pixmap->screen_y;
#endif
off_x += drawable->x;
off_y += drawable->y;
}
gc = GetScratchGC(dst->depth, screen); gc = GetScratchGC(dst->depth, screen);
if (!gc) if (!gc)
return; return;
pCopyClip = REGION_CREATE(screen, NULL, 0); pCopyClip = REGION_CREATE(screen, NULL, 0);
REGION_COPY(screen, pCopyClip, pRegion); REGION_COPY(screen, pCopyClip, pRegion);
if (translate)
REGION_TRANSLATE(screen, pCopyClip, off_x, off_y);
(*gc->funcs->ChangeClip) (gc, CT_REGION, pCopyClip, 0); (*gc->funcs->ChangeClip) (gc, CT_REGION, pCopyClip, 0);
ValidateGC(dst, gc); ValidateGC(dst, gc);
@ -283,11 +318,19 @@ ms_dri2_copy_region(DrawablePtr drawable, RegionPtr pRegion,
gc->ops->CopyArea(src, dst, gc, gc->ops->CopyArea(src, dst, gc,
0, 0, 0, 0,
drawable->width, drawable->height, drawable->width, drawable->height,
0, 0); off_x, off_y);
FreeScratchGC(gc); FreeScratchGC(gc);
} }
static void
ms_dri2_copy_region(DrawablePtr drawable, RegionPtr pRegion,
DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer)
{
ms_dri2_copy_region2(drawable->pScreen, drawable, pRegion, destBuffer,
sourceBuffer);
}
static uint64_t static uint64_t
gettime_us(void) gettime_us(void)
{ {
@ -1046,13 +1089,16 @@ ms_dri2_screen_init(ScreenPtr screen)
info.driverName = NULL; /* Compat field, unused. */ info.driverName = NULL; /* Compat field, unused. */
info.deviceName = drmGetDeviceNameFromFd(ms->fd); info.deviceName = drmGetDeviceNameFromFd(ms->fd);
info.version = 4; info.version = 9;
info.CreateBuffer = ms_dri2_create_buffer; info.CreateBuffer = ms_dri2_create_buffer;
info.DestroyBuffer = ms_dri2_destroy_buffer; info.DestroyBuffer = ms_dri2_destroy_buffer;
info.CopyRegion = ms_dri2_copy_region; info.CopyRegion = ms_dri2_copy_region;
info.ScheduleSwap = ms_dri2_schedule_swap; info.ScheduleSwap = ms_dri2_schedule_swap;
info.GetMSC = ms_dri2_get_msc; info.GetMSC = ms_dri2_get_msc;
info.ScheduleWaitMSC = ms_dri2_schedule_wait_msc; info.ScheduleWaitMSC = ms_dri2_schedule_wait_msc;
info.CreateBuffer2 = ms_dri2_create_buffer2;
info.DestroyBuffer2 = ms_dri2_destroy_buffer2;
info.CopyRegion2 = ms_dri2_copy_region2;
/* These two will be filled in by dri2.c */ /* These two will be filled in by dri2.c */
info.numDrivers = 0; info.numDrivers = 0;