diff options
author | Jordan Crouse <jordan.crouse@amd.com> | 2008-08-18 14:19:34 -0600 |
---|---|---|
committer | Jordan Crouse <jordan.crouse@amd.com> | 2008-08-18 14:19:34 -0600 |
commit | 38e868271bd24be7a884c8c56772b25cd6fa6f1d (patch) | |
tree | dfc6f8ab0e7f2c6c641d0bdb68cdaef5fa522b42 | |
parent | d681a844e448712a9a419d2a4dca81930d39a80a (diff) |
lx: Add rotation for Randr 1.2 + cleanups
Enable rotation through RandR 1.2 and add the accelerated rotation blit
the EXA composite function. Also, fix a handful of critical bugs and
remove some more dead code.
-rw-r--r-- | src/geode.h | 1 | ||||
-rw-r--r-- | src/lx_cursor.c | 83 | ||||
-rw-r--r-- | src/lx_display.c | 27 | ||||
-rw-r--r-- | src/lx_driver.c | 20 | ||||
-rw-r--r-- | src/lx_exa.c | 337 | ||||
-rw-r--r-- | src/lx_memory.c | 44 | ||||
-rw-r--r-- | src/lx_output.c | 6 | ||||
-rw-r--r-- | src/lx_panel.c | 3 | ||||
-rw-r--r-- | src/lx_video.c | 2 |
9 files changed, 322 insertions, 201 deletions
diff --git a/src/geode.h b/src/geode.h index 4fefcb6..3a281f2 100644 --- a/src/geode.h +++ b/src/geode.h @@ -453,6 +453,7 @@ GeodeMemPtr GeodeAllocOffscreen(GeodeRec * pGeode, int size, int align); void GeodeFreeOffscreen(GeodeRec * pGeode, GeodeMemPtr ptr); void LXInitOffscreen(ScrnInfoPtr pScrni); void GeodeCloseOffscreen(ScrnInfoPtr pScrni); +unsigned int GeodeOffscreenFreeSize(GeodeRec * pGeode); /* lx_cursor.c */ Bool LXCursorInit(ScreenPtr pScrn); diff --git a/src/lx_cursor.c b/src/lx_cursor.c index 61bee04..ca74dd6 100644 --- a/src/lx_cursor.c +++ b/src/lx_cursor.c @@ -35,69 +35,50 @@ Bool LXCursorInit(ScreenPtr pScrn) { return xf86_cursors_init(pScrn, 32, 32, - HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | - HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED); + HARDWARE_CURSOR_INVERT_MASK | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32); +} + +static int +_getrow(char *src, int stride, int x, int y) +{ + x = ((x & ~31) << 1) | (x & 31); + src += y * stride; + return (src[x >> 3] >> (x & 7)) & 1; +} + +static int +_getmask(char *src, int stride, int x, int y) +{ + x = ((x & ~31) << 1) | (1 << 5) | (x & 31); + src += y * stride; + return (src[x >> 3] >> (x & 7)) & 1; } void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src) { - int i, n, x, y, newX, newY; - unsigned long andMask[32], xorMask[32]; GeodeRec *pGeode = GEODEPTR(pScrni); - unsigned long mskb, rowb; - unsigned char *rowp = &src[0]; - unsigned char *mskp = &src[128]; - - if (src != NULL) { - mskb = rowb = 0; - for (y = 32; --y >= 0;) - andMask[y] = xorMask[y] = 0; - for (y = 0; y < 32; ++y) { - for (x = 0; x < 32; ++x) { - if ((i = x & 7) == 0) { - rowb = (*rowp & *mskp); - mskb = ~(*mskp); - ++rowp; - ++mskp; - } + unsigned long andMask[32], xorMask[32]; + unsigned char *ptr = src; + int y, x; - switch (pGeode->rotation) { - default: - ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__, - pGeode->rotation); - case RR_Rotate_0: - newX = x; - newY = y; - break; - case RR_Rotate_270: - newX = y; - newY = 31 - x; - break; - case RR_Rotate_180: - newX = 31 - x; - newY = 31 - y; - break; - case RR_Rotate_90: - newX = 31 - y; - newY = x; - break; - } + for (y = 0; y < 32; y++) { + andMask[y] = (src) ? 0 : ~0; + xorMask[y] = 0; + } - i = 7 - i; - n = 31 - newX; - andMask[newY] |= (((mskb >> i) & 1) << n); - xorMask[newY] |= (((rowb >> i) & 1) << n); + if (src != NULL) { + for (y = 0; y < 32; y++) { + for (x = 0; x < 32; x++) { + xorMask[y] |= _getrow(src, 8, x, y) << (31 - x); + andMask[y] |= _getmask(src, 8, x, y) << (31 - x); } } - } else { - for (y = 32; --y >= 0;) { - andMask[y] = ~0; - xorMask[y] = 0; - } } vg_set_mono_cursor_shape32(pGeode->CursorStartOffset, &andMask[0], - &xorMask[0], 31, 31); + &xorMask[0], 32, 32); } diff --git a/src/lx_display.c b/src/lx_display.c index c53a9f5..fa74831 100644 --- a/src/lx_display.c +++ b/src/lx_display.c @@ -279,10 +279,16 @@ lx_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, vg_set_display_pitch(pGeode->Pitch); gp_set_bpp(pScrni->bitsPerPixel); + /* Set the acceleration offset if we are drawing to a shadow */ + if (crtc->rotatedData != NULL) + vg_set_display_offset((unsigned int)((char *)crtc->rotatedData - + (char *)pGeode->FBBase)); + else + vg_set_display_offset(0); + /* FIXME: Whats up with X and Y? Does that come into play * here? */ - vg_set_display_offset(0); df_configure_video_source(&vs_odd, &vs_even); vg_wait_vertical_blank(); @@ -358,7 +364,11 @@ lx_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) if (lx_crtc->rotate_mem == NULL) { xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Couldn't allocate shadow memory for rotated CRTC\n"); + "Couldn't allocate the shadow memory for rotation\n"); + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + " You need 0x%x bytes, but only 0x%x bytes are available\n", + size, GeodeOffscreenFreeSize(pGeode)); + return NULL; } @@ -370,16 +380,15 @@ static PixmapPtr lx_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) { ScrnInfoPtr pScrni = crtc->scrn; + GeodeRec *pGeode = GEODEPTR(pScrni); PixmapPtr rpixmap; - unsigned int rpitch; if (!data) data = lx_crtc_shadow_allocate(crtc, width, height); - rpitch = pScrni->displayWidth * (pScrni->bitsPerPixel / 8); - rpixmap = GetScratchPixmapHeader(pScrni->pScreen, - width, height, pScrni->depth, pScrni->bitsPerPixel, rpitch, data); + width, height, pScrni->depth, pScrni->bitsPerPixel, pGeode->Pitch, + data); if (rpixmap == NULL) { xf86DrvMsg(pScrni->scrnIndex, X_ERROR, @@ -443,9 +452,7 @@ lx_crtc_hide_cursor(xf86CrtcPtr crtc) static void lx_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src) { - ScrnInfoPtr pScrni = crtc->scrn; - - LXLoadCursorImage(pScrni, src); + LXLoadCursorImage(crtc->scrn, src); } static const xf86CrtcFuncsRec lx_crtc_funcs = { @@ -476,7 +483,7 @@ LXSetupCrtc(ScrnInfoPtr pScrni) crtc = xf86CrtcCreate(pScrni, &lx_crtc_funcs); if (crtc == NULL) { - ErrorF("ERROR - xf86CrtcCreate() fail %x\n", crtc); + ErrorF("ERROR - failed to create a CRTC\n"); return; } diff --git a/src/lx_driver.c b/src/lx_driver.c index c50827a..9f68a03 100644 --- a/src/lx_driver.c +++ b/src/lx_driver.c @@ -808,19 +808,6 @@ LXLoadPalette(ScrnInfoPtr pScrni, } static Bool -LXCreateScreenResources(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - - pScreen->CreateScreenResources = pGeode->CreateScreenResources; - if (!(*pScreen->CreateScreenResources) (pScreen)) - return FALSE; - - return TRUE; -} - -static Bool LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) { ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; @@ -968,13 +955,16 @@ LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) pGeode->PointerMoved = pScrni->PointerMoved; pScrni->PointerMoved = GeodePointerMoved; - pGeode->CreateScreenResources = pScrn->CreateScreenResources; - pScrn->CreateScreenResources = LXCreateScreenResources; pGeode->CloseScreen = pScrn->CloseScreen; pScrn->CloseScreen = LXCloseScreen; pScrn->SaveScreen = LXSaveScreen; + if (!xf86CrtcScreenInit(pScrn)) { + xf86DrvMsg(scrnIndex, X_ERROR, "CRTCScreenInit failed.\n"); + return FALSE; + } + if (serverGeneration == 1) xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); diff --git a/src/lx_exa.c b/src/lx_exa.c index e686cec..c85b322 100644 --- a/src/lx_exa.c +++ b/src/lx_exa.c @@ -43,6 +43,9 @@ #include "geode_blend.h" +#define F(x) IntToxFixed(x) +#define I(x) xFixedToInt(x) + static const struct exa_format_t { int exa; @@ -68,6 +71,7 @@ static const struct exa_format_t #define COMP_TYPE_MASK 0 #define COMP_TYPE_ONEPASS 1 #define COMP_TYPE_TWOPASS 3 +#define COMP_TYPE_ROTATE 5 static struct { @@ -86,6 +90,10 @@ static struct unsigned int bufferOffset; struct exa_format_t *srcFormat; struct exa_format_t *dstFormat; + + int rotate; + PictTransform *transform; + } exaScratch; static const int SDfn[16] = { @@ -346,8 +354,8 @@ lx_do_copy(PixmapPtr pxDst, int srcX, int srcY, srcOffset = exaScratch.srcOffset + (exaScratch.srcPitch * srcY) + (exaScratch.srcBpp) * srcX; - dstOffset = exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + - (dstBpp * dstX); + dstOffset = exaGetPixmapOffset(pxDst) + + (dstPitch * dstY) + (dstBpp * dstX); flags = 0; @@ -462,19 +470,71 @@ lx_get_format(PicturePtr p) return (&lx_exa_formats[i]); } -#if 0 - ErrorF("Couldn't match on format %x\n", format); - ErrorF("BPP = %d, type = %d, ARGB(%d,%d,%d,%d)n", - PICT_FORMAT_BPP(format), - PICT_FORMAT_TYPE(format), - PICT_FORMAT_A(format), - PICT_FORMAT_R(format), PICT_FORMAT_G(format), PICT_FORMAT_B(format)); -#endif - return NULL; } static Bool +lx_process_transform(PicturePtr pSrc) +{ + PictTransformPtr t = pSrc->transform; + xFixed c0 = t->matrix[0][0]; + xFixed s0 = t->matrix[0][1]; + xFixed s1 = t->matrix[1][0]; + xFixed c1 = t->matrix[1][1]; + + /* If the transform doesn't have any rotation + * or scaling components, then just grab the + * translate coordinates */ + + if (t->matrix[0][0] == 0 && + t->matrix[0][1] == 0 && + t->matrix[1][0] == 0 && t->matrix[1][1] == 0) { + exaScratch.transform = pSrc->transform; + return TRUE; + } + + /* Otherwise, see if this is a simple + * rotate transform - if it isn't, then + * we have to punt back to software */ + + if (t->matrix[2][2] != F(1)) + return FALSE; + + /* The rotate matrix looks like this: + * [ cos X -sin x + * sin X cos X ] + * + * Where X is the angle. We do a simple + * check first - if [0,0] != [1,1], then + * scaling was specified too, and we can + * bail, and if [0,1] != -[1,1] then this + * isn't scaling that we can handle. + */ + + if ((c0 != c1) || (s0 != -s1)) + return FALSE; + + /* Now, figure out what angle we want - we + * can only accelerate right angle rotations, + * so this turns into an easy set of if statements */ + + if (c0 == F(1) && s1 == F(0)) + exaScratch.rotate = RR_Rotate_0; + else if (c0 == F(0) && s1 == F(1)) + exaScratch.rotate = RR_Rotate_90; + else if (c0 == F(-1) && s1 == F(0)) + exaScratch.rotate = RR_Rotate_180; + else if (c0 == F(0) && s1 == F(-1)) + exaScratch.rotate = RR_Rotate_270; + else + return FALSE; + + exaScratch.transform = pSrc->transform; + + return TRUE; +} + +static Bool lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst) { GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst); @@ -503,9 +563,13 @@ lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst) return FALSE; } - /* We don't handle transforms */ + /* Keep an eye out for rotation transforms - those we can + * do something about */ + + exaScratch.rotate = RR_Rotate_0; + exaScratch.transform = NULL; - if (pSrc->transform) + if (pSrc->transform && !lx_process_transform(pSrc)) return FALSE; /* XXX - I don't understand PICT_a8 enough - so I'm punting */ @@ -550,8 +614,18 @@ lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk, /* FIXME: See a way around this! */ - if (srcFmt->alphabits == 0 && dstFmt->alphabits != 0) + if (srcFmt->alphabits == 0 && dstFmt->alphabits != 0) { + ErrorF("EXA: no src alpha bits\n"); + return FALSE; + } + + /* If this is a rotate operation, then make sure the src and dst + * formats are the same */ + + if (exaScratch.rotate != RR_Rotate_0 && srcFmt != dstFmt) { + ErrorF("EXA: Can't rotate and convert formats at the same time\n"); return FALSE; + } /* Set up the scratch buffer with the information we need */ @@ -613,6 +687,8 @@ lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk, } else { if (usesPasses(op)) exaScratch.type = COMP_TYPE_TWOPASS; + else if (exaScratch.rotate != RR_Rotate_0) + exaScratch.type = COMP_TYPE_ROTATE; else exaScratch.type = COMP_TYPE_ONEPASS; @@ -686,8 +762,6 @@ get_op_type(struct exa_format_t *src, struct exa_format_t *dst, int type) * ifdefed out until such time that we are sure its not needed */ -#if 1 - static void lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset, unsigned long srcOffset, int width, int height) @@ -716,99 +790,6 @@ lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset, gp_screen_to_screen_convert(dstOffset, srcOffset, width, height, 0); } -#else - -/* XXX - For now, we assume that the conversion will fit */ - -static void -lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset, - unsigned long srcOffset, int width, int height) -{ - struct blend_ops_t *opPtr; - int apply, type; - int sbpp = lx_get_bpp_from_format(exaScratch.srcFormat->fmt); - - /* Copy the destination into the scratch buffer */ - - gp_declare_blt(0); - - gp_set_bpp(sbpp); - - gp_set_source_format(exaScratch.dstFormat->fmt); - - gp_set_raster_operation(0xCC); - gp_set_strides(exaScratch.srcPitch, exaGetPixmapPitch(pxDst)); - gp_screen_to_screen_convert(exaScratch.bufferOffset, dstOffset, width, - height, 0); - - /* Do the blend */ - - opPtr = &lx_alpha_ops[exaScratch.op * 2]; - apply = (exaScratch.srcFormat->alphabits == 0) ? - CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL; - - gp_declare_blt(0); - gp_set_bpp(sbpp); - - type = - get_op_type(exaScratch.srcFormat, exaScrach.dstFormat, opPtr->type); - - gp_set_alpha_operation(opPtr->operation, type, opPtr->channel, apply, 0); - - gp_set_strides(exaScratch.srcPitch, exaScratch.srcPitch); - gp_screen_to_screen_blt(exaScratch.bufferOffset, srcOffset, - width, height, 0); - - /* And copy back */ - - gp_declare_blt(0); - gp_set_bpp(pxDst->drawable.bitsPerPixel); - gp_set_source_format(exaScratch.srcFormat->fmt); - gp_set_raster_operation(0xCC); - gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch); - gp_screen_to_screen_convert(dstOffset, exaScratch.bufferOffset, - width, height, 0); -} - -#endif - -#if 0 - -lx_composite_convert(PixmapPtr pxDst, unsigned long dstOffset, - unsigned long srcOffset, int width, int height) -{ - /* Step 1 - copy the destination into the scratch buffer */ - - gp_declare_blt(0); - gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); - - gp_set_raster_operation(0xCC); - gp_set_strides(exaGetPixmapPitch(pxDst), exaGetPixmapPitch(pxDst)); - - gp_screen_to_screen_blt(exaScratch.bufferOffset, dstOffset, width, height, - 0); - - /* Step 2 - Do the original blend */ - - lx_composite_onepass(pxDst, exaScratch.bufferOffset, srcOffset, width, - height); - - /* Step 3 - copy back and fixup the alpha */ - gp_declare_blt(0); - gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); - gp_set_strides(exaGetPixmapPitch(pxDst), exaGetPixmapPitch(pxDst)); - - /* FIXME: Does this alpha value need to be changed for the mode? */ - - gp_set_alpha_operation(CIMGP_ALPHA_TIMES_A, CIMGP_CONSTANT_ALPHA, - CIMGP_CHANNEL_A_SOURCE, CIMGP_APPLY_BLEND_TO_ALPHA, 1); - - gp_screen_to_screen_blt(dstOffset, exaScratch.bufferOffset, width, height, - 0); -} - -#endif - /* This function handles the multipass blend functions */ static void @@ -878,6 +859,41 @@ lx_composite_multipass(PixmapPtr pxDst, unsigned long dstOffset, } static void +lx_composite_rotate(PixmapPtr pxDst, unsigned long dstOffset, + unsigned int srcOffset, int width, int height) +{ + int degrees = 0; + + gp_wait_until_idle(); + + gp_declare_blt(0); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch); + + lx_set_source_format(exaScratch.srcFormat->fmt, + exaScratch.dstFormat->fmt); + + gp_set_raster_operation(0xCC); + + /* RandR rotation is counter-clockwise, our rotation + * is clockwise, so adjust the numbers accordingly */ + + switch (exaScratch.rotate) { + case RR_Rotate_90: + degrees = 270; + break; + case RR_Rotate_180: + degrees = 180; + break; + case RR_Rotate_270: + degrees = 90; + break; + } + + gp_rotate_blt(dstOffset, srcOffset, width, height, degrees); +} + +static void lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset, unsigned int maskOffset, int width, int height) { @@ -902,29 +918,87 @@ static void lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height) { - struct blend_ops_t *opPtr = &lx_alpha_ops[exaScratch.op * 2]; - unsigned int dstOffset, srcOffset; + unsigned int dstOffset, srcOffset = 0; unsigned int opX = dstX; unsigned int opY = dstY; unsigned int opWidth = width; unsigned int opHeight = height; + unsigned int sX = srcX; + unsigned int sY = srcY; + + /* Transform the source coordinates */ + + /* srcX, srcY point to the upper right side of the bounding box + * in the unrotated coordinate space. Depending on the orientation, + * we have to translate the coordinates to point to the origin of + * the rectangle in the source pixmap */ + + if (exaScratch.transform) { + + switch (exaScratch.rotate) { + case RR_Rotate_270: + /* srcX,srcY starts at the lower right side of the original rect */ + srcX += width; + break; + + case RR_Rotate_180: + + /* srcX,srcY starts at the lower left side of the original rect */ + srcX += width; + srcY += height; + break; + + case RR_Rotate_90: + srcY += height; + break; + } + + /* Now, transform the unrotated coordinates to the original rect in the + * src pixmap */ + + sX = (I(exaScratch.transform->matrix[0][0]) * srcX) + + (I(exaScratch.transform->matrix[0][1]) * srcY) + + (I(exaScratch.transform->matrix[0][2]) * 1); + + sY = (I(exaScratch.transform->matrix[1][0]) * srcX) + + (I(exaScratch.transform->matrix[1][1]) * srcY) + + (I(exaScratch.transform->matrix[1][2]) * 1); + } + + /* If we are rotated, flip the operational width and the height */ + + if (exaScratch.rotate == RR_Rotate_90 + || exaScratch.rotate == RR_Rotate_270) { + opWidth = height; + opHeight = width; + } + + /* Make sure the source is in bounds */ + + if (sX < 0) { + opWidth += sX; + sX = 0; + } + if (sY < 0) { + opHeight += sY; + sY = 0; + } + if (exaScratch.type == COMP_TYPE_MASK) srcOffset = exaScratch.srcOffset + (maskY * exaScratch.srcPitch) + (maskX * exaScratch.srcBpp); else - srcOffset = exaScratch.srcOffset + (srcY * exaScratch.srcPitch) + - (srcX * exaScratch.srcBpp); + srcOffset = exaScratch.srcOffset + (sY * exaScratch.srcPitch) + + (sX * exaScratch.srcBpp); - /* Adjust the width / height of the operation the size of the source */ - - if (exaScratch.srcWidth < width) + if (exaScratch.srcWidth < opWidth) opWidth = exaScratch.srcWidth; - if (exaScratch.srcHeight < height) + if (exaScratch.srcHeight < opHeight) opHeight = exaScratch.srcHeight; while (1) { @@ -955,6 +1029,10 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, case COMP_TYPE_TWOPASS: lx_composite_multipass(pxDst, dstOffset, srcOffset, opWidth, opHeight); + + case COMP_TYPE_ROTATE: + lx_composite_rotate(pxDst, dstOffset, srcOffset, opWidth, + opHeight); break; } @@ -989,6 +1067,27 @@ lx_done(PixmapPtr ptr) { } +#if EXA_VERSION_MINOR >= 2 + +static Bool +lx_exa_pixmap_is_offscreen(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrni = xf86Screens[pPixmap->drawable.pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + void *start = (void *)(pGeode->FBBase); + void *end = + (void *)(pGeode->FBBase + pGeode->offscreenStart + + pGeode->offscreenSize); + + if ((void *)pPixmap->devPrivate.ptr >= start && + (void *)pPixmap->devPrivate.ptr < end) + return TRUE; + + return FALSE; +} + +#endif + Bool LXExaInit(ScreenPtr pScreen) { @@ -1015,5 +1114,9 @@ LXExaInit(ScreenPtr pScreen) pExa->Composite = lx_do_composite; pExa->DoneComposite = lx_done; +#if EXA_VERSION_MINOR >= 2 + pExa->PixmapIsOffscreen = lx_exa_pixmap_is_offscreen; +#endif + return exaDriverInit(pScreen, pGeode->pExa); } diff --git a/src/lx_memory.c b/src/lx_memory.c index 5056ba5..9c4620f 100644 --- a/src/lx_memory.c +++ b/src/lx_memory.c @@ -37,6 +37,20 @@ provides a semi-robust mechanism for doing that. */ +/* Return the number of free bytes */ + +unsigned int +GeodeOffscreenFreeSize(GeodeRec * pGeode) +{ + GeodeMemPtr ptr = pGeode->offscreenList; + + if (ptr == NULL) + return pGeode->offscreenSize; + + for (; ptr->next; ptr = ptr->next) ; + return pGeode->offscreenSize - (ptr->offset + ptr->size); +} + void GeodeFreeOffscreen(GeodeRec * pGeode, GeodeMemPtr ptr) { @@ -152,6 +166,8 @@ GeodeAllocOffscreen(GeodeRec * pGeode, int size, int align) the usual suspects that need offscreen memory */ +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + void LXInitOffscreen(ScrnInfoPtr pScrni) { @@ -162,7 +178,8 @@ LXInitOffscreen(ScrnInfoPtr pScrni) /* The scratch buffer is always used */ fbavail = pGeode->FBAvail - GP3_SCRATCH_BUFFER_SIZE; - pGeode->displaySize = pScrni->virtualY * pGeode->Pitch; + pGeode->displaySize = MAX(pScrni->virtualX, pScrni->virtualY) + * pGeode->Pitch; pGeode->offscreenStart = pGeode->displaySize; pGeode->offscreenSize = fbavail - pGeode->displaySize; @@ -171,7 +188,8 @@ LXInitOffscreen(ScrnInfoPtr pScrni) if (pGeode->tryCompression) { int size = pScrni->virtualY * LX_CB_PITCH; - ptr = GeodeAllocOffscreen(pGeode, size, 4); + /* The compression buffer needs to be 16 byte aligned */ + ptr = GeodeAllocOffscreen(pGeode, size, 16); if (ptr != NULL) { pGeode->CBData.compression_offset = ptr->offset; @@ -232,11 +250,31 @@ LXInitOffscreen(ScrnInfoPtr pScrni) ptr = GeodeAllocRemainder(pGeode); } - if (ptr) { + if (ptr != NULL) { pGeode->pExa->offScreenBase = ptr->offset; pGeode->pExa->memorySize = ptr->offset + ptr->size; } } + + /* Show the memory map for diagnostic purposes */ + + xf86DrvMsg(pScrni->scrnIndex, X_INFO, "LX video memory:\n"); + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " Display: 0x%x bytes\n", + pGeode->displaySize); + + if (pGeode->Compression) + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " Compression: 0x%x bytes\n", + pScrni->virtualY * LX_CB_PITCH); + + if (pGeode->HWCursor) + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " Cursor: 0x400 bytes\n"); + + if (pGeode->pExa->offScreenBase) + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " EXA: 0x%x bytes\n", + pGeode->pExa->memorySize - pGeode->pExa->offScreenBase); + + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " FREE: 0x%x bytes\n", + GeodeOffscreenFreeSize(pGeode)); } /* Called as we go down, so blitz everybody */ diff --git a/src/lx_output.c b/src/lx_output.c index e0c3c78..53a538a 100644 --- a/src/lx_output.c +++ b/src/lx_output.c @@ -213,8 +213,7 @@ lx_output_get_modes(xf86OutputPtr output) xf86OutputSetEDID(output, mon); modes = xf86OutputGetEDIDModes(output); } else { - modes = pGeode->panelMode; - modes->next = NULL; + modes = xf86DuplicateMode(pGeode->panelMode); } return modes; @@ -251,13 +250,12 @@ LXSetupOutput(ScrnInfoPtr pScrni) xf86OutputPtr output; LXOutputPrivatePtr lxpriv; - output = xf86OutputCreate(pScrni, &lx_output_funcs, "Default"); + output = xf86OutputCreate(pScrni, &lx_output_funcs, "default"); lxpriv = xnfcalloc(1, sizeof(LXOutputPrivateRec)); if (!lxpriv) { xf86OutputDestroy(output); - ErrorF("ERROR - Unable to create the output\n"); return; } diff --git a/src/lx_panel.c b/src/lx_panel.c index 6387a34..3a0e363 100644 --- a/src/lx_panel.c +++ b/src/lx_panel.c @@ -91,6 +91,7 @@ LXGetLegacyPanelMode(void) if (ret < 7) return &lx_panel_modes[ret]; + } return NULL; @@ -135,5 +136,7 @@ LXGetManualPanelMode(char *modestr) mode->VSyncEnd = vsend; mode->VTotal = vtotal; + mode->prev = mode->next = NULL; + return mode; } diff --git a/src/lx_video.c b/src/lx_video.c index c31ac02..8bdb006 100644 --- a/src/lx_video.c +++ b/src/lx_video.c @@ -870,7 +870,7 @@ LXFreeSurface(XF86SurfacePtr surface) LXStopSurface(surface); if (pPriv->vidmem) { - GeodeFreeOffscren(pGeode, pPriv->vidmem); + GeodeFreeOffscreen(pGeode, pPriv->vidmem); pPriv->vidmem = NULL; } |