fbcopy.c revision 1b5d61b8
1/* 2 * Copyright © 1998 Keith Packard 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Keith Packard not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Keith Packard makes no 11 * representations about the suitability of this software for any purpose. It 12 * is provided "as is" without express or implied warranty. 13 * 14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_DIX_CONFIG_H 24#include <dix-config.h> 25#endif 26 27#include <stdlib.h> 28 29#include "fb.h" 30 31void 32fbCopyNtoN(DrawablePtr pSrcDrawable, 33 DrawablePtr pDstDrawable, 34 GCPtr pGC, 35 BoxPtr pbox, 36 int nbox, 37 int dx, 38 int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) 39{ 40 CARD8 alu = pGC ? pGC->alu : GXcopy; 41 FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES; 42 FbBits *src; 43 FbStride srcStride; 44 int srcBpp; 45 int srcXoff, srcYoff; 46 FbBits *dst; 47 FbStride dstStride; 48 int dstBpp; 49 int dstXoff, dstYoff; 50 51 fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); 52 fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 53 54 while (nbox--) { 55#ifndef FB_ACCESS_WRAPPER /* pixman_blt() doesn't support accessors yet */ 56 if (pm == FB_ALLONES && alu == GXcopy && !reverse && !upsidedown) { 57 if (!pixman_blt 58 ((uint32_t *) src, (uint32_t *) dst, srcStride, dstStride, 59 srcBpp, dstBpp, (pbox->x1 + dx + srcXoff), 60 (pbox->y1 + dy + srcYoff), (pbox->x1 + dstXoff), 61 (pbox->y1 + dstYoff), (pbox->x2 - pbox->x1), 62 (pbox->y2 - pbox->y1))) 63 goto fallback; 64 else 65 goto next; 66 } 67 fallback: 68#endif 69 fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride, 70 srcStride, 71 (pbox->x1 + dx + srcXoff) * srcBpp, 72 dst + (pbox->y1 + dstYoff) * dstStride, 73 dstStride, 74 (pbox->x1 + dstXoff) * dstBpp, 75 (pbox->x2 - pbox->x1) * dstBpp, 76 (pbox->y2 - pbox->y1), alu, pm, dstBpp, reverse, upsidedown); 77#ifndef FB_ACCESS_WRAPPER 78 next: 79#endif 80 pbox++; 81 } 82 fbFinishAccess(pDstDrawable); 83 fbFinishAccess(pSrcDrawable); 84} 85 86void 87fbCopy1toN(DrawablePtr pSrcDrawable, 88 DrawablePtr pDstDrawable, 89 GCPtr pGC, 90 BoxPtr pbox, 91 int nbox, 92 int dx, 93 int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) 94{ 95 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 96 FbBits *src; 97 FbStride srcStride; 98 int srcBpp; 99 int srcXoff, srcYoff; 100 FbBits *dst; 101 FbStride dstStride; 102 int dstBpp; 103 int dstXoff, dstYoff; 104 105 fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); 106 fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 107 108 while (nbox--) { 109 if (dstBpp == 1) { 110 fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride, 111 srcStride, 112 (pbox->x1 + dx + srcXoff) * srcBpp, 113 dst + (pbox->y1 + dstYoff) * dstStride, 114 dstStride, 115 (pbox->x1 + dstXoff) * dstBpp, 116 (pbox->x2 - pbox->x1) * dstBpp, 117 (pbox->y2 - pbox->y1), 118 FbOpaqueStipple1Rop(pGC->alu, 119 pGC->fgPixel, pGC->bgPixel), 120 pPriv->pm, dstBpp, reverse, upsidedown); 121 } 122 else { 123 fbBltOne((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride), 124 srcStride * (FB_UNIT / FB_STIP_UNIT), 125 (pbox->x1 + dx + srcXoff), 126 dst + (pbox->y1 + dstYoff) * dstStride, 127 dstStride, 128 (pbox->x1 + dstXoff) * dstBpp, 129 dstBpp, 130 (pbox->x2 - pbox->x1) * dstBpp, 131 (pbox->y2 - pbox->y1), 132 pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor); 133 } 134 pbox++; 135 } 136 137 fbFinishAccess(pDstDrawable); 138 fbFinishAccess(pSrcDrawable); 139} 140 141void 142fbCopyNto1(DrawablePtr pSrcDrawable, 143 DrawablePtr pDstDrawable, 144 GCPtr pGC, 145 BoxPtr pbox, 146 int nbox, 147 int dx, 148 int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) 149{ 150 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 151 152 while (nbox--) { 153 if (pDstDrawable->bitsPerPixel == 1) { 154 FbBits *src; 155 FbStride srcStride; 156 int srcBpp; 157 int srcXoff, srcYoff; 158 159 FbStip *dst; 160 FbStride dstStride; 161 int dstBpp; 162 int dstXoff, dstYoff; 163 164 fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, 165 srcYoff); 166 fbGetStipDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, 167 dstYoff); 168 fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride, srcStride, 169 (pbox->x1 + dx + srcXoff) * srcBpp, srcBpp, 170 dst + (pbox->y1 + dstYoff) * dstStride, dstStride, 171 (pbox->x1 + dstXoff) * dstBpp, 172 (pbox->x2 - pbox->x1) * srcBpp, (pbox->y2 - pbox->y1), 173 (FbStip) pPriv->and, (FbStip) pPriv->xor, 174 (FbStip) pPriv->bgand, (FbStip) pPriv->bgxor, bitplane); 175 fbFinishAccess(pDstDrawable); 176 fbFinishAccess(pSrcDrawable); 177 } 178 else { 179 FbBits *src; 180 FbStride srcStride; 181 int srcBpp; 182 int srcXoff, srcYoff; 183 184 FbBits *dst; 185 FbStride dstStride; 186 int dstBpp; 187 int dstXoff, dstYoff; 188 189 FbStip *tmp; 190 FbStride tmpStride; 191 int width, height; 192 193 width = pbox->x2 - pbox->x1; 194 height = pbox->y2 - pbox->y1; 195 196 tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT); 197 tmp = xallocarray(tmpStride * height, sizeof(FbStip)); 198 if (!tmp) 199 return; 200 201 fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, 202 srcYoff); 203 fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, 204 dstYoff); 205 206 fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride, 207 srcStride, 208 (pbox->x1 + dx + srcXoff) * srcBpp, 209 srcBpp, 210 tmp, 211 tmpStride, 212 0, 213 width * srcBpp, 214 height, 215 fbAndStip(GXcopy, FB_ALLONES, FB_ALLONES), 216 fbXorStip(GXcopy, FB_ALLONES, FB_ALLONES), 217 fbAndStip(GXcopy, 0, FB_ALLONES), 218 fbXorStip(GXcopy, 0, FB_ALLONES), bitplane); 219 fbBltOne(tmp, 220 tmpStride, 221 0, 222 dst + (pbox->y1 + dstYoff) * dstStride, 223 dstStride, 224 (pbox->x1 + dstXoff) * dstBpp, 225 dstBpp, 226 width * dstBpp, 227 height, 228 pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor); 229 free(tmp); 230 231 fbFinishAccess(pDstDrawable); 232 fbFinishAccess(pSrcDrawable); 233 } 234 pbox++; 235 } 236} 237 238RegionPtr 239fbCopyArea(DrawablePtr pSrcDrawable, 240 DrawablePtr pDstDrawable, 241 GCPtr pGC, 242 int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut) 243{ 244 return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, 245 widthSrc, heightSrc, xOut, yOut, fbCopyNtoN, 0, 0); 246} 247 248RegionPtr 249fbCopyPlane(DrawablePtr pSrcDrawable, 250 DrawablePtr pDstDrawable, 251 GCPtr pGC, 252 int xIn, 253 int yIn, 254 int widthSrc, 255 int heightSrc, int xOut, int yOut, unsigned long bitplane) 256{ 257 if (pSrcDrawable->bitsPerPixel > 1) 258 return miDoCopy(pSrcDrawable, pDstDrawable, pGC, 259 xIn, yIn, widthSrc, heightSrc, 260 xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0); 261 else if (bitplane & 1) 262 return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, 263 widthSrc, heightSrc, xOut, yOut, fbCopy1toN, 264 (Pixel) bitplane, 0); 265 else 266 return miHandleExposures(pSrcDrawable, pDstDrawable, pGC, 267 xIn, yIn, 268 widthSrc, heightSrc, xOut, yOut); 269} 270