fbgc.c revision 03b705cf
1/* 2 * Copyright © 1998 Keith Packard 3 * Copyright © 2012 Intel Corporation 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of Keith Packard not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. Keith Packard makes no 12 * representations about the suitability of this software for any purpose. It 13 * is provided "as is" without express or implied warranty. 14 * 15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24#include "fb.h" 25#include <gcstruct.h> 26#include <migc.h> 27#include <scrnintstr.h> 28 29/* 30 * Pad pixmap to FB_UNIT bits wide 31 */ 32void 33fbPadPixmap(PixmapPtr pPixmap) 34{ 35 int width; 36 FbBits *bits; 37 FbBits b; 38 FbBits mask; 39 int height; 40 int w; 41 int stride; 42 int bpp; 43 _X_UNUSED int xOff, yOff; 44 45 fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff); 46 47 width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel; 48 height = pPixmap->drawable.height; 49 mask = FbBitsMask(0, width); 50 while (height--) { 51 b = READ(bits) & mask; 52 w = width; 53 while (w < FB_UNIT) { 54 b = b | FbScrRight(b, w); 55 w <<= 1; 56 } 57 WRITE(bits, b); 58 bits += stride; 59 } 60} 61 62/* 63 * Verify that 'bits' repeats every 'len' bits 64 */ 65static Bool 66fbBitsRepeat(FbBits bits, int len, int width) 67{ 68 FbBits mask = FbBitsMask(0, len); 69 FbBits orig = bits & mask; 70 int i; 71 72 if (width > FB_UNIT) 73 width = FB_UNIT; 74 for (i = 0; i < width / len; i++) { 75 if ((bits & mask) != orig) 76 return FALSE; 77 bits = FbScrLeft(bits, len); 78 } 79 return TRUE; 80} 81 82/* 83 * Check whether an entire bitmap line is a repetition of 84 * the first 'len' bits 85 */ 86static Bool 87fbLineRepeat(FbBits * bits, int len, int width) 88{ 89 FbBits first = bits[0]; 90 91 if (!fbBitsRepeat(first, len, width)) 92 return FALSE; 93 width = (width + FB_UNIT - 1) >> FB_SHIFT; 94 bits++; 95 while (--width) 96 if (READ(bits) != first) 97 return FALSE; 98 return TRUE; 99} 100 101/* 102 * The even stipple code wants the first FB_UNIT/bpp bits on 103 * each scanline to represent the entire stipple 104 */ 105static Bool 106fbCanEvenStipple(PixmapPtr pStipple, int bpp) 107{ 108 int len = FB_UNIT / bpp; 109 FbBits *bits; 110 int stride; 111 int stip_bpp; 112 _X_UNUSED int stipXoff, stipYoff; 113 int h; 114 115 /* make sure the stipple width is a multiple of the even stipple width */ 116 if (pStipple->drawable.width % len != 0) 117 return FALSE; 118 119 fbGetDrawable(&pStipple->drawable, bits, stride, stip_bpp, stipXoff, 120 stipYoff); 121 h = pStipple->drawable.height; 122 /* check to see that the stipple repeats horizontally */ 123 while (h--) { 124 if (!fbLineRepeat(bits, len, pStipple->drawable.width)) 125 return FALSE; 126 127 bits += stride; 128 } 129 return TRUE; 130} 131 132void 133fbValidateGC(GCPtr gc, unsigned long changes, DrawablePtr drawable) 134{ 135 FbGCPrivPtr pgc = fb_gc(gc); 136 FbBits mask; 137 138 DBG(("%s changes=%lx\n", __FUNCTION__, changes)); 139 140 if (changes & GCStipple) { 141 pgc->evenStipple = FALSE; 142 143 if (gc->stipple) { 144 /* can we do an even stipple ?? */ 145 if (FbEvenStip(gc->stipple->drawable.width, 146 drawable->bitsPerPixel) && 147 (fbCanEvenStipple(gc->stipple, drawable->bitsPerPixel))) 148 pgc->evenStipple = TRUE; 149 } 150 } 151 152 /* 153 * Recompute reduced rop values 154 */ 155 if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) { 156 int s; 157 FbBits depthMask; 158 159 mask = FbFullMask(drawable->bitsPerPixel); 160 depthMask = FbFullMask(drawable->depth); 161 162 DBG(("%s: computing rrop mask=%08x, depthMask=%08x, fg=%08x, bg=%08x, planemask=%08x\n", 163 __FUNCTION__, mask, depthMask, (int)gc->fgPixel, (int)gc->bgPixel, (int)gc->planemask)); 164 165 pgc->fg = gc->fgPixel & mask; 166 pgc->bg = gc->bgPixel & mask; 167 168 if ((gc->planemask & depthMask) == depthMask) 169 pgc->pm = mask; 170 else 171 pgc->pm = gc->planemask & mask; 172 173 s = drawable->bitsPerPixel; 174 while (s < FB_UNIT) { 175 pgc->fg |= pgc->fg << s; 176 pgc->bg |= pgc->bg << s; 177 pgc->pm |= pgc->pm << s; 178 s <<= 1; 179 } 180 pgc->and = fbAnd(gc->alu, pgc->fg, pgc->pm); 181 pgc->xor = fbXor(gc->alu, pgc->fg, pgc->pm); 182 pgc->bgand = fbAnd(gc->alu, pgc->bg, pgc->pm); 183 pgc->bgxor = fbXor(gc->alu, pgc->bg, pgc->pm); 184 185 DBG(("%s: rrop fg=%08x, bg=%08x, pm=%08x, and=%08x, xor=%08x, bgand=%08x, bgxor=%08x\n", 186 __FUNCTION__, pgc->fg, pgc->bg, pgc->pm, pgc->and, pgc->xor, pgc->bgand, pgc->bgxor)); 187 } 188 189 if (changes & GCDashList) { 190 unsigned short n = gc->numInDashList; 191 unsigned char *dash = gc->dash; 192 unsigned int dashLength = 0; 193 194 while (n--) 195 dashLength += (unsigned int) *dash++; 196 pgc->dashLength = dashLength; 197 } 198} 199