/* * Create an xa format from a PICT format. */ enum xa_formats to_xa_format(enum _PictFormatShort format) { uint32_t ptype = PICT_FORMAT_TYPE(format); if ((ptype >= ARRAY_SIZE(stype_map)) || (stype_map[ptype] == 0) || (stype_map[ptype] == xa_type_other)) return xa_format_unknown; return xa_format(PICT_FORMAT_BPP(format), stype_map[ptype], PICT_FORMAT_A(format), PICT_FORMAT_R(format), PICT_FORMAT_G(format), PICT_FORMAT_B(format)); }
static Bool uxa_get_pixel_from_rgba(CARD32 * pixel, CARD16 red, CARD16 green, CARD16 blue, CARD16 alpha, CARD32 format) { int rbits, bbits, gbits, abits; int rshift, bshift, gshift, ashift; rbits = PICT_FORMAT_R(format); gbits = PICT_FORMAT_G(format); bbits = PICT_FORMAT_B(format); abits = PICT_FORMAT_A(format); if (abits == 0) abits = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits); if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { *pixel = alpha >> (16 - abits); return TRUE; }
static ExaGlyphCacheResult exaBufferGlyph(ScreenPtr pScreen, ExaGlyphBufferPtr buffer, GlyphPtr pGlyph, PicturePtr pSrc, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst) { ExaScreenPriv(pScreen); unsigned int format = (GetGlyphPicture(pGlyph, pScreen))->format; int width = pGlyph->info.width; int height = pGlyph->info.height; ExaCompositeRectPtr rect; PicturePtr mask; int i; if (buffer->count == GLYPH_BUFFER_SIZE) return ExaGlyphNeedFlush; if (PICT_FORMAT_BPP(format) == 1) format = PICT_a8; for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; if (format == cache->format && width <= cache->glyphWidth && height <= cache->glyphHeight) { ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen, &pExaScr-> glyphCaches [i], buffer, pGlyph, pSrc, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst); switch (result) { case ExaGlyphFail: break; case ExaGlyphSuccess: case ExaGlyphNeedFlush: return result; } } } /* Couldn't find the glyph in the cache, use the glyph picture directly */ mask = GetGlyphPicture(pGlyph, pScreen); if (buffer->mask && buffer->mask != mask) return ExaGlyphNeedFlush; buffer->mask = mask; rect = &buffer->rects[buffer->count]; rect->xSrc = xSrc; rect->ySrc = ySrc; rect->xMask = xMask; rect->yMask = yMask; rect->xDst = xDst; rect->yDst = yDst; rect->width = width; rect->height = height; buffer->count++; return ExaGlyphSuccess; }
void tridentComposite (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { SetupTrident (pDst->pDrawable->pScreen); tridentScreenInfo(pScreenPriv); RegionRec region; int n; BoxPtr pbox; CARD32 rgb; CARD8 *msk, *mskLine; FbBits *mskBits; FbStride mskStride; int mskBpp; int mskXoff, mskYoff; CARD32 *src, *srcLine; CARD32 *off, *offLine; FbBits *srcBits; FbStride srcStride; int srcXoff, srcYoff; FbStride offStride; int srcBpp; int x_msk, y_msk, x_src, y_src, x_dst, y_dst; int x2; int w, h, w_this, h_this, w_remain; CARD32 *off_screen; int off_size = tridents->off_screen_size >> 2; int off_width, off_height; int stride = pScreenPriv->screen->fb[0].pixelStride; int mskExtra; CARD32 off_screen_offset = tridents->off_screen - tridents->screen; int mode; #define MODE_NONE 0 #define MODE_IMAGE 1 #define MODE_MASK 2 rgb = *((CARD32 *) ((PixmapPtr) (pSrc->pDrawable))->devPrivate.ptr); if (pMask && !pMask->repeat && pMask->format == PICT_a8 && op == PictOpOver && pSrc->repeat && pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && PICT_FORMAT_BPP(pSrc->format) == 32 && (PICT_FORMAT_A(pSrc->format) == 0 || (rgb & 0xff000000) == 0xff000000) && pDst->pDrawable->bitsPerPixel == 32 && pDst->pDrawable->type == DRAWABLE_WINDOW) { mode = MODE_MASK; } else if (!pMask && op == PictOpOver && !pSrc->repeat && PICT_FORMAT_A(pSrc->format) == 8 && PICT_FORMAT_BPP(pSrc->format) == 32 && pDst->pDrawable->bitsPerPixel == 32 && pDst->pDrawable->type == DRAWABLE_WINDOW) { mode = MODE_IMAGE; } else mode = MODE_NONE; if (mode != MODE_NONE) { xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x; ySrc += pSrc->pDrawable->y; fbGetDrawable (pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); if (pMask) { xMask += pMask->pDrawable->x; yMask += pMask->pDrawable->y; fbGetDrawable (pMask->pDrawable, mskBits, mskStride, mskBpp, mskXoff, mskYoff); mskStride = mskStride * sizeof (FbBits) / sizeof (CARD8); } if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) return; _tridentInit(cop,tridentc); cop->multi = COP_MULTI_PATTERN; cop->src_offset = off_screen_offset; if (mode == MODE_IMAGE) { cop->multi = (COP_MULTI_ALPHA | COP_ALPHA_BLEND_ENABLE | COP_ALPHA_WRITE_ENABLE | 0x7 << 16 | COP_ALPHA_DST_BLEND_1_SRC_A | COP_ALPHA_SRC_BLEND_1); } else { rgb &= 0xffffff; cop->multi = (COP_MULTI_ALPHA | COP_ALPHA_BLEND_ENABLE | COP_ALPHA_WRITE_ENABLE | 0x7 << 16 | COP_ALPHA_DST_BLEND_1_SRC_A | COP_ALPHA_SRC_BLEND_SRC_A); } n = REGION_NUM_RECTS (®ion); pbox = REGION_RECTS (®ion); while (n--) { h = pbox->y2 - pbox->y1; w = pbox->x2 - pbox->x1; offStride = (w + 7) & ~7; off_height = off_size / offStride; if (off_height > h) off_height = h; cop->multi = COP_MULTI_STRIDE | (stride << 16) | offStride; y_dst = pbox->y1; y_src = y_dst - yDst + ySrc; y_msk = y_dst - yDst + yMask; x_dst = pbox->x1; x_src = x_dst - xDst + xSrc; x_msk = x_dst - xDst + xMask; if (mode == MODE_IMAGE) srcLine = (CARD32 *) srcBits + (y_src - srcYoff) * srcStride + (x_src - srcXoff); else mskLine = (CARD8 *) mskBits + (y_msk - mskYoff) * mskStride + (x_msk - mskXoff); while (h) { h_this = h; if (h_this > off_height) h_this = off_height; h -= h_this; offLine = (CARD32 *) tridents->off_screen; _tridentWaitDone(cop); cop->dst_start_xy = TRI_XY(x_dst, y_dst); cop->dst_end_xy = TRI_XY(x_dst + w - 1, y_dst + h_this - 1); cop->src_start_xy = TRI_XY(0,0); cop->src_end_xy = TRI_XY(w - 1, h_this - 1); if (mode == MODE_IMAGE) { while (h_this--) { w_remain = w; src = srcLine; srcLine += srcStride; off = offLine; offLine += offStride; while (w_remain--) *off++ = *src++; } } else { while (h_this--) { w_remain = w; msk = mskLine; mskLine += mskStride; off = offLine; offLine += offStride; while (w_remain--) *off++ = rgb | (*msk++ << 24); } } cop->command = (COP_OP_BLT | COP_SCL_OPAQUE | COP_OP_FB); } pbox++; } cop->src_offset = 0; KdMarkSync (pDst->pDrawable->pScreen); } else { KdCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); } }