Add an option to EXA for the DDX to request that EXA hide the pixmap's
devPrivate.ptr when pointing at offscreen memory, outside of exaPrepare/FinishAccess(). This was used with fakexa to find (by NULL dereference) many instances of un-Prepared CPU access to the framebuffer: - GC tiles used in several ops when fillStyle == FillTiled were never Prepared. - Migration could lead to un-Prepared access to mask data in render's Trapezoids and Triangles - PutImage's UploadToScreen failure fallback failed to Prepare.
This commit is contained in:
parent
f480dc797b
commit
2e38fedd29
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
||||||
|
2006-03-31 Eric Anholt <anholt@FreeBSD.org>
|
||||||
|
|
||||||
|
* exa/exa.c: (exaGetPixmapOffset), (exaPixmapIsOffscreen),
|
||||||
|
(exaPrepareAccess), (exaFinishAccess), (exaDriverInit):
|
||||||
|
* exa/exa_accel.c: (exaPutImage):
|
||||||
|
* exa/exa_migration.c: (exaPixmapSave), (exaMoveInPixmap),
|
||||||
|
(exaMoveOutPixmap):
|
||||||
|
* exa/exa_priv.h:
|
||||||
|
* exa/exa_render.c: (exaRasterizeTrapezoid), (exaAddTriangles):
|
||||||
|
* exa/exa_unaccel.c: (exaPrepareAccessGC), (exaFinishAccessGC),
|
||||||
|
(ExaCheckFillSpans), (ExaCheckPolylines), (ExaCheckPolySegment),
|
||||||
|
(ExaCheckPolyArc), (ExaCheckPolyFillRect), (ExaCheckImageGlyphBlt),
|
||||||
|
(ExaCheckPolyGlyphBlt), (ExaCheckPushPixels):
|
||||||
|
* hw/kdrive/ephyr/ephyr.h:
|
||||||
|
* hw/kdrive/ephyr/ephyr_draw.c: (ephyrPreparePipelinedAccess),
|
||||||
|
(ephyrFinishPipelinedAccess), (ephyrPrepareSolid),
|
||||||
|
(ephyrDoneSolid), (ephyrPrepareCopy), (ephyrDoneCopy),
|
||||||
|
(ephyrPrepareComposite), (ephyrDoneComposite),
|
||||||
|
(ephyrDownloadFromScreen), (ephyrUploadToScreen),
|
||||||
|
(ephyrPrepareAccess), (ephyrDrawInit), (exaDDXDriverInit):
|
||||||
|
Add an option to EXA for the DDX to request that EXA hide the pixmap's
|
||||||
|
devPrivate.ptr when pointing at offscreen memory, outside of
|
||||||
|
exaPrepare/FinishAccess(). This was used with fakexa to find (by NULL
|
||||||
|
dereference) many instances of un-Prepared CPU access to the
|
||||||
|
framebuffer:
|
||||||
|
- GC tiles used in several ops when fillStyle == FillTiled were never
|
||||||
|
Prepared.
|
||||||
|
- Migration could lead to un-Prepared access to mask data in render's
|
||||||
|
Trapezoids and Triangles
|
||||||
|
- PutImage's UploadToScreen failure fallback failed to Prepare.
|
||||||
|
|
||||||
2006-03-31 Eric Anholt <anholt@FreeBSD.org>
|
2006-03-31 Eric Anholt <anholt@FreeBSD.org>
|
||||||
|
|
||||||
* exa/exa_offscreen.c: (ExaOffscreenValidate):
|
* exa/exa_offscreen.c: (ExaOffscreenValidate):
|
||||||
|
|
42
exa/exa.c
42
exa/exa.c
|
@ -58,9 +58,16 @@ unsigned long
|
||||||
exaGetPixmapOffset(PixmapPtr pPix)
|
exaGetPixmapOffset(PixmapPtr pPix)
|
||||||
{
|
{
|
||||||
ExaScreenPriv (pPix->drawable.pScreen);
|
ExaScreenPriv (pPix->drawable.pScreen);
|
||||||
|
ExaPixmapPriv (pPix);
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
return ((unsigned long)pPix->devPrivate.ptr -
|
/* Return the offscreen pointer if we've hidden the data. */
|
||||||
(unsigned long)pExaScr->info->memoryBase);
|
if (pPix->devPrivate.ptr == NULL)
|
||||||
|
ptr = pExaPixmap->fb_ptr;
|
||||||
|
else
|
||||||
|
ptr = pPix->devPrivate.ptr;
|
||||||
|
|
||||||
|
return ((unsigned long)ptr - (unsigned long)pExaScr->info->memoryBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -232,6 +239,11 @@ exaPixmapIsOffscreen(PixmapPtr p)
|
||||||
ScreenPtr pScreen = p->drawable.pScreen;
|
ScreenPtr pScreen = p->drawable.pScreen;
|
||||||
ExaScreenPriv(pScreen);
|
ExaScreenPriv(pScreen);
|
||||||
|
|
||||||
|
/* If the devPrivate.ptr is NULL, it's offscreen but we've hidden the data.
|
||||||
|
*/
|
||||||
|
if (p->devPrivate.ptr == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
|
return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
|
||||||
(CARD8 *) pExaScr->info->memoryBase) <
|
(CARD8 *) pExaScr->info->memoryBase) <
|
||||||
pExaScr->info->memorySize);
|
pExaScr->info->memorySize);
|
||||||
|
@ -301,6 +313,13 @@ exaPrepareAccess(DrawablePtr pDrawable, int index)
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Unhide pixmap pointer */
|
||||||
|
if (pPixmap->devPrivate.ptr == NULL) {
|
||||||
|
ExaPixmapPriv (pPixmap);
|
||||||
|
|
||||||
|
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (pExaScr->info->PrepareAccess == NULL)
|
if (pExaScr->info->PrepareAccess == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -324,14 +343,25 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
|
||||||
ScreenPtr pScreen = pDrawable->pScreen;
|
ScreenPtr pScreen = pDrawable->pScreen;
|
||||||
ExaScreenPriv (pScreen);
|
ExaScreenPriv (pScreen);
|
||||||
PixmapPtr pPixmap;
|
PixmapPtr pPixmap;
|
||||||
|
ExaPixmapPrivPtr pExaPixmap;
|
||||||
|
|
||||||
if (index == EXA_PREPARE_DEST)
|
if (index == EXA_PREPARE_DEST)
|
||||||
exaDrawableDirty (pDrawable);
|
exaDrawableDirty (pDrawable);
|
||||||
|
|
||||||
|
pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||||
|
|
||||||
|
pExaPixmap = ExaGetPixmapPriv(pPixmap);
|
||||||
|
|
||||||
|
/* Rehide pixmap pointer if we're doing that. */
|
||||||
|
if (pExaPixmap != NULL && pExaScr->hideOffscreenPixmapData &&
|
||||||
|
pExaPixmap->fb_ptr == pPixmap->devPrivate.ptr)
|
||||||
|
{
|
||||||
|
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (pExaScr->info->FinishAccess == NULL)
|
if (pExaScr->info->FinishAccess == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pPixmap = exaGetDrawablePixmap (pDrawable);
|
|
||||||
if (!exaPixmapIsOffscreen (pPixmap))
|
if (!exaPixmapIsOffscreen (pPixmap))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -508,6 +538,12 @@ exaDriverInit (ScreenPtr pScreen,
|
||||||
pExaScr->SavedComposite = ps->Composite;
|
pExaScr->SavedComposite = ps->Composite;
|
||||||
ps->Composite = exaComposite;
|
ps->Composite = exaComposite;
|
||||||
|
|
||||||
|
pExaScr->SavedRasterizeTrapezoid = ps->RasterizeTrapezoid;
|
||||||
|
ps->RasterizeTrapezoid = exaRasterizeTrapezoid;
|
||||||
|
|
||||||
|
pExaScr->SavedAddTriangles = ps->AddTriangles;
|
||||||
|
ps->AddTriangles = exaAddTriangles;
|
||||||
|
|
||||||
pExaScr->SavedGlyphs = ps->Glyphs;
|
pExaScr->SavedGlyphs = ps->Glyphs;
|
||||||
ps->Glyphs = exaGlyphs;
|
ps->Glyphs = exaGlyphs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,6 +165,9 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
||||||
if (pPix == NULL)
|
if (pPix == NULL)
|
||||||
goto fallback;
|
goto fallback;
|
||||||
|
|
||||||
|
x += pDrawable->x;
|
||||||
|
y += pDrawable->y;
|
||||||
|
|
||||||
pClip = fbGetCompositeClip(pGC);
|
pClip = fbGetCompositeClip(pGC);
|
||||||
src_stride = PixmapBytePad(w, pDrawable->depth);
|
src_stride = PixmapBytePad(w, pDrawable->depth);
|
||||||
for (nbox = REGION_NUM_RECTS(pClip),
|
for (nbox = REGION_NUM_RECTS(pClip),
|
||||||
|
@ -190,7 +193,7 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
||||||
if (x1 >= x2 || y1 >= y2)
|
if (x1 >= x2 || y1 >= y2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
src = bits + (y1 - y + yoff) * src_stride + (x1 - x + xoff) * (bpp / 8);
|
src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
|
||||||
ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
|
ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
|
||||||
x2 - x1, y2 - y1, src, src_stride);
|
x2 - x1, y2 - y1, src, src_stride);
|
||||||
/* If we fail to accelerate the upload, fall back to using unaccelerated
|
/* If we fail to accelerate the upload, fall back to using unaccelerated
|
||||||
|
@ -202,6 +205,8 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
||||||
int dstBpp;
|
int dstBpp;
|
||||||
int dstXoff, dstYoff;
|
int dstXoff, dstYoff;
|
||||||
|
|
||||||
|
exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
|
||||||
|
|
||||||
fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp,
|
fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp,
|
||||||
dstXoff, dstYoff);
|
dstXoff, dstYoff);
|
||||||
|
|
||||||
|
@ -214,6 +219,8 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
||||||
(x2 - x1) * bpp,
|
(x2 - x1) * bpp,
|
||||||
y2 - y1,
|
y2 - y1,
|
||||||
GXcopy, FB_ALLONES, bpp);
|
GXcopy, FB_ALLONES, bpp);
|
||||||
|
|
||||||
|
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@ exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
|
||||||
pPixmap->drawable.width,
|
pPixmap->drawable.width,
|
||||||
pPixmap->drawable.height));
|
pPixmap->drawable.height));
|
||||||
|
|
||||||
if (pPixmap->devPrivate.ptr == pExaPixmap->fb_ptr) {
|
if (exaPixmapIsOffscreen(pPixmap)) {
|
||||||
exaCopyDirtyToSys (pPixmap);
|
exaCopyDirtyToSys (pPixmap);
|
||||||
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
||||||
pPixmap->devKind = pExaPixmap->sys_pitch;
|
pPixmap->devKind = pExaPixmap->sys_pitch;
|
||||||
|
@ -233,7 +233,7 @@ exaMoveInPixmap (PixmapPtr pPixmap)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If we're already in FB, our work is done. */
|
/* If we're already in FB, our work is done. */
|
||||||
if (pPixmap->devPrivate.ptr == pExaPixmap->fb_ptr)
|
if (exaPixmapIsOffscreen(pPixmap))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If we're not allowed to move, then fail. */
|
/* If we're not allowed to move, then fail. */
|
||||||
|
@ -267,7 +267,10 @@ exaMoveInPixmap (PixmapPtr pPixmap)
|
||||||
|
|
||||||
exaCopyDirtyToFb (pPixmap);
|
exaCopyDirtyToFb (pPixmap);
|
||||||
|
|
||||||
pPixmap->devPrivate.ptr = (pointer) pExaPixmap->fb_ptr;
|
if (pExaScr->hideOffscreenPixmapData)
|
||||||
|
pPixmap->devPrivate.ptr = NULL;
|
||||||
|
else
|
||||||
|
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||||
pPixmap->devKind = pExaPixmap->fb_pitch;
|
pPixmap->devKind = pExaPixmap->fb_pitch;
|
||||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||||
}
|
}
|
||||||
|
@ -291,7 +294,7 @@ exaMoveOutPixmap (PixmapPtr pPixmap)
|
||||||
pPixmap->drawable.width,
|
pPixmap->drawable.width,
|
||||||
pPixmap->drawable.height));
|
pPixmap->drawable.height));
|
||||||
|
|
||||||
if (pPixmap->devPrivate.ptr == pExaPixmap->fb_ptr) {
|
if (exaPixmapIsOffscreen(pPixmap)) {
|
||||||
exaCopyDirtyToSys (pPixmap);
|
exaCopyDirtyToSys (pPixmap);
|
||||||
|
|
||||||
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
||||||
|
|
|
@ -100,10 +100,13 @@ typedef struct {
|
||||||
CopyWindowProcPtr SavedCopyWindow;
|
CopyWindowProcPtr SavedCopyWindow;
|
||||||
#ifdef RENDER
|
#ifdef RENDER
|
||||||
CompositeProcPtr SavedComposite;
|
CompositeProcPtr SavedComposite;
|
||||||
|
RasterizeTrapezoidProcPtr SavedRasterizeTrapezoid;
|
||||||
|
AddTrianglesProcPtr SavedAddTriangles;
|
||||||
GlyphsProcPtr SavedGlyphs;
|
GlyphsProcPtr SavedGlyphs;
|
||||||
#endif
|
#endif
|
||||||
Bool swappedOut;
|
Bool swappedOut;
|
||||||
enum ExaMigrationHeuristic migration;
|
enum ExaMigrationHeuristic migration;
|
||||||
|
Bool hideOffscreenPixmapData;
|
||||||
} ExaScreenPrivRec, *ExaScreenPrivPtr;
|
} ExaScreenPrivRec, *ExaScreenPrivPtr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -219,24 +222,14 @@ void
|
||||||
ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
|
ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
int nsegInit, xSegment *pSegInit);
|
int nsegInit, xSegment *pSegInit);
|
||||||
|
|
||||||
void
|
|
||||||
ExaCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
|
|
||||||
int nrects, xRectangle *prect);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
|
ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
int narcs, xArc *pArcs);
|
int narcs, xArc *pArcs);
|
||||||
|
|
||||||
#define ExaCheckFillPolygon miFillPolygon
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
|
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
int nrect, xRectangle *prect);
|
int nrect, xRectangle *prect);
|
||||||
|
|
||||||
void
|
|
||||||
ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
|
|
||||||
int narcs, xArc *pArcs);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
|
ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
int x, int y, unsigned int nglyph,
|
int x, int y, unsigned int nglyph,
|
||||||
|
@ -374,6 +367,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
|
||||||
Pixel bitplane,
|
Pixel bitplane,
|
||||||
void *closure);
|
void *closure);
|
||||||
|
|
||||||
|
/* exa_render.c */
|
||||||
void
|
void
|
||||||
exaComposite(CARD8 op,
|
exaComposite(CARD8 op,
|
||||||
PicturePtr pSrc,
|
PicturePtr pSrc,
|
||||||
|
@ -388,6 +382,14 @@ exaComposite(CARD8 op,
|
||||||
CARD16 width,
|
CARD16 width,
|
||||||
CARD16 height);
|
CARD16 height);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap,
|
||||||
|
int x_off, int y_off);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
|
||||||
|
xTriangle *tris);
|
||||||
|
|
||||||
void
|
void
|
||||||
exaGlyphs (CARD8 op,
|
exaGlyphs (CARD8 op,
|
||||||
PicturePtr pSrc,
|
PicturePtr pSrc,
|
||||||
|
|
|
@ -576,6 +576,49 @@ exaComposite(CARD8 op,
|
||||||
|
|
||||||
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
|
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* exaRasterizeTrapezoid is just a wrapper around the software implementation.
|
||||||
|
*
|
||||||
|
* The trapezoid specification is basically too hard to be done in hardware (at
|
||||||
|
* the very least, without programmability), so we just do the appropriate
|
||||||
|
* Prepare/FinishAccess for it before using fbtrap.c.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap,
|
||||||
|
int x_off, int y_off)
|
||||||
|
{
|
||||||
|
ExaMigrationRec pixmaps[1];
|
||||||
|
|
||||||
|
pixmaps[0].as_dst = TRUE;
|
||||||
|
pixmaps[0].as_src = TRUE;
|
||||||
|
pixmaps[0].pPix = exaGetDrawablePixmap (pPicture->pDrawable);
|
||||||
|
exaDoMigration(pixmaps, 1, FALSE);
|
||||||
|
|
||||||
|
exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
||||||
|
fbRasterizeTrapezoid(pPicture, trap, x_off, y_off);
|
||||||
|
exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* exaAddTriangles does migration and syncing before dumping down to the
|
||||||
|
* software implementation.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
|
||||||
|
xTriangle *tris)
|
||||||
|
{
|
||||||
|
ExaMigrationRec pixmaps[1];
|
||||||
|
|
||||||
|
pixmaps[0].as_dst = TRUE;
|
||||||
|
pixmaps[0].as_src = TRUE;
|
||||||
|
pixmaps[0].pPix = exaGetDrawablePixmap (pPicture->pDrawable);
|
||||||
|
exaDoMigration(pixmaps, 1, FALSE);
|
||||||
|
|
||||||
|
exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
||||||
|
fbAddTriangles(pPicture, x_off, y_off, ntri, tris);
|
||||||
|
exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
||||||
|
}
|
||||||
|
|
||||||
/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The
|
/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The
|
||||||
* issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
|
* issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
|
||||||
* migrate these pixmaps. So, instead we create a pixmap at the beginning of
|
* migrate these pixmaps. So, instead we create a pixmap at the beginning of
|
||||||
|
|
|
@ -29,13 +29,39 @@
|
||||||
* the accelerator is idle
|
* the accelerator is idle
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the
|
||||||
|
* current fill style.
|
||||||
|
*
|
||||||
|
* Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
|
||||||
|
* 1bpp and never in fb, so we don't worry about them.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
exaPrepareAccessGC(GCPtr pGC)
|
||||||
|
{
|
||||||
|
if (pGC->fillStyle == FillTiled)
|
||||||
|
exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes access to the tile in the GC, if used.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
exaFinishAccessGC(GCPtr pGC)
|
||||||
|
{
|
||||||
|
if (pGC->fillStyle == FillTiled)
|
||||||
|
exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
|
ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
|
||||||
DDXPointPtr ppt, int *pwidth, int fSorted)
|
DDXPointPtr ppt, int *pwidth, int fSorted)
|
||||||
{
|
{
|
||||||
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
|
exaPrepareAccessGC (pGC);
|
||||||
fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
|
fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
|
||||||
|
exaFinishAccessGC (pGC);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,10 +138,13 @@ ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
|
||||||
if (pGC->lineWidth == 0) {
|
if (pGC->lineWidth == 0) {
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
|
exaPrepareAccessGC (pGC);
|
||||||
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
|
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
|
||||||
|
exaFinishAccessGC (pGC);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* fb calls mi functions in the lineWidth != 0 case. */
|
||||||
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
|
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,27 +155,16 @@ ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
||||||
if (pGC->lineWidth == 0) {
|
if (pGC->lineWidth == 0) {
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
|
exaPrepareAccessGC (pGC);
|
||||||
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
|
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
|
||||||
|
exaFinishAccessGC (pGC);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* fb calls mi functions in the lineWidth != 0 case. */
|
||||||
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
|
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ExaCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
|
|
||||||
int nrects, xRectangle *prect)
|
|
||||||
{
|
|
||||||
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
|
||||||
if (pGC->lineWidth == 0) {
|
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
|
||||||
fbPolyRectangle (pDrawable, pGC, nrects, prect);
|
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fbPolyRectangle (pDrawable, pGC, nrects, prect);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
|
ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
int narcs, xArc *pArcs)
|
int narcs, xArc *pArcs)
|
||||||
|
@ -155,42 +173,24 @@ ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
if (pGC->lineWidth == 0)
|
if (pGC->lineWidth == 0)
|
||||||
{
|
{
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
|
exaPrepareAccessGC (pGC);
|
||||||
fbPolyArc (pDrawable, pGC, narcs, pArcs);
|
fbPolyArc (pDrawable, pGC, narcs, pArcs);
|
||||||
|
exaFinishAccessGC (pGC);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
miPolyArc (pDrawable, pGC, narcs, pArcs);
|
miPolyArc (pDrawable, pGC, narcs, pArcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void
|
|
||||||
ExaCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC,
|
|
||||||
int shape, int mode, int count, DDXPointPtr pPts)
|
|
||||||
{
|
|
||||||
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
|
||||||
fbFillPolygon (pDrawable, pGC, mode, count, pPts);
|
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
|
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
int nrect, xRectangle *prect)
|
int nrect, xRectangle *prect)
|
||||||
{
|
{
|
||||||
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
|
exaPrepareAccessGC (pGC);
|
||||||
fbPolyFillRect (pDrawable, pGC, nrect, prect);
|
fbPolyFillRect (pDrawable, pGC, nrect, prect);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccessGC (pGC);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
|
|
||||||
int narcs, xArc *pArcs)
|
|
||||||
{
|
|
||||||
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
|
||||||
fbPolyFillArc (pDrawable, pGC, narcs, pArcs);
|
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +201,9 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
{
|
{
|
||||||
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
|
exaPrepareAccessGC (pGC);
|
||||||
fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
||||||
|
exaFinishAccessGC (pGC);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +214,9 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
{
|
{
|
||||||
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
|
exaPrepareAccessGC (pGC);
|
||||||
fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
||||||
|
exaFinishAccessGC (pGC);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +227,9 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
|
||||||
{
|
{
|
||||||
EXA_FALLBACK(("from 0x%lx to 0x%lx\n", (long)pBitmap, (long)pDrawable));
|
EXA_FALLBACK(("from 0x%lx to 0x%lx\n", (long)pBitmap, (long)pDrawable));
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
|
exaPrepareAccessGC (pGC);
|
||||||
fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
|
fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
|
||||||
|
exaFinishAccessGC (pGC);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,8 @@ typedef struct _ephyrFakexaPriv {
|
||||||
*/
|
*/
|
||||||
int op;
|
int op;
|
||||||
PicturePtr pSrcPicture, pMaskPicture, pDstPicture;
|
PicturePtr pSrcPicture, pMaskPicture, pDstPicture;
|
||||||
PixmapPtr pSrc, pDst;
|
void *saved_ptrs[3];
|
||||||
|
PixmapPtr pDst, pSrc, pMask;
|
||||||
GCPtr pGC;
|
GCPtr pGC;
|
||||||
} EphyrFakexaPriv;
|
} EphyrFakexaPriv;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <kdrive-config.h>
|
#include <kdrive-config.h>
|
||||||
#endif
|
#endif
|
||||||
|
#undef NDEBUG /* No, really. The whole point of this module is to crash. */
|
||||||
|
|
||||||
#include "ephyr.h"
|
#include "ephyr.h"
|
||||||
#include "exa_priv.h"
|
#include "exa_priv.h"
|
||||||
|
@ -48,6 +49,44 @@
|
||||||
#define EPHYR_OFFSCREEN_SIZE (16 * 1024 * 1024)
|
#define EPHYR_OFFSCREEN_SIZE (16 * 1024 * 1024)
|
||||||
#define EPHYR_OFFSCREEN_BASE (1 * 1024 * 1024)
|
#define EPHYR_OFFSCREEN_BASE (1 * 1024 * 1024)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces a real devPrivate.ptr for hidden pixmaps, so that we can call down to
|
||||||
|
* fb functions.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ephyrPreparePipelinedAccess(PixmapPtr pPix, int index)
|
||||||
|
{
|
||||||
|
KdScreenPriv(pPix->drawable.pScreen);
|
||||||
|
KdScreenInfo *screen = pScreenPriv->screen;
|
||||||
|
EphyrScrPriv *scrpriv = screen->driver;
|
||||||
|
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
||||||
|
|
||||||
|
assert(fakexa->saved_ptrs[index] == NULL);
|
||||||
|
fakexa->saved_ptrs[index] = pPix->devPrivate.ptr;
|
||||||
|
|
||||||
|
if (pPix->devPrivate.ptr != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pPix->devPrivate.ptr = fakexa->exa->memoryBase + exaGetPixmapOffset(pPix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the original devPrivate.ptr of the pixmap from before we messed with
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ephyrFinishPipelinedAccess(PixmapPtr pPix, int index)
|
||||||
|
{
|
||||||
|
KdScreenPriv(pPix->drawable.pScreen);
|
||||||
|
KdScreenInfo *screen = pScreenPriv->screen;
|
||||||
|
EphyrScrPriv *scrpriv = screen->driver;
|
||||||
|
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
||||||
|
void *offscreen_begin, *offscreen_end;
|
||||||
|
|
||||||
|
pPix->devPrivate.ptr = fakexa->saved_ptrs[index];
|
||||||
|
fakexa->saved_ptrs[index] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up a scratch GC for fbFill, and saves other parameters for the
|
* Sets up a scratch GC for fbFill, and saves other parameters for the
|
||||||
* ephyrSolid implementation.
|
* ephyrSolid implementation.
|
||||||
|
@ -62,6 +101,8 @@ ephyrPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
|
||||||
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
||||||
CARD32 tmpval[3];
|
CARD32 tmpval[3];
|
||||||
|
|
||||||
|
ephyrPreparePipelinedAccess(pPix, EXA_PREPARE_DEST);
|
||||||
|
|
||||||
fakexa->pDst = pPix;
|
fakexa->pDst = pPix;
|
||||||
fakexa->pGC = GetScratchGC(pPix->drawable.depth, pScreen);
|
fakexa->pGC = GetScratchGC(pPix->drawable.depth, pScreen);
|
||||||
|
|
||||||
|
@ -106,6 +147,8 @@ ephyrDoneSolid(PixmapPtr pPix)
|
||||||
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
||||||
|
|
||||||
FreeScratchGC(fakexa->pGC);
|
FreeScratchGC(fakexa->pGC);
|
||||||
|
|
||||||
|
ephyrFinishPipelinedAccess(pPix, EXA_PREPARE_DEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,6 +166,9 @@ ephyrPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu,
|
||||||
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
||||||
CARD32 tmpval[2];
|
CARD32 tmpval[2];
|
||||||
|
|
||||||
|
ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
|
||||||
|
ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
|
||||||
|
|
||||||
fakexa->pSrc = pSrc;
|
fakexa->pSrc = pSrc;
|
||||||
fakexa->pDst = pDst;
|
fakexa->pDst = pDst;
|
||||||
fakexa->pGC = GetScratchGC(pDst->drawable.depth, pScreen);
|
fakexa->pGC = GetScratchGC(pDst->drawable.depth, pScreen);
|
||||||
|
@ -167,6 +213,9 @@ ephyrDoneCopy(PixmapPtr pDst)
|
||||||
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
||||||
|
|
||||||
FreeScratchGC (fakexa->pGC);
|
FreeScratchGC (fakexa->pGC);
|
||||||
|
|
||||||
|
ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC);
|
||||||
|
ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,10 +243,18 @@ ephyrPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
|
||||||
EphyrScrPriv *scrpriv = screen->driver;
|
EphyrScrPriv *scrpriv = screen->driver;
|
||||||
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
||||||
|
|
||||||
|
ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
|
||||||
|
ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
|
||||||
|
if (pMask != NULL)
|
||||||
|
ephyrPreparePipelinedAccess(pMask, EXA_PREPARE_MASK);
|
||||||
|
|
||||||
fakexa->op = op;
|
fakexa->op = op;
|
||||||
fakexa->pSrcPicture = pSrcPicture;
|
fakexa->pSrcPicture = pSrcPicture;
|
||||||
fakexa->pMaskPicture = pMaskPicture;
|
fakexa->pMaskPicture = pMaskPicture;
|
||||||
fakexa->pDstPicture = pDstPicture;
|
fakexa->pDstPicture = pDstPicture;
|
||||||
|
fakexa->pSrc = pSrc;
|
||||||
|
fakexa->pMask = pMask;
|
||||||
|
fakexa->pDst = pDst;
|
||||||
|
|
||||||
TRACE_DRAW();
|
TRACE_DRAW();
|
||||||
|
|
||||||
|
@ -224,6 +281,15 @@ ephyrComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
|
||||||
static void
|
static void
|
||||||
ephyrDoneComposite(PixmapPtr pDst)
|
ephyrDoneComposite(PixmapPtr pDst)
|
||||||
{
|
{
|
||||||
|
KdScreenPriv(pDst->drawable.pScreen);
|
||||||
|
KdScreenInfo *screen = pScreenPriv->screen;
|
||||||
|
EphyrScrPriv *scrpriv = screen->driver;
|
||||||
|
EphyrFakexaPriv *fakexa = scrpriv->fakexa;
|
||||||
|
|
||||||
|
if (fakexa->pMask != NULL)
|
||||||
|
ephyrFinishPipelinedAccess(fakexa->pMask, EXA_PREPARE_MASK);
|
||||||
|
ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC);
|
||||||
|
ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,6 +309,8 @@ ephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst,
|
||||||
if (pSrc->drawable.bitsPerPixel < 8)
|
if (pSrc->drawable.bitsPerPixel < 8)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
|
||||||
|
|
||||||
cpp = pSrc->drawable.bitsPerPixel / 8;
|
cpp = pSrc->drawable.bitsPerPixel / 8;
|
||||||
src_pitch = exaGetPixmapPitch(pSrc);
|
src_pitch = exaGetPixmapPitch(pSrc);
|
||||||
src = fakexa->exa->memoryBase + exaGetPixmapOffset(pSrc);
|
src = fakexa->exa->memoryBase + exaGetPixmapOffset(pSrc);
|
||||||
|
@ -256,6 +324,8 @@ ephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst,
|
||||||
|
|
||||||
exaMarkSync(pSrc->drawable.pScreen);
|
exaMarkSync(pSrc->drawable.pScreen);
|
||||||
|
|
||||||
|
ephyrFinishPipelinedAccess(pSrc, EXA_PREPARE_SRC);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,11 +346,13 @@ ephyrUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
|
||||||
if (pDst->drawable.bitsPerPixel < 8)
|
if (pDst->drawable.bitsPerPixel < 8)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
|
||||||
|
|
||||||
cpp = pDst->drawable.bitsPerPixel / 8;
|
cpp = pDst->drawable.bitsPerPixel / 8;
|
||||||
dst_pitch = exaGetPixmapPitch(pDst);
|
dst_pitch = exaGetPixmapPitch(pDst);
|
||||||
dst = fakexa->exa->memoryBase + exaGetPixmapOffset(pDst);
|
dst = fakexa->exa->memoryBase + exaGetPixmapOffset(pDst);
|
||||||
dst += y * dst_pitch + x * cpp;
|
dst += y * dst_pitch + x * cpp;
|
||||||
|
ErrorF("uts %d,%d, %dx%d, %dbpp %p/%x\n", x, y, w, h, pDst->drawable.bitsPerPixel, dst, dst_pitch);
|
||||||
for (; h > 0; h--) {
|
for (; h > 0; h--) {
|
||||||
memcpy(dst, src, w * cpp);
|
memcpy(dst, src, w * cpp);
|
||||||
dst += dst_pitch;
|
dst += dst_pitch;
|
||||||
|
@ -289,14 +361,26 @@ ephyrUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
|
||||||
|
|
||||||
exaMarkSync(pDst->drawable.pScreen);
|
exaMarkSync(pDst->drawable.pScreen);
|
||||||
|
|
||||||
|
ephyrFinishPipelinedAccess(pDst, EXA_PREPARE_DEST);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
ephyrPrepareAccess(PixmapPtr pPix, int index)
|
||||||
|
{
|
||||||
|
/* Make sure we don't somehow end up with a pointer that is in framebuffer
|
||||||
|
* and hasn't been readied for us.
|
||||||
|
*/
|
||||||
|
assert(pPix->devPrivate.ptr != NULL);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In fakexa, we currently only track whether we have synced to the latest
|
* In fakexa, we currently only track whether we have synced to the latest
|
||||||
* "accelerated" drawing that has happened or not. This will be used by an
|
* "accelerated" drawing that has happened or not. It's not used for anything
|
||||||
* ephyrPrepareAccess for the purpose of reliably providing garbage when
|
* yet.
|
||||||
* reading/writing when we haven't synced.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ephyrMarkSync(ScreenPtr pScreen)
|
ephyrMarkSync(ScreenPtr pScreen)
|
||||||
|
@ -382,6 +466,8 @@ ephyrDrawInit(ScreenPtr pScreen)
|
||||||
fakexa->exa->MarkSync = ephyrMarkSync;
|
fakexa->exa->MarkSync = ephyrMarkSync;
|
||||||
fakexa->exa->WaitMarker = ephyrWaitMarker;
|
fakexa->exa->WaitMarker = ephyrWaitMarker;
|
||||||
|
|
||||||
|
fakexa->exa->PrepareAccess = ephyrPrepareAccess;
|
||||||
|
|
||||||
fakexa->exa->pixmapOffsetAlign = EPHYR_OFFSET_ALIGN;
|
fakexa->exa->pixmapOffsetAlign = EPHYR_OFFSET_ALIGN;
|
||||||
fakexa->exa->pixmapPitchAlign = EPHYR_PITCH_ALIGN;
|
fakexa->exa->pixmapPitchAlign = EPHYR_PITCH_ALIGN;
|
||||||
|
|
||||||
|
@ -429,4 +515,5 @@ exaDDXDriverInit(ScreenPtr pScreen)
|
||||||
ExaScreenPriv(pScreen);
|
ExaScreenPriv(pScreen);
|
||||||
|
|
||||||
pExaScr->migration = ExaMigrationAlways;
|
pExaScr->migration = ExaMigrationAlways;
|
||||||
|
pExaScr->hideOffscreenPixmapData = TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue