Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / rom / graphics / bltmaskbitmaprastport.c
blobc72076a7015abc95c405711fdbc4048997780530
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include <aros/debug.h>
9 #include <proto/graphics.h>
10 #include <proto/oop.h>
11 #include "graphics_intern.h"
12 #include "gfxfuncsupport.h"
13 #include <hardware/blit.h>
15 /* Nominal size of the pixel conversion buffer
17 #ifdef __mc68000
18 #define NUMPIX 4096 /* Not that much room to spare */
19 #else
20 #define NUMPIX 100000
21 #endif
23 struct bltmask_render_data
25 struct render_special_info rsi;
26 struct BitMap *srcbm;
27 OOP_Object *srcbm_obj;
28 OOP_Object *srcpf;
29 HIDDT_ColorModel src_colmod;
30 PLANEPTR mask;
31 ULONG mask_bpr;
32 ULONG minterm;
33 BOOL samebitmapformat;
36 static ULONG bltmask_render(APTR bltmask_rd, LONG srcx, LONG srcy,
37 OOP_Object *dstbm_obj, OOP_Object *dst_gc,
38 LONG x1, LONG y1, LONG x2, LONG y2, struct GfxBase *GfxBase);
40 /*****************************************************************************
42 NAME */
43 #include <clib/graphics_protos.h>
45 AROS_LH10(void, BltMaskBitMapRastPort,
47 /* SYNOPSIS */
48 AROS_LHA(struct BitMap *, srcBitMap, A0),
49 AROS_LHA(LONG , xSrc, D0),
50 AROS_LHA(LONG , ySrc, D1),
51 AROS_LHA(struct RastPort *, destRP, A1),
52 AROS_LHA(LONG , xDest, D2),
53 AROS_LHA(LONG , yDest, D3),
54 AROS_LHA(LONG , xSize, D4),
55 AROS_LHA(LONG , ySize, D5),
56 AROS_LHA(ULONG , minterm, D6),
57 AROS_LHA(PLANEPTR , bltMask, A2),
59 /* LOCATION */
60 struct GfxBase *, GfxBase, 106, Graphics)
62 /* FUNCTION
63 Copies a part of a bitmap to another bitmap with using a mask.
65 INPUTS
66 srcBitMap - Copy from this bitmap.
67 xSrc, ySrc - This is the upper left corner of the area to copy.
68 destRP - Destination RastPort.
69 xDest, yDest - Upper left corner where to place the copy
70 xSize, ySize - The size of the area to copy
71 minterm - How to copy. See BltBitMap() for an explanation.
72 bltMask - The mask bitplane must be of the same size as the source bitmap.
74 RESULT
75 TRUE.
77 NOTES
79 EXAMPLE
81 BUGS
83 SEE ALSO
84 ClipBlit()
86 INPUTS
88 RESULT
90 NOTES
92 INTERNALS
94 HISTORY
95 27-11-96 digulla automatically created from
96 graphics_lib.fd and clib/graphics_protos.h
98 *****************************************************************************/
100 AROS_LIBFUNC_INIT
102 struct bltmask_render_data brd;
103 struct Rectangle rr;
104 HIDDT_DrawMode old_drmd;
105 OOP_Object *gc;
106 Point src;
108 struct TagItem gc_tags[] =
110 { aHidd_GC_DrawMode , 0UL },
111 { TAG_DONE }
114 EnterFunc(bug("BltMaskBitMapRastPort(%d %d %d, %d, %d, %d)\n"
115 , xSrc, ySrc, xDest, yDest, xSize, ySize));
117 FIX_GFXCOORD(xSrc);
118 FIX_GFXCOORD(ySrc);
119 FIX_GFXCOORD(xDest);
120 FIX_GFXCOORD(yDest);
122 if ((xSize < 1) || (ySize < 1)) return;
124 if (!OBTAIN_DRIVERDATA(destRP, GfxBase))
125 return;
127 brd.minterm = minterm;
128 brd.srcbm_obj = OBTAIN_HIDD_BM(srcBitMap);
129 if (NULL == brd.srcbm_obj)
131 RELEASE_DRIVERDATA(destRP, GfxBase);
132 return;
135 brd.srcbm = srcBitMap;
136 brd.mask = bltMask;
138 /* The mask has always the same size as the source bitmap */
139 brd.mask_bpr = 2 * WIDTH_TO_WORDS(GetBitMapAttr(srcBitMap, BMA_WIDTH));
141 OOP_GetAttr(brd.srcbm_obj, aHidd_BitMap_PixFmt, (IPTR *)&brd.srcpf);
143 IPTR attr;
145 OOP_GetAttr(brd.srcpf, aHidd_PixFmt_ColorModel, &attr);
146 brd.src_colmod = (HIDDT_ColorModel)attr;
149 gc = GetDriverData(destRP)->dd_GC;
150 OOP_GetAttr(gc, aHidd_GC_DrawMode, &old_drmd);
152 gc_tags[0].ti_Data = vHidd_GC_DrawMode_Copy;
153 OOP_SetAttrs(gc, gc_tags);
155 rr.MinX = xDest;
156 rr.MinY = yDest;
157 rr.MaxX = xDest + xSize - 1;
158 rr.MaxY = yDest + ySize - 1;
160 src.x = xSrc;
161 src.y = ySrc;
163 do_render_func(destRP, &src, &rr, bltmask_render, &brd, TRUE, TRUE, GfxBase);
165 RELEASE_HIDD_BM(brd.srcbm_obj, srcBitMap);
167 gc_tags[0].ti_Data = old_drmd;
168 OOP_SetAttrs(gc, gc_tags);
170 RELEASE_DRIVERDATA(destRP, GfxBase);
172 ReturnVoid("BltBitMapRastPort");
174 AROS_LIBFUNC_EXIT
176 } /* BltMaskBitMapRastPort */
178 /****************************************************************************************/
180 static ULONG bltmask_render(APTR bltmask_rd, LONG srcx, LONG srcy,
181 OOP_Object *dstbm_obj, OOP_Object *dst_gc,
182 LONG x1, LONG y1, LONG x2, LONG y2, struct GfxBase *GfxBase)
184 struct bltmask_render_data *brd;
185 OOP_Object *dest_pf;
186 HIDDT_ColorModel dest_colmod;
187 HIDDT_Pixel *pixtab = NULL;
188 ULONG x, y, width, height;
189 LONG lines_done, lines_per_step, doing_lines;
190 BOOL pal_to_true = FALSE;
191 ULONG pixfmt = vHidd_StdPixFmt_Native32;
192 UBYTE *srcbuf;
194 width = x2 - x1 + 1;
195 height = y2 - y1 + 1;
197 OOP_GetAttr(dstbm_obj, aHidd_BitMap_PixFmt, (IPTR *)&dest_pf);
199 IPTR attr;
201 OOP_GetAttr(dest_pf, aHidd_PixFmt_ColorModel, &attr);
202 dest_colmod = (HIDDT_ColorModel)attr;
205 brd = (struct bltmask_render_data *)bltmask_rd;
206 if ((brd->src_colmod == vHidd_ColorModel_Palette) && (dest_colmod == vHidd_ColorModel_Palette))
209 else if ((brd->src_colmod == vHidd_ColorModel_Palette) && (dest_colmod == vHidd_ColorModel_TrueColor))
211 pixtab = IS_HIDD_BM(brd->srcbm) ? HIDD_BM_PIXTAB(brd->srcbm) : NULL;
212 if (!pixtab) pixtab = IS_HIDD_BM(brd->rsi.curbm) ? HIDD_BM_PIXTAB(brd->rsi.curbm) : NULL;
214 if (!pixtab)
216 D(bug("BltMaskBitMapRastPort could not retrieve pixel table for blit from palette to truecolor bitmap"));
217 return width * height;
220 pal_to_true = TRUE;
222 else if ((brd->src_colmod == vHidd_ColorModel_TrueColor) && (dest_colmod == vHidd_ColorModel_TrueColor))
224 if (brd->srcpf != dest_pf)
226 pixfmt = vHidd_StdPixFmt_ARGB32;
229 else if ((brd->src_colmod == vHidd_ColorModel_TrueColor) && (dest_colmod == vHidd_ColorModel_Palette))
231 D(bug("BltMaskBitMapRastPort from truecolor bitmap to palette bitmap not supported!"));
232 return width * height;
235 /* Based on the NUMPIX advice, figure out how many
236 * lines per step we can allocate
238 lines_per_step = NUMPIX / (width * sizeof(HIDDT_Pixel));
239 if (lines_per_step == 0)
240 lines_per_step = 1;
242 /* Allocate a temporary buffer */
243 srcbuf = AllocMem(2 * lines_per_step * width * sizeof(HIDDT_Pixel), MEMF_ANY);
245 /* Try line-at-a-time if we can't allocate a big buffer */
246 if (!srcbuf && lines_per_step > 1) {
247 lines_per_step = 1;
248 srcbuf = AllocMem(2 * lines_per_step * width * sizeof(HIDDT_Pixel), MEMF_ANY);
251 if (srcbuf)
253 UBYTE *destbuf;
255 destbuf = srcbuf;
256 destbuf += lines_per_step * width * sizeof(HIDDT_Pixel);
258 for(lines_done = 0; lines_done != height; lines_done += doing_lines)
260 HIDDT_Pixel *srcpixelbuf;
261 HIDDT_Pixel *destpixelbuf;
262 UBYTE *mask;
264 doing_lines = lines_per_step;
265 if (lines_done + doing_lines > height) doing_lines = height - lines_done;
267 HIDD_BM_GetImage(brd->srcbm_obj,
268 srcbuf,
269 width * sizeof(HIDDT_Pixel),
270 srcx, srcy + lines_done,
271 width, doing_lines,
272 pixfmt);
274 HIDD_BM_GetImage(dstbm_obj,
275 destbuf,
276 width * sizeof(HIDDT_Pixel),
277 x1, y1 + lines_done,
278 width, doing_lines,
279 pixfmt);
281 mask = &brd->mask[COORD_TO_BYTEIDX(0, srcy + lines_done, brd->mask_bpr)];
283 srcpixelbuf = (HIDDT_Pixel *)srcbuf;
284 destpixelbuf = (HIDDT_Pixel *)destbuf;
286 switch(brd->minterm)
288 case (ABC|ABNC|ANBC): /* (ABC|ABNC|ANBC) if copy source and blit thru mask */
289 case 0xC0: /* compatibility with AOS3 */
290 if (pal_to_true)
292 for(y = 0; y < doing_lines; y++)
294 for(x = 0; x < width; x++)
296 if (mask[XCOORD_TO_BYTEIDX(srcx + x)] & XCOORD_TO_MASK(srcx + x))
298 *destpixelbuf = pixtab[*srcpixelbuf];
300 srcpixelbuf++;
301 destpixelbuf++;
303 mask += brd->mask_bpr;
306 else
308 for(y = 0; y < doing_lines; y++)
310 for(x = 0; x < width; x++)
312 if (mask[XCOORD_TO_BYTEIDX(srcx + x)] & XCOORD_TO_MASK(srcx + x))
314 *destpixelbuf = *srcpixelbuf;
316 srcpixelbuf++;
317 destpixelbuf++;
319 mask += brd->mask_bpr;
322 break;
324 case ANBC: /* (ANBC) if invert source and blit thru mask */
325 D(bug("BltMaskBitMapRastPort does not support ANBC minterm yet"));
326 break;
328 default:
329 D(bug("BltMaskBitMapRastPort: minterm 0x%x not handled.\n", brd->minterm));
330 break;
331 } /* switch(brd->minterm) */
333 HIDD_BM_PutImage(dstbm_obj,
334 dst_gc,
335 destbuf,
336 width * sizeof(HIDDT_Pixel),
337 x1, y1 + lines_done,
338 width, doing_lines,
339 pixfmt);
341 } /* for(lines_done = 0; lines_done != height; lines_done += doing_lines) */
343 /* Free our temporary buffer */
344 FreeMem(srcbuf, 2 * lines_per_step * width * sizeof(HIDDT_Pixel));
346 } /* if (lines_per_step) */
347 else
349 /* urk :-( pixelbuffer too small to hold two lines) */
351 D(bug("BltMaskBitMapRastPort found pixelbuffer to be too small"));
354 return width * height;
357 /****************************************************************************************/