|
|
|
|
@@ -35,17 +35,21 @@
|
|
|
|
|
|
|
|
|
|
/* DGA stuff */
|
|
|
|
|
|
|
|
|
|
#define DEBUG_GOBLIN 1
|
|
|
|
|
// #define DEBUG_GOBLIN 1
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_GOBLIN
|
|
|
|
|
//#define ENTER xf86Msg(X_ERROR, "%s>\n", __func__);
|
|
|
|
|
#define ENTER
|
|
|
|
|
#define DPRINTF xf86Msg
|
|
|
|
|
#define RPRINTF xf86Msg
|
|
|
|
|
#else
|
|
|
|
|
#define ENTER
|
|
|
|
|
#define DPRINTF while (0) xf86Msg
|
|
|
|
|
#define RPRINTF xf86Msg
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define arraysize(ary) (sizeof(ary) / sizeof(ary[0]))
|
|
|
|
|
|
|
|
|
|
static Bool Goblin_OpenFramebuffer(ScrnInfoPtr pScrn, char **, unsigned char **mem,
|
|
|
|
|
int *, int *, int *);
|
|
|
|
|
static Bool Goblin_SetMode(ScrnInfoPtr, DGAModePtr);
|
|
|
|
|
@@ -62,6 +66,14 @@ static Bool GoblinPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xd
|
|
|
|
|
static void GoblinCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int w, int h);
|
|
|
|
|
static void GoblinSync(ScrnInfoPtr);
|
|
|
|
|
|
|
|
|
|
static Bool GoblinCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture);
|
|
|
|
|
static Bool GoblinPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
|
|
|
|
|
static void GoblinComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height);
|
|
|
|
|
|
|
|
|
|
/* internal helper */
|
|
|
|
|
static Bool GoblinCheckPicture(PicturePtr pict);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static DGAFunctionRec Goblin_DGAFuncs = {
|
|
|
|
|
Goblin_OpenFramebuffer,
|
|
|
|
|
NULL,
|
|
|
|
|
@@ -206,9 +218,6 @@ GOBLINEXAInit(ScreenPtr pScreen)
|
|
|
|
|
pExa->flags = EXA_OFFSCREEN_PIXMAPS;/* | EXA_MIXED_PIXMAPS; */ /* | EXA_SUPPORTS_OFFSCREEN_OVERLAPS; */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* these limits are bogus
|
|
|
|
|
* Jareth doesn't deal with coordinates at all, so there is no limit but
|
|
|
|
|
* we have to put something here
|
|
|
|
|
*/
|
|
|
|
|
pExa->maxX = 4096;
|
|
|
|
|
pExa->maxY = 4096;
|
|
|
|
|
@@ -226,6 +235,13 @@ GOBLINEXAInit(ScreenPtr pScreen)
|
|
|
|
|
pExa->UploadToScreen = GoblinUploadToScreen;
|
|
|
|
|
pExa->DownloadFromScreen = GoblinDownloadFromScreen;
|
|
|
|
|
|
|
|
|
|
if (pGoblin->has_xrender) {
|
|
|
|
|
pExa->CheckComposite = GoblinCheckComposite;
|
|
|
|
|
pExa->PrepareComposite = GoblinPrepareComposite;
|
|
|
|
|
pExa->Composite = GoblinComposite;
|
|
|
|
|
pExa->DoneComposite = GoblinDone;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return exaDriverInit(pScreen, pExa);;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -280,7 +296,7 @@ GoblinUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int
|
|
|
|
|
int wBytes = w * cpp;
|
|
|
|
|
|
|
|
|
|
ENTER;
|
|
|
|
|
DPRINTF(X_ERROR, "%s depth %d x %d y %d w %d h %d src %d %p dst %d 0x%08x %p cpp %d wBytes %d\n", __func__, bpp,
|
|
|
|
|
DPRINTF(X_INFO, "%s depth %d x %d y %d w %d h %d src %d %p dst %d 0x%08x %p cpp %d wBytes %d\n", __func__, bpp,
|
|
|
|
|
x, y, w, h,
|
|
|
|
|
src_pitch, src,
|
|
|
|
|
dst_pitch, exaGetPixmapOffset(pDst), dst,
|
|
|
|
|
@@ -336,12 +352,12 @@ GoblinPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
ENTER;
|
|
|
|
|
DPRINTF(X_ERROR, "PrepareSolid bpp: %d, alu %d, pm 0x%08x, Fg 0x%08x\n", pPixmap->drawable.bitsPerPixel, alu, planemask, fg);
|
|
|
|
|
DPRINTF(X_INFO, "%s bpp: %d, alu %d, pm 0x%08x, Fg 0x%08x\n", __func__, pPixmap->drawable.bitsPerPixel, alu, planemask, fg);
|
|
|
|
|
|
|
|
|
|
GoblinWait(pGoblin);
|
|
|
|
|
|
|
|
|
|
//goblin->jreg->reg_XXXXX = planemask;
|
|
|
|
|
pGoblin->jreg->reg_fgcolor = fg;
|
|
|
|
|
pGoblin->jreg->reg_fgcolor = __builtin_bswap32(fg); // ???
|
|
|
|
|
|
|
|
|
|
pGoblin->last_mask = planemask;
|
|
|
|
|
pGoblin->last_rop = alu;
|
|
|
|
|
@@ -349,11 +365,13 @@ GoblinPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
|
|
|
|
|
pGoblin->jreg->reg_dst_ptr = 0;
|
|
|
|
|
|
|
|
|
|
if ((alu == 0x3) && // GXcopy
|
|
|
|
|
(planemask == 0xFFFFFFFF)) { // full pattern
|
|
|
|
|
(planemask == 0xFFFFFFFF)) { // full patternp
|
|
|
|
|
// fill
|
|
|
|
|
pGoblin->jreg->reg_op = alu;
|
|
|
|
|
pGoblin->jreg->reg_depth = 0; // reset to native
|
|
|
|
|
} else {
|
|
|
|
|
// fillrop
|
|
|
|
|
DPRINTF(X_ERROR, "PrepareSolid unsupported: 0x08x, 0x%08x\n", alu, planemask);
|
|
|
|
|
DPRINTF(X_ERROR, "%s unsupported: 0x08x, 0x%08x\n", __func__, alu, planemask);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
@@ -401,7 +419,7 @@ GoblinSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
|
|
|
|
|
else
|
|
|
|
|
pGoblin->jreg->reg_dst_ptr = 0;
|
|
|
|
|
|
|
|
|
|
DPRINTF(X_INFO, "Solid {%d} %d %d %d %d [%d %d], %d %d -> %d (%p: %p)\n",
|
|
|
|
|
DPRINTF(X_INFO, "%s {%d} %d %d %d %d [%d %d], %d %d -> %d (%p: %p)\n", __func__,
|
|
|
|
|
depth,
|
|
|
|
|
x1, y1, x2, y2,
|
|
|
|
|
w, h, dstpitch, dstoff, start, (void*)start, ptr);
|
|
|
|
|
@@ -414,7 +432,6 @@ GoblinSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
|
|
|
|
|
static void GoblinDone(PixmapPtr pDstPixmap) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
|
GoblinPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
|
|
|
|
|
int xdir, int ydir, int alu, Pixel planemask)
|
|
|
|
|
@@ -440,23 +457,27 @@ GoblinPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
|
|
|
|
|
if ((alu == 0x3) && // GCcopy
|
|
|
|
|
(planemask == 0xFFFFFFFF)) { // full pattern
|
|
|
|
|
// fill
|
|
|
|
|
pGoblin->jreg->reg_op = alu;
|
|
|
|
|
pGoblin->jreg->reg_depth = 0; // reset to native
|
|
|
|
|
} else {
|
|
|
|
|
// fillrop
|
|
|
|
|
DPRINTF(X_ERROR, "PrepareCopy unsupported: 0x08x, 0x%08x\n", alu, planemask);
|
|
|
|
|
DPRINTF(X_ERROR, "%s unsupported: 0x08x, 0x%08x\n", __func__, alu, planemask);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ((alu == 0x3) && // GCcopy
|
|
|
|
|
(planemask == 0xFFFFFFFF)) { // full pattern
|
|
|
|
|
// fill
|
|
|
|
|
pGoblin->jreg->reg_op = alu;
|
|
|
|
|
pGoblin->jreg->reg_depth = 0; // reset to native
|
|
|
|
|
} else {
|
|
|
|
|
// fillrop
|
|
|
|
|
DPRINTF(X_ERROR, "PrepareCopy unsupported: 0x08x, 0x%08x\n", alu, planemask);
|
|
|
|
|
DPRINTF(X_ERROR, "%s unsupported: 0x08x, 0x%08x\n", __func__, alu, planemask);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DPRINTF(X_ERROR, "PrepareCopy: alu %d, pm 0x%08x, xdir/ydir %d/%d\n", alu, planemask, xdir, ydir);
|
|
|
|
|
DPRINTF(X_INFO, "%s: alu %d, pm 0x%08x, xdir/ydir %d/%d\n", __func__, alu, planemask, xdir, ydir);
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
@@ -509,8 +530,7 @@ GoblinCopy(PixmapPtr pDstPixmap,
|
|
|
|
|
else
|
|
|
|
|
pGoblin->jreg->reg_dst_ptr = 0;
|
|
|
|
|
|
|
|
|
|
//DPRINTF(X_ERROR, "Copy %d %d -> %d %d [%d x %d, %d %d] ; %d -> %d \n", srcX, srcY, dstX, dstY, w, h, pGoblin->xdir, pGoblin->ydir, srcstart, dststart);
|
|
|
|
|
DPRINTF(X_ERROR, "Copy %d %d -> %d %d [%d x %d, %d %d] ; 0x%08x 0x%08x ; %d %d \n", srcX, srcY, dstX, dstY, w, h, pGoblin->xdir, pGoblin->ydir, pGoblin->srcoff, dstoff, pGoblin->srcpitch, dstpitch);
|
|
|
|
|
DPRINTF(X_INFO, "%s %d %d -> %d %d [%d x %d, %d %d] ; 0x%08x 0x%08x ; %d %d \n", __func__, srcX, srcY, dstX, dstY, w, h, pGoblin->xdir, pGoblin->ydir, pGoblin->srcoff, dstoff, pGoblin->srcpitch, dstpitch);
|
|
|
|
|
|
|
|
|
|
pGoblin->jreg->reg_cmd = 1; // 1<<DO_COPY_BIT
|
|
|
|
|
|
|
|
|
|
@@ -537,3 +557,393 @@ GoblinCopy(PixmapPtr pDstPixmap,
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int src_formats[] = {PICT_a8r8g8b8, PICT_x8r8g8b8,
|
|
|
|
|
PICT_a8b8g8r8, PICT_x8b8g8r8, PICT_a8};
|
|
|
|
|
int tex_formats[] = {PICT_a8r8g8b8, PICT_a8b8g8r8, PICT_a8};
|
|
|
|
|
|
|
|
|
|
static const char* fmt2name(const int fmt) {
|
|
|
|
|
switch (fmt) {
|
|
|
|
|
case PICT_a8r8g8b8: return "PICT_a8r8g8b8";
|
|
|
|
|
case PICT_x8r8g8b8: return "PICT_x8r8g8b8";
|
|
|
|
|
case PICT_a8b8g8r8: return "PICT_a8b8g8r8";
|
|
|
|
|
case PICT_x8b8g8r8: return "PICT_x8b8g8r8";
|
|
|
|
|
case PICT_a8: return "PICT_a8";
|
|
|
|
|
default: return "PICT_Unknown";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
static const char* op2name(const int op) {
|
|
|
|
|
switch (op) {
|
|
|
|
|
case PictOpClear: return "PictOpClear";
|
|
|
|
|
case PictOpSrc: return "PictOpSrc";
|
|
|
|
|
case PictOpDst: return "PictOpDst";
|
|
|
|
|
case PictOpOver: return "PictOpOver";
|
|
|
|
|
case PictOpOverReverse: return "PictOpOverReverse";
|
|
|
|
|
case PictOpIn: return "PictOpIn";
|
|
|
|
|
case PictOpInReverse: return "PictOpInReverse";
|
|
|
|
|
case PictOpOut: return "PictOpOut";
|
|
|
|
|
case PictOpOutReverse: return "PictOpOutReverse";
|
|
|
|
|
case PictOpAtop: return "PictOpAtop";
|
|
|
|
|
case PictOpAtopReverse: return "PictOpAtopReverse";
|
|
|
|
|
case PictOpXor: return "PictOpXor";
|
|
|
|
|
case PictOpAdd: return "PictOpAdd";
|
|
|
|
|
case PictOpSaturate: return "PictOpSaturate";
|
|
|
|
|
default: return "PictOpUnknown";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Bool GoblinCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture) {
|
|
|
|
|
int i, ok = FALSE;
|
|
|
|
|
|
|
|
|
|
ENTER;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Like SX, Goblin is in theory capable of accelerating pretty much all Xrender ops,
|
|
|
|
|
* even coordinate transformation and gradients.
|
|
|
|
|
* However someone needs to write all that software...
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if ((op != PictOpOver) &&
|
|
|
|
|
(op != PictOpAdd) &&
|
|
|
|
|
/* (op != PictOpSrc) && */
|
|
|
|
|
/* (op != PictOpOutReverse) && */
|
|
|
|
|
1) {
|
|
|
|
|
RPRINTF(X_ERROR, "%s: rejecting %s (%d)\n", __func__, op2name(op), op);
|
|
|
|
|
return FALSE;
|
|
|
|
|
} else {
|
|
|
|
|
RPRINTF(X_INFO, "%s: accepting %s (%d)\n", __func__, op2name(op), op);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pSrcPicture != NULL) {
|
|
|
|
|
i = 0;
|
|
|
|
|
while ((i < arraysize(src_formats)) && (!ok)) {
|
|
|
|
|
ok = (pSrcPicture->format == src_formats[i]);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ok) {
|
|
|
|
|
RPRINTF(X_ERROR, "%s: unsupported src format %s (%x)\n",
|
|
|
|
|
__func__, fmt2name(pSrcPicture->format), pSrcPicture->format);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!GoblinCheckPicture(pSrcPicture)) {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RPRINTF(X_INFO, "%s: src is %s (%x), %s (%d)\n", __func__, fmt2name(pSrcPicture->format), pSrcPicture->format, op2name(op), op);
|
|
|
|
|
// pSrcPicture->pDrawable->width, pSrcPicture->pDrawable->height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pDstPicture != NULL) {
|
|
|
|
|
i = 0;
|
|
|
|
|
ok = FALSE;
|
|
|
|
|
while ((i < arraysize(src_formats)) && (!ok)) {
|
|
|
|
|
ok = (pDstPicture->format == src_formats[i]);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ok) {
|
|
|
|
|
RPRINTF(X_ERROR, "%s: unsupported dst format %x\n",
|
|
|
|
|
__func__, pDstPicture->format);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RPRINTF(X_INFO, "%s: dst is %s (%x), %s (%d)\n", __func__, fmt2name(pDstPicture->format), pDstPicture->format, op2name(op), op);
|
|
|
|
|
// pDstPicture->pDrawable->width, pDstPicture->pDrawable->height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pMaskPicture != NULL) {
|
|
|
|
|
if (!GoblinCheckPicture(pMaskPicture)) {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RPRINTF(X_INFO, "%s: mask is %s (%x), %d x %d\n", __func__, fmt2name(pMaskPicture->format), pMaskPicture->format,
|
|
|
|
|
pMaskPicture->pDrawable->width,
|
|
|
|
|
pMaskPicture->pDrawable->height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Bool GoblinCheckPicture(PicturePtr pict) {
|
|
|
|
|
int w, h;
|
|
|
|
|
|
|
|
|
|
if (pict->pDrawable) {
|
|
|
|
|
w = pict->pDrawable->width;
|
|
|
|
|
h = pict->pDrawable->height;
|
|
|
|
|
} else {
|
|
|
|
|
if (pict->pSourcePict->type != SourcePictTypeSolidFill) {
|
|
|
|
|
RPRINTF(X_ERROR, "%s: Gradient pictures not supported\n", __func__);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
w = 1;
|
|
|
|
|
h = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (w >= 4096 || h >= 4096) {
|
|
|
|
|
RPRINTF(X_ERROR, "%s: Picture too large, %d x %d\n", __func__, w, h);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((pict->repeat != RepeatNone) &&
|
|
|
|
|
((w != 1) || (h != 1))) {
|
|
|
|
|
RPRINTF(X_ERROR, "%s: Picture is repeating non-trivial\n", __func__);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pict->filter) {
|
|
|
|
|
RPRINTF(X_ERROR, "%s: Picture has filter\n", __func__);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pict->transform) {
|
|
|
|
|
RPRINTF(X_ERROR, "%s: Picture has transform\n", __func__);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Bool GoblinPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) {
|
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
|
|
|
|
|
GoblinPtr pGoblin = GET_GOBLIN_FROM_SCRN(pScrn);
|
|
|
|
|
|
|
|
|
|
ENTER;
|
|
|
|
|
|
|
|
|
|
pGoblin->no_source_pixmap = FALSE;
|
|
|
|
|
pGoblin->source_is_solid = FALSE;
|
|
|
|
|
|
|
|
|
|
if (pSrcPicture->format == PICT_a1) {
|
|
|
|
|
xf86Msg(X_ERROR, "src mono, dst %x, op %d\n",
|
|
|
|
|
pDstPicture->format, op);
|
|
|
|
|
if (pMaskPicture != NULL) {
|
|
|
|
|
xf86Msg(X_ERROR, "msk %x\n", pMaskPicture->format);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pSrcPicture->pSourcePict != NULL) {
|
|
|
|
|
if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
|
|
|
|
|
pGoblin->fillcolour =
|
|
|
|
|
pSrcPicture->pSourcePict->solidFill.color;
|
|
|
|
|
RPRINTF(X_INFO, "%s: solid src %08x\n", __func__, pGoblin->fillcolour);
|
|
|
|
|
pGoblin->no_source_pixmap = TRUE;
|
|
|
|
|
pGoblin->source_is_solid = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((pMaskPicture != NULL) && (pMaskPicture->pSourcePict != NULL)) {
|
|
|
|
|
if (pMaskPicture->pSourcePict->type ==
|
|
|
|
|
SourcePictTypeSolidFill) {
|
|
|
|
|
pGoblin->fillcolour =
|
|
|
|
|
pMaskPicture->pSourcePict->solidFill.color;
|
|
|
|
|
xf86Msg(X_ERROR, "%s: solid mask %08x\n", __func__, pGoblin->fillcolour);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pMaskPicture != NULL) {
|
|
|
|
|
pGoblin->mskoff = exaGetPixmapOffset(pMask);
|
|
|
|
|
pGoblin->mskpitch = exaGetPixmapPitch(pMask);
|
|
|
|
|
pGoblin->mskformat = pMaskPicture->format;
|
|
|
|
|
} else {
|
|
|
|
|
pGoblin->mskoff = 0;
|
|
|
|
|
pGoblin->mskpitch = 0;
|
|
|
|
|
pGoblin->mskformat = 0;
|
|
|
|
|
}
|
|
|
|
|
if (pSrc != NULL) {
|
|
|
|
|
//pGoblin->source_is_solid = ((pSrc->drawable.width == 1) && (pSrc->drawable.height == 1));
|
|
|
|
|
pGoblin->source_is_solid = 0;
|
|
|
|
|
pGoblin->srcoff = exaGetPixmapOffset(pSrc);
|
|
|
|
|
pGoblin->srcpitch = exaGetPixmapPitch(pSrc);
|
|
|
|
|
if (pGoblin->source_is_solid) {
|
|
|
|
|
pGoblin->fillcolour = *(uint32_t *)(pGoblin->fb + pGoblin->srcoff);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pGoblin->srcformat = pSrcPicture->format;
|
|
|
|
|
pGoblin->dstformat = pDstPicture->format;
|
|
|
|
|
|
|
|
|
|
if (pGoblin->source_is_solid) {
|
|
|
|
|
// init for solid ?
|
|
|
|
|
}
|
|
|
|
|
pGoblin->op = op;
|
|
|
|
|
|
|
|
|
|
/* if (op == PictOpSrc) { */
|
|
|
|
|
/* CG14PrepareCopy(pSrc, pDst, 1, 1, GXcopy, 0xffffffff); */
|
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((pGoblin->op == PictOpOver) &&
|
|
|
|
|
(pGoblin->source_is_solid) &&
|
|
|
|
|
(pGoblin->mskformat == PICT_a8) &&
|
|
|
|
|
1) {
|
|
|
|
|
RPRINTF(X_INFO, "%s: A %s (%d) %s _ %s [%d %d _] %s\n", __func__, op2name(op), op, fmt2name(pGoblin->srcformat), fmt2name(pGoblin->dstformat),
|
|
|
|
|
pGoblin->srcpitch, pGoblin->mskpitch, pGoblin->source_is_solid ? "Solid" : "");
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((pGoblin->op == PictOpOver) &&
|
|
|
|
|
(~pGoblin->source_is_solid) &&
|
|
|
|
|
((pGoblin->srcformat == PICT_x8r8g8b8) || (pGoblin->srcformat == PICT_x8b8g8r8)) &&
|
|
|
|
|
(pGoblin->mskformat == PICT_a8r8g8b8) &&
|
|
|
|
|
1) {
|
|
|
|
|
RPRINTF(X_INFO, "%s: B %s (%d) %s _ %s [%d %d _] %s\n", __func__, op2name(op), op, fmt2name(pGoblin->srcformat), fmt2name(pGoblin->dstformat),
|
|
|
|
|
pGoblin->srcpitch, pGoblin->mskpitch, pGoblin->source_is_solid ? "Solid" : "");
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((pGoblin->op == PictOpAdd) &&
|
|
|
|
|
(pGoblin->srcformat == PICT_a8) &&
|
|
|
|
|
(pGoblin->dstformat == PICT_a8) &&
|
|
|
|
|
(pGoblin->mskformat == 0) &&
|
|
|
|
|
1) {
|
|
|
|
|
RPRINTF(X_INFO, "%s: C %s (%d) %s _ %s [%d %d _] %s\n", __func__, op2name(op), op, fmt2name(pGoblin->srcformat), fmt2name(pGoblin->dstformat),
|
|
|
|
|
pGoblin->srcpitch, pGoblin->mskpitch, pGoblin->source_is_solid ? "Solid" : "");
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RPRINTF(X_ERROR, "%s: NOT %s (%d) %s _ %s [%d %d _] %s\n", __func__, op2name(op), op, fmt2name(pGoblin->srcformat), fmt2name(pGoblin->dstformat),
|
|
|
|
|
pGoblin->srcpitch, pGoblin->mskpitch, pGoblin->source_is_solid ? "Solid" : "");
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void GoblinComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height) {
|
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
|
|
|
|
|
GoblinPtr pGoblin = GET_GOBLIN_FROM_SCRN(pScrn);
|
|
|
|
|
uint32_t dstoff, dstpitch;
|
|
|
|
|
uint32_t dst, msk, src;
|
|
|
|
|
int flip = 0;
|
|
|
|
|
|
|
|
|
|
ENTER;
|
|
|
|
|
dstoff = exaGetPixmapOffset(pDst);
|
|
|
|
|
dstpitch = exaGetPixmapPitch(pDst);
|
|
|
|
|
|
|
|
|
|
flip = (PICT_FORMAT_TYPE(pGoblin->srcformat) !=
|
|
|
|
|
PICT_FORMAT_TYPE(pGoblin->dstformat));
|
|
|
|
|
|
|
|
|
|
switch (pGoblin->op) {
|
|
|
|
|
case PictOpOver: {
|
|
|
|
|
GoblinWait(pGoblin);
|
|
|
|
|
pGoblin->jreg->reg_op = (0x80 | PictOpOver | ((flip && ~pGoblin->source_is_solid) ? 0x40 : 0)); // xrender operation
|
|
|
|
|
pGoblin->jreg->reg_depth = 0; // or 32 ?
|
|
|
|
|
pGoblin->jreg->reg_width = width;
|
|
|
|
|
pGoblin->jreg->reg_height = height;
|
|
|
|
|
|
|
|
|
|
pGoblin->jreg->reg_dst_stride = dstpitch;
|
|
|
|
|
pGoblin->jreg->reg_bitblt_dst_x = dstX;
|
|
|
|
|
pGoblin->jreg->reg_bitblt_dst_y = dstY;
|
|
|
|
|
if (dstoff != 0)
|
|
|
|
|
pGoblin->jreg->reg_dst_ptr = (0x8f000000 + dstoff); // fixme: hw'ired @
|
|
|
|
|
else
|
|
|
|
|
pGoblin->jreg->reg_dst_ptr = 0;
|
|
|
|
|
|
|
|
|
|
pGoblin->jreg->reg_msk_stride = pGoblin->mskpitch;
|
|
|
|
|
pGoblin->jreg->reg_bitblt_msk_x = maskX;
|
|
|
|
|
pGoblin->jreg->reg_bitblt_msk_y = maskY;
|
|
|
|
|
if (pGoblin->mskoff != 0)
|
|
|
|
|
pGoblin->jreg->reg_msk_ptr = (0x8f000000 + pGoblin->mskoff); // fixme: hw'ired @
|
|
|
|
|
else
|
|
|
|
|
pGoblin->jreg->reg_msk_ptr = 0;
|
|
|
|
|
|
|
|
|
|
if (pGoblin->source_is_solid) {
|
|
|
|
|
pGoblin->jreg->reg_fgcolor = flip ? __builtin_bswap32(pGoblin->fillcolour) : pGoblin->fillcolour;
|
|
|
|
|
switch (pGoblin->mskformat) {
|
|
|
|
|
case PICT_a8:
|
|
|
|
|
RPRINTF(X_INFO, "%s: Starting PictOpOver: %d x %d, flip %d, %d x %d (+0x%08x)-> %d x %d (+0x%08x), fg 0x%08x\n", __func__,
|
|
|
|
|
width, height, flip,
|
|
|
|
|
maskX, maskY, pGoblin->mskoff,
|
|
|
|
|
dstX, dstY, dstoff,
|
|
|
|
|
pGoblin->fillcolour
|
|
|
|
|
);
|
|
|
|
|
pGoblin->jreg->reg_cmd = 8; // 1<<DO_RSMSK8DST32_BIT
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
RPRINTF(X_ERROR, "%s: A Unsupported mask format %s (%d) for PictOpOver (%d x %d)\n", __func__, fmt2name(pGoblin->mskformat), pGoblin->mskformat, width, height);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
pGoblin->jreg->reg_src_stride = pGoblin->srcpitch;
|
|
|
|
|
pGoblin->jreg->reg_bitblt_src_x = srcX;
|
|
|
|
|
pGoblin->jreg->reg_bitblt_src_y = srcY;
|
|
|
|
|
if (pGoblin->srcoff != 0)
|
|
|
|
|
pGoblin->jreg->reg_src_ptr = (0x8f000000 + pGoblin->srcoff); // fixme: hw'ired @
|
|
|
|
|
else
|
|
|
|
|
pGoblin->jreg->reg_src_ptr = 0;
|
|
|
|
|
switch (pGoblin->mskformat) {
|
|
|
|
|
case PICT_a8r8g8b8:
|
|
|
|
|
case PICT_a8b8g8r8:
|
|
|
|
|
RPRINTF(X_INFO, "%s: Starting PictOpOver: %d x %d, flip %d, %d x %d (+0x%08x) & %d x %d (+0x%08x) -> %d x %d (+0x%08x)\n", __func__,
|
|
|
|
|
width, height, flip,
|
|
|
|
|
srcX, srcY, pGoblin->srcoff,
|
|
|
|
|
maskX, maskY, pGoblin->mskoff,
|
|
|
|
|
dstX, dstY, dstoff
|
|
|
|
|
);
|
|
|
|
|
if ((width == 1) && (height == 1)) {
|
|
|
|
|
RPRINTF(X_INFO, "%s: before ... 0x%08x 0x%08x 0x%08x\n", __func__,
|
|
|
|
|
*(unsigned int*)(pGoblin->fb + pGoblin->srcoff),
|
|
|
|
|
*(unsigned int*)(pGoblin->fb + pGoblin->mskoff),
|
|
|
|
|
*(unsigned int*)(pGoblin->fb + dstoff));
|
|
|
|
|
}
|
|
|
|
|
if ((pGoblin->srcoff != pGoblin->mskoff) ||
|
|
|
|
|
(srcX != maskX) ||
|
|
|
|
|
(srcY != maskY)) {
|
|
|
|
|
pGoblin->jreg->reg_cmd = 0x10; // 1<<DO_RSRC32MSK32DST32_BIT
|
|
|
|
|
} else {
|
|
|
|
|
// mask is just src
|
|
|
|
|
pGoblin->jreg->reg_cmd = 0x20; // 1<<DO_RSRC32DST32_BIT
|
|
|
|
|
}
|
|
|
|
|
if ((width == 1) && (height == 1)) {
|
|
|
|
|
GoblinWait(pGoblin);
|
|
|
|
|
RPRINTF(X_INFO, "%s: after ... 0x%08x 0x%08x 0x%08x\n", __func__,
|
|
|
|
|
*(unsigned int*)(pGoblin->fb + pGoblin->srcoff),
|
|
|
|
|
*(unsigned int*)(pGoblin->fb + pGoblin->mskoff),
|
|
|
|
|
*(unsigned int*)(pGoblin->fb + dstoff));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
RPRINTF(X_ERROR, "%s: B Unsupported mask format %s (%d) for PictOpOver (%d x %d)\n", __func__, fmt2name(pGoblin->mskformat), pGoblin->mskformat, width, height);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case PictOpAdd: {
|
|
|
|
|
GoblinWait(pGoblin);
|
|
|
|
|
pGoblin->jreg->reg_op = (0x80 | PictOpAdd); // xrender operation
|
|
|
|
|
pGoblin->jreg->reg_width = width;
|
|
|
|
|
pGoblin->jreg->reg_height = height;
|
|
|
|
|
|
|
|
|
|
pGoblin->jreg->reg_dst_stride = dstpitch;
|
|
|
|
|
pGoblin->jreg->reg_bitblt_dst_x = dstX;
|
|
|
|
|
pGoblin->jreg->reg_bitblt_dst_y = dstY;
|
|
|
|
|
if (dstoff != 0)
|
|
|
|
|
pGoblin->jreg->reg_dst_ptr = (0x8f000000 + dstoff); // fixme: hw'ired @
|
|
|
|
|
else
|
|
|
|
|
pGoblin->jreg->reg_dst_ptr = 0;
|
|
|
|
|
|
|
|
|
|
pGoblin->jreg->reg_src_stride = pGoblin->srcpitch;
|
|
|
|
|
pGoblin->jreg->reg_bitblt_src_x = srcX;
|
|
|
|
|
pGoblin->jreg->reg_bitblt_src_y = srcY;
|
|
|
|
|
if (pGoblin->srcoff != 0)
|
|
|
|
|
pGoblin->jreg->reg_src_ptr = (0x8f000000 + pGoblin->srcoff); // fixme: hw'ired @
|
|
|
|
|
else
|
|
|
|
|
pGoblin->jreg->reg_src_ptr = 0;
|
|
|
|
|
|
|
|
|
|
if ((pGoblin->srcformat == PICT_a8) &&
|
|
|
|
|
(pGoblin->dstformat == PICT_a8) &&
|
|
|
|
|
(pGoblin->mskformat == 0) &&
|
|
|
|
|
1) {
|
|
|
|
|
RPRINTF(X_INFO, "%s: Starting PictOpAdd: %d x %d, flip %d, %d x %d (+0x%08x)-> %d x %d (+0x%08x)\n", __func__,
|
|
|
|
|
width, height, flip,
|
|
|
|
|
srcX, srcY, pGoblin->srcoff,
|
|
|
|
|
dstX, dstY, dstoff
|
|
|
|
|
);
|
|
|
|
|
pGoblin->jreg->reg_depth = 8; // force 8 bits mode in the blitter
|
|
|
|
|
pGoblin->jreg->reg_cmd = 1; // 1<<DO_COPY_BIT
|
|
|
|
|
} else {
|
|
|
|
|
RPRINTF(X_ERROR, "%s: Unsupported fmts %s (%d), %s (%d), %s (%d)\n", __func__, pGoblin->srcformat, pGoblin->srcformat, pGoblin->dstformat, pGoblin->dstformat, pGoblin->mskformat, pGoblin->mskformat);
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
default:
|
|
|
|
|
RPRINTF(X_ERROR, "%s: Unsupported %s (%d)\n", __func__, op2name(pGoblin->op), pGoblin->op);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exaMarkSync(pDst->drawable.pScreen);
|
|
|
|
|
}
|
|
|
|
|
|