diff options
Diffstat (limited to 'src/videocore-exa.c')
-rw-r--r-- | src/videocore-exa.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/src/videocore-exa.c b/src/videocore-exa.c index f58b4ac..c401706 100644 --- a/src/videocore-exa.c +++ b/src/videocore-exa.c @@ -242,6 +242,12 @@ typedef struct _VideoCorePixmapPriv { EGLint global_image[5]; EGLImageKHR egl_image; GLuint texture_id; + + /* Blob of memory backing the pixmap. If is_screen_pixmap || texture_id + * != 0, only set between PrepareAccess and FinishAccess. Otherwise, + * allocated in ModifyPixmapHeader and freed in DestroyPixmap. + */ + void *data; } VideoCorePixmapPrivRec, *VideoCorePixmapPrivPtr; static void * @@ -397,7 +403,13 @@ VideoCoreModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, if (bitsPerPixel != 32) { DEBUG_MSG("Can't accelerate pixmap %p with bpp %u", pPixmap, bitsPerPixel); - pPixmap->devPrivate.ptr = malloc(pPixmap->devKind * height); + /* FIXME: we'll presumably need to free previously-allocated + * blobs at some point if we're modifying a pixmap */ + priv->data = malloc(pPixmap->devKind * height); + if (priv->data == NULL) { + WARNING_MSG("can't allocate %u * %u bytes", pPixmap->devKind, height); + } + pPixmap->devPrivate.ptr = priv->data; return TRUE; /* ??? */ } @@ -432,6 +444,7 @@ VideoCoreDestroyPixmap(ScreenPtr pScreen, void *driverPriv) VideoCorePixmapPrivPtr priv = driverPriv; DestroyGlobalImage(vcExa, pScrn, priv); + free(priv->data); free(priv); } @@ -470,7 +483,6 @@ VideoCorePrepareAccess(PixmapPtr pPixmap, int index) VideoCorePixmapPrivPtr priv = exaGetPixmapDriverPrivate(pPixmap); ScrnInfoPtr pScrn = pix2scrn(pPixmap); unsigned short width, height; - pointer data; DEBUG_MSG("called for pixmap %p, is_screen_pixmap %s, texture %u, index %u", pPixmap, @@ -484,23 +496,27 @@ VideoCorePrepareAccess(PixmapPtr pPixmap, int index) width = pPixmap->drawable.width; height = pPixmap->drawable.height; - assert (pPixmap->drawable.bitsPerPixel / 8 == 4); - data = malloc(width * height * 4); - if (!data) { + /* If we're here, this had better be an XRGB pixmap */ + assert (pPixmap->drawable.bitsPerPixel / 8 == 4); + /* And we shouldn't get here more than once at a time */ + assert (priv->data == NULL); + priv->data = malloc(width * height * 4); + if (!priv->data) { ERROR_MSG("couldn't allocate %hu * %hu * 4 bytes!", width, height); return FALSE; } - ReadPixels(pScrn, priv->texture_id, 0, 0, width, height, data, 0 /* FIXME: pitch */); + ReadPixels(pScrn, priv->texture_id, 0, 0, width, height, priv->data, 0 /* FIXME: pitch */); if (!CheckGLError(pScrn, "PrepareAccess:ReadPixels")) { - free(data); + free(priv->data); + priv->data = NULL; return FALSE; } - pPixmap->devPrivate.ptr = data; - DEBUG_MSG("allocated %p for pixmap %p", data, pPixmap); + pPixmap->devPrivate.ptr = priv->data; + DEBUG_MSG("allocated %p for pixmap %p", priv->data, pPixmap); return TRUE; } @@ -510,7 +526,6 @@ VideoCoreFinishAccess(PixmapPtr pPixmap, int index) VideoCorePixmapPrivPtr priv = exaGetPixmapDriverPrivate(pPixmap); ScrnInfoPtr pScrn = pix2scrn(pPixmap); unsigned short width, height; - pointer data; if (!priv->is_screen_pixmap) { WARNING_MSG("called for a pixmap other than the screen!"); @@ -522,13 +537,11 @@ VideoCoreFinishAccess(PixmapPtr pPixmap, int index) width = pPixmap->drawable.width; height = pPixmap->drawable.height; - data = pPixmap->devPrivate.ptr; - assert(data != NULL); - pPixmap->devPrivate.ptr = NULL; + assert(priv->data != NULL); /* FIXME: shade me up */ (void) (width + height); - free(data); + free(priv->data); CheckGLError(pScrn, "FinishAccess:glDrawPixels"); } |