123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- /*
- *
- * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <X11/X.h>
- #include "scrnintstr.h"
- #include "windowstr.h"
- #include <X11/fonts/font.h>
- #include "dixfontstr.h"
- #include <X11/fonts/fontstruct.h>
- #include "mi.h"
- #include "regionstr.h"
- #include "globals.h"
- #include "gcstruct.h"
- #include "shadow.h"
- #include "fb.h"
- /*
- * These indicate which way the source (shadow) is scanned when
- * walking the screen in a particular direction
- */
- #define LEFT_TO_RIGHT 1
- #define RIGHT_TO_LEFT -1
- #define TOP_TO_BOTTOM 2
- #define BOTTOM_TO_TOP -2
- void
- shadowUpdateRotatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
- {
- RegionPtr damage = shadowDamage(pBuf);
- PixmapPtr pShadow = pBuf->pPixmap;
- int nbox = REGION_NUM_RECTS(damage);
- BoxPtr pbox = REGION_RECTS(damage);
- FbBits *shaBits;
- FbStride shaStride;
- int shaBpp;
- int shaXoff _X_UNUSED, shaYoff _X_UNUSED;
- int box_x1, box_x2, box_y1, box_y2;
- int sha_x1 = 0, sha_y1 = 0;
- int scr_x1 = 0, scr_x2 = 0, scr_y1 = 0, scr_y2 = 0, scr_w, scr_h;
- int scr_x, scr_y;
- int w;
- int pixelsPerBits;
- int pixelsMask;
- FbStride shaStepOverY = 0, shaStepDownY = 0;
- FbStride shaStepOverX = 0, shaStepDownX = 0;
- FbBits *shaLine, *sha;
- int shaHeight = pShadow->drawable.height;
- int shaWidth = pShadow->drawable.width;
- FbBits shaMask;
- int shaFirstShift, shaShift;
- int o_x_dir;
- int o_y_dir;
- int x_dir;
- int y_dir;
- fbGetDrawable(&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff,
- shaYoff);
- pixelsPerBits = (sizeof(FbBits) * 8) / shaBpp;
- pixelsMask = ~(pixelsPerBits - 1);
- shaMask = FbBitsMask(FB_UNIT - shaBpp, shaBpp);
- /*
- * Compute rotation related constants to walk the shadow
- */
- o_x_dir = LEFT_TO_RIGHT;
- o_y_dir = TOP_TO_BOTTOM;
- if (pBuf->randr & SHADOW_REFLECT_X)
- o_x_dir = -o_x_dir;
- if (pBuf->randr & SHADOW_REFLECT_Y)
- o_y_dir = -o_y_dir;
- switch (pBuf->randr & (SHADOW_ROTATE_ALL)) {
- case SHADOW_ROTATE_0: /* upper left shadow -> upper left screen */
- default:
- x_dir = o_x_dir;
- y_dir = o_y_dir;
- break;
- case SHADOW_ROTATE_90: /* upper right shadow -> upper left screen */
- x_dir = o_y_dir;
- y_dir = -o_x_dir;
- break;
- case SHADOW_ROTATE_180: /* lower right shadow -> upper left screen */
- x_dir = -o_x_dir;
- y_dir = -o_y_dir;
- break;
- case SHADOW_ROTATE_270: /* lower left shadow -> upper left screen */
- x_dir = -o_y_dir;
- y_dir = o_x_dir;
- break;
- }
- switch (x_dir) {
- case LEFT_TO_RIGHT:
- shaStepOverX = shaBpp;
- shaStepOverY = 0;
- break;
- case TOP_TO_BOTTOM:
- shaStepOverX = 0;
- shaStepOverY = shaStride;
- break;
- case RIGHT_TO_LEFT:
- shaStepOverX = -shaBpp;
- shaStepOverY = 0;
- break;
- case BOTTOM_TO_TOP:
- shaStepOverX = 0;
- shaStepOverY = -shaStride;
- break;
- }
- switch (y_dir) {
- case TOP_TO_BOTTOM:
- shaStepDownX = 0;
- shaStepDownY = shaStride;
- break;
- case RIGHT_TO_LEFT:
- shaStepDownX = -shaBpp;
- shaStepDownY = 0;
- break;
- case BOTTOM_TO_TOP:
- shaStepDownX = 0;
- shaStepDownY = -shaStride;
- break;
- case LEFT_TO_RIGHT:
- shaStepDownX = shaBpp;
- shaStepDownY = 0;
- break;
- }
- while (nbox--) {
- box_x1 = pbox->x1;
- box_y1 = pbox->y1;
- box_x2 = pbox->x2;
- box_y2 = pbox->y2;
- pbox++;
- /*
- * Compute screen and shadow locations for this box
- */
- switch (x_dir) {
- case LEFT_TO_RIGHT:
- scr_x1 = box_x1 & pixelsMask;
- scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask;
- sha_x1 = scr_x1;
- break;
- case TOP_TO_BOTTOM:
- scr_x1 = box_y1 & pixelsMask;
- scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask;
- sha_y1 = scr_x1;
- break;
- case RIGHT_TO_LEFT:
- scr_x1 = (shaWidth - box_x2) & pixelsMask;
- scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask;
- sha_x1 = (shaWidth - scr_x1 - 1);
- break;
- case BOTTOM_TO_TOP:
- scr_x1 = (shaHeight - box_y2) & pixelsMask;
- scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask;
- sha_y1 = (shaHeight - scr_x1 - 1);
- break;
- }
- switch (y_dir) {
- case TOP_TO_BOTTOM:
- scr_y1 = box_y1;
- scr_y2 = box_y2;
- sha_y1 = scr_y1;
- break;
- case RIGHT_TO_LEFT:
- scr_y1 = (shaWidth - box_x2);
- scr_y2 = (shaWidth - box_x1);
- sha_x1 = box_x2 - 1;
- break;
- case BOTTOM_TO_TOP:
- scr_y1 = shaHeight - box_y2;
- scr_y2 = shaHeight - box_y1;
- sha_y1 = box_y2 - 1;
- break;
- case LEFT_TO_RIGHT:
- scr_y1 = box_x1;
- scr_y2 = box_x2;
- sha_x1 = box_x1;
- break;
- }
- scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT;
- scr_h = scr_y2 - scr_y1;
- scr_y = scr_y1;
- /* shift amount for first pixel on screen */
- shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp;
- /* pointer to shadow data first placed on screen */
- shaLine = (shaBits +
- sha_y1 * shaStride + ((sha_x1 * shaBpp) >> FB_SHIFT));
- /*
- * Copy the bits, always write across the physical frame buffer
- * to take advantage of write combining.
- */
- while (scr_h--) {
- int p;
- FbBits bits;
- FbBits *win;
- int i;
- CARD32 winSize;
- sha = shaLine;
- shaShift = shaFirstShift;
- w = scr_w;
- scr_x = scr_x1 * shaBpp >> FB_SHIFT;
- while (w) {
- /*
- * Map some of this line
- */
- win = (FbBits *) (*pBuf->window) (pScreen,
- scr_y,
- scr_x << 2,
- SHADOW_WINDOW_WRITE,
- &winSize, pBuf->closure);
- i = (winSize >> 2);
- if (i > w)
- i = w;
- w -= i;
- scr_x += i;
- /*
- * Copy the portion of the line mapped
- */
- while (i--) {
- bits = 0;
- p = pixelsPerBits;
- /*
- * Build one word of output from multiple inputs
- *
- * Note that for 90/270 rotations, this will walk
- * down the shadow hitting each scanline once.
- * This is probably not very efficient.
- */
- while (p--) {
- bits = FbScrLeft(bits, shaBpp);
- bits |= FbScrRight(*sha, shaShift) & shaMask;
- shaShift -= shaStepOverX;
- if (shaShift >= FB_UNIT) {
- shaShift -= FB_UNIT;
- sha--;
- }
- else if (shaShift < 0) {
- shaShift += FB_UNIT;
- sha++;
- }
- sha += shaStepOverY;
- }
- *win++ = bits;
- }
- }
- scr_y++;
- shaFirstShift -= shaStepDownX;
- if (shaFirstShift >= FB_UNIT) {
- shaFirstShift -= FB_UNIT;
- shaLine--;
- }
- else if (shaFirstShift < 0) {
- shaFirstShift += FB_UNIT;
- shaLine++;
- }
- shaLine += shaStepDownY;
- }
- }
- }
- shadowUpdateProc
- shadowUpdateRotatePackedWeak(void)
- {
- return shadowUpdateRotatePacked;
- }
|