If fakexa is enabled, create a larger buffer in the Ximage, but keep the

same width/height for front-buffer drawing. The fakexa code then uses
    this extra space for offscreen pixmaps. Note that this tones down the
    absurdity of fakexa's offscreen pixmap alignment requirements (odd
    alignment is too weird, so stick with "24", which is still strange but
    exists out there). It also fixes a couple of bugs in the fakexa
    implementation revealed by using offscreen pixmaps.
This commit is contained in:
Eric Anholt 2006-03-10 21:36:24 +00:00
parent 5b1a7b478f
commit d695579848
5 changed files with 51 additions and 36 deletions

View File

@ -1,3 +1,18 @@
2006-03-10 Eric Anholt <anholt@FreeBSD.org>
* hw/kdrive/ephyr/ephyr.c: (ephyrMapFramebuffer):
* hw/kdrive/ephyr/ephyr_draw.c: (ephyrPrepareComposite),
(ephyrDrawInit):
* hw/kdrive/ephyr/hostx.c: (hostx_screen_init):
* hw/kdrive/ephyr/hostx.h:
If fakexa is enabled, create a larger buffer in the Ximage, but keep
the same width/height for front-buffer drawing. The fakexa code then
uses this extra space for offscreen pixmaps. Note that this tones down
the absurdity of fakexa's offscreen pixmap alignment requirements (odd
alignment is too weird, so stick with "24", which is still strange but
exists out there). It also fixes a couple of bugs in the fakexa
implementation revealed by using offscreen pixmaps.
2006-03-10 Eric Anholt <anholt@FreeBSD.org>
* exa/exa.c: (exaPrepareAccess), (exaFinishAccess):

View File

@ -199,6 +199,7 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
EphyrScrPriv *scrpriv = screen->driver;
EphyrPriv *priv = screen->card->driver;
KdMouseMatrix m;
int buffer_height;
EPHYR_DBG(" screen->width: %d, screen->height: %d",
screen->width, screen->height);
@ -210,11 +211,19 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
priv->bytes_per_line = ((screen->width * screen->fb[0].bitsPerPixel + 31) >> 5) << 2;
/* point the framebuffer to the data in an XImage */
priv->base = hostx_screen_init (screen->width, screen->height);
/* If fakexa is enabled, allocate a larger buffer so that fakexa has space to
* put offscreen pixmaps.
*/
if (ephyrFuncs.initAccel == NULL)
buffer_height = screen->height;
else
buffer_height = 3 * screen->height;
priv->base = hostx_screen_init (screen->width, screen->height, buffer_height);
screen->memory_base = (CARD8 *) (priv->base);
screen->memory_size = 0;
screen->off_screen_base = 0;
screen->memory_size = priv->bytes_per_line * buffer_height;
screen->off_screen_base = priv->bytes_per_line * screen->height;
if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All))
{
@ -223,7 +232,6 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
screen->fb[0].byteStride = priv->bytes_per_line;
screen->fb[0].pixelStride = screen->width;
screen->fb[0].frameBuffer = (CARD8 *) (priv->base);
screen->off_screen_base = priv->bytes_per_line * screen->height;
}
else
{

View File

@ -42,8 +42,8 @@
#endif
/* Use some oddball alignments, to expose issues in alignment handling in EXA. */
#define EPHYR_OFFSET_ALIGN 11
#define EPHYR_PITCH_ALIGN 9
#define EPHYR_OFFSET_ALIGN 24
#define EPHYR_PITCH_ALIGN 24
#define EPHYR_OFFSCREEN_SIZE (16 * 1024 * 1024)
#define EPHYR_OFFSCREEN_BASE (1 * 1024 * 1024)
@ -194,7 +194,7 @@ ephyrPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
EphyrScrPriv *scrpriv = screen->driver;
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
op = op;
fakexa->op = op;
fakexa->pSrcPicture = pSrcPicture;
fakexa->pMaskPicture = pMaskPicture;
fakexa->pDstPicture = pDstPicture;
@ -286,30 +286,10 @@ ephyrDrawInit(ScreenPtr pScreen)
xfree(fakexa);
return FALSE;
}
#if 0
/* Currently, EXA isn't ready for what we want to do here. We want one
* pointer to the framebuffer (which is set in exaMapFramebuffer) to be
* considered "in framebuffer", and a separate pointer to offscreen memory,
* which is also considered to be in framebuffer. The alternative would be
* to extend the XImage data area set up in hostx.c from exaMapFramebuffer,
* but that may be complicated.
*/
fakexa->exa->memoryBase = xalloc(EPHYR_OFFSCREEN_SIZE);
if (fakexa->exa->memoryBase == NULL) {
xfree(fakexa->exa);
xfree(fakexa);
return FALSE;
}
fakexa->exa->memorySize = EPHYR_OFFSCREEN_SIZE;
fakexa->exa->offScreenBase = EPHYR_OFFSCREEN_BASE;
#else
/* Tell EXA that there's a single framebuffer area, which happens to cover
* exactly what the front buffer is.
*/
fakexa->exa->memoryBase = screen->memory_base;
fakexa->exa->memorySize = screen->off_screen_base;
fakexa->exa->memorySize = screen->memory_size;
fakexa->exa->offScreenBase = screen->off_screen_base;
#endif
/* Since we statically link against EXA, we shouldn't have to be smart about
* versioning.

View File

@ -438,8 +438,20 @@ hostx_set_cmap_entry(unsigned char idx,
HostX.cmap[idx] = (r << 16) | (g << 8) | (b);
}
/**
* hostx_screen_init creates the XImage that will contain the front buffer of
* the ephyr screen, and possibly offscreen memory.
*
* @param width width of the screen
* @param height height of the screen
* @param buffer_height height of the rectangle to be allocated.
*
* hostx_screen_init() creates an XImage, using MIT-SHM if it's available.
* buffer_height can be used to create a larger offscreen buffer, which is used
* by fakexa for storing offscreen pixmap data.
*/
void*
hostx_screen_init (int width, int height)
hostx_screen_init (int width, int height, int buffer_height)
{
int bitmap_pad;
Bool shm_success = False;
@ -476,10 +488,10 @@ hostx_screen_init (int width, int height)
{
HostX.ximg = XShmCreateImage(HostX.dpy, HostX.visual, HostX.depth,
ZPixmap, NULL, &HostX.shminfo,
width, height );
width, buffer_height );
HostX.shminfo.shmid = shmget(IPC_PRIVATE,
HostX.ximg->bytes_per_line * height,
HostX.ximg->bytes_per_line * buffer_height,
IPC_CREAT|0777);
HostX.shminfo.shmaddr = HostX.ximg->data = shmat(HostX.shminfo.shmid,
0, 0);
@ -509,11 +521,11 @@ hostx_screen_init (int width, int height)
HostX.depth,
ZPixmap, 0, 0,
width,
height,
buffer_height,
bitmap_pad,
0);
HostX.ximg->data = malloc( HostX.ximg->bytes_per_line * height );
HostX.ximg->data = malloc( HostX.ximg->bytes_per_line * buffer_height );
}
@ -548,7 +560,7 @@ hostx_screen_init (int width, int height)
else
{
EPHYR_DBG("server bpp %i", HostX.server_depth>>3);
HostX.fb_data = malloc(width*height*(HostX.server_depth>>3));
HostX.fb_data = malloc(width*buffer_height*(HostX.server_depth>>3));
return HostX.fb_data;
}
}

View File

@ -136,7 +136,7 @@ hostx_set_cmap_entry(unsigned char idx,
unsigned char b);
void*
hostx_screen_init (int width, int height);
hostx_screen_init (int width, int height, int buffer_height);
void
hostx_paint_rect(int sx, int sy,