summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Crouse <jordan.crouse@amd.com>2008-08-18 14:19:34 -0600
committerJordan Crouse <jordan.crouse@amd.com>2008-08-18 14:19:34 -0600
commit38e868271bd24be7a884c8c56772b25cd6fa6f1d (patch)
treedfc6f8ab0e7f2c6c641d0bdb68cdaef5fa522b42
parentd681a844e448712a9a419d2a4dca81930d39a80a (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.h1
-rw-r--r--src/lx_cursor.c83
-rw-r--r--src/lx_display.c27
-rw-r--r--src/lx_driver.c20
-rw-r--r--src/lx_exa.c337
-rw-r--r--src/lx_memory.c44
-rw-r--r--src/lx_output.c6
-rw-r--r--src/lx_panel.c3
-rw-r--r--src/lx_video.c2
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;
}