summaryrefslogtreecommitdiff
path: root/hw/xfree86/dri2/dri2.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/dri2/dri2.c')
-rw-r--r--hw/xfree86/dri2/dri2.c107
1 files changed, 71 insertions, 36 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index d5273877e..74aef7196 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -38,6 +38,8 @@
#include "xf86Module.h"
#include "scrnintstr.h"
#include "windowstr.h"
+#include "region.h"
+#include "damage.h"
#include "dri2.h"
#include <GL/internal/dri_sarea.h>
@@ -48,8 +50,9 @@ static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKey;
static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKey;
typedef struct _DRI2DrawablePriv {
- drm_drawable_t drawable;
- unsigned int handle;
+ unsigned int refCount;
+ unsigned int boHandle;
+ unsigned int dri2Handle;
} DRI2DrawablePrivRec, *DRI2DrawablePrivPtr;
typedef struct _DRI2Screen {
@@ -58,6 +61,7 @@ typedef struct _DRI2Screen {
void *sarea;
unsigned int sareaSize;
const char *driverName;
+ unsigned int nextHandle;
__DRIEventBuffer *buffer;
int locked;
@@ -147,7 +151,7 @@ DRI2PostDrawableConfig(DrawablePtr pDraw)
e = DRI2ScreenAllocEvent(ds, size);
e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_DRAWABLE_CONFIG, size);
- e->drawable = pPriv->drawable;
+ e->drawable = pPriv->dri2Handle;
e->x = pDraw->x - pPixmap->screen_x;
e->y = pDraw->y - pPixmap->screen_y;
e->width = pDraw->width;
@@ -164,7 +168,7 @@ DRI2PostDrawableConfig(DrawablePtr pDraw)
}
static void
-DRI2PostBufferAttach(DrawablePtr pDraw)
+DRI2PostBufferAttach(DrawablePtr pDraw, Bool force)
{
ScreenPtr pScreen = pDraw->pScreen;
DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
@@ -173,7 +177,8 @@ DRI2PostBufferAttach(DrawablePtr pDraw)
PixmapPtr pPixmap;
__DRIBufferAttachEvent *e;
size_t size;
- unsigned int handle, flags;
+ unsigned int flags;
+ unsigned int boHandle;
if (pDraw->type == DRAWABLE_WINDOW) {
pWin = (WindowPtr) pDraw;
@@ -187,22 +192,20 @@ DRI2PostBufferAttach(DrawablePtr pDraw)
if (!pPriv)
return;
- size = sizeof *e;
-
- handle = ds->getPixmapHandle(pPixmap, &flags);
- if (handle == 0 || handle == pPriv->handle)
+ boHandle = ds->getPixmapHandle(pPixmap, &flags);
+ if (boHandle == pPriv->boHandle && !force)
return;
+ pPriv->boHandle = boHandle;
+ size = sizeof *e;
e = DRI2ScreenAllocEvent(ds, size);
e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_BUFFER_ATTACH, size);
- e->drawable = pPriv->drawable;
+ e->drawable = pPriv->dri2Handle;
e->buffer.attachment = DRI_DRAWABLE_BUFFER_FRONT_LEFT;
- e->buffer.handle = handle;
+ e->buffer.handle = pPriv->boHandle;
e->buffer.pitch = pPixmap->devKind;
e->buffer.cpp = pPixmap->drawable.bitsPerPixel / 8;
e->buffer.flags = flags;
-
- pPriv->handle = handle;
}
static void
@@ -223,7 +226,7 @@ DRI2ClipNotify(WindowPtr pWin, int dx, int dy)
}
DRI2PostDrawableConfig(&pWin->drawable);
- DRI2PostBufferAttach(&pWin->drawable);
+ DRI2PostBufferAttach(&pWin->drawable, FALSE);
}
static void
@@ -262,10 +265,10 @@ DRI2CloseScreen(ScreenPtr pScreen)
}
Bool
-DRI2CreateDrawable(ScreenPtr pScreen, DrawablePtr pDraw,
- drm_drawable_t *pDrmDrawable, unsigned int *head)
+DRI2CreateDrawable(DrawablePtr pDraw,
+ unsigned int *handle, unsigned int *head)
{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
WindowPtr pWin;
PixmapPtr pPixmap;
DRI2DrawablePrivPtr pPriv;
@@ -283,47 +286,66 @@ DRI2CreateDrawable(ScreenPtr pScreen, DrawablePtr pDraw,
}
pPriv = dixLookupPrivate(devPrivates, key);
- if (pPriv == NULL) {
+ if (pPriv != NULL) {
+ pPriv->refCount++;
+ } else {
pPriv = xalloc(sizeof *pPriv);
- if (drmCreateDrawable(ds->fd, &pPriv->drawable))
- return FALSE;
-
+ pPriv->refCount = 1;
+ pPriv->boHandle = 0;
+ pPriv->dri2Handle = ds->nextHandle++;
dixSetPrivate(devPrivates, key, pPriv);
}
- *pDrmDrawable = pPriv->drawable;
-
+ *handle = pPriv->dri2Handle;
*head = ds->buffer->head;
+
DRI2PostDrawableConfig(pDraw);
- DRI2PostBufferAttach(pDraw);
+ DRI2PostBufferAttach(pDraw, TRUE);
DRI2ScreenCommitEvents(ds);
return TRUE;
}
void
-DRI2DestroyDrawable(ScreenPtr pScreen, DrawablePtr pDraw)
+DRI2DestroyDrawable(DrawablePtr pDraw)
{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
- PixmapPtr pPixmap;
- WindowPtr pWin;
- DRI2DrawablePrivPtr pPriv;
+ PixmapPtr pPixmap;
+ WindowPtr pWin;
+ DRI2DrawablePrivPtr pPriv;
+ DevPrivateKey key;
+ PrivateRec **devPrivates;
if (pDraw->type == DRAWABLE_WINDOW) {
pWin = (WindowPtr) pDraw;
- pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
- dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
+ devPrivates = &pWin->devPrivates;
+ key = dri2WindowPrivateKey;
} else {
pPixmap = (PixmapPtr) pDraw;
- pPriv = dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
- dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
+ devPrivates = &pPixmap->devPrivates;
+ key = dri2PixmapPrivateKey;
}
+ pPriv = dixLookupPrivate(devPrivates, key);
if (pPriv == NULL)
return;
- drmDestroyDrawable(ds->fd, pPriv->drawable);
- xfree(pPriv);
+ pPriv->refCount--;
+ if (pPriv->refCount == 0) {
+ dixSetPrivate(devPrivates, key, NULL);
+ xfree(pPriv);
+ }
+}
+
+void
+DRI2ReemitDrawableInfo(DrawablePtr pDraw, unsigned int *head)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+
+ *head = ds->buffer->head;
+
+ DRI2PostDrawableConfig(pDraw);
+ DRI2PostBufferAttach(pDraw, TRUE);
+ DRI2ScreenCommitEvents(ds);
}
Bool
@@ -409,8 +431,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
if (!ds)
return NULL;
- ds->fd = info->fd;
+ ds->fd = info->fd;
ds->driverName = info->driverName;
+ ds->nextHandle = 1;
ds->getPixmapHandle = info->getPixmapHandle;
ds->beginClipNotify = info->beginClipNotify;
@@ -434,9 +457,21 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
return p;
}
+extern ExtensionModule dri2ExtensionModule;
+
static pointer
DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ LoadExtension(&dri2ExtensionModule, FALSE);
+ } else {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ }
+
return (pointer) 1;
}