2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
6 /****************************************************************************************/
8 #include <cybergraphx/cybergraphics.h>
9 #include <graphics/rpattr.h>
10 #include <proto/exec.h>
11 #include <proto/graphics.h>
12 #include <proto/layers.h>
13 #include <proto/oop.h>
14 #include <clib/macros.h>
16 #include "graphics_intern.h"
18 #include "intregions.h"
19 #include "gfxfuncsupport.h"
20 #include "graphics_driver.h"
23 #include <aros/debug.h>
25 #define DEBUG_PLANARBM(x)
27 /****************************************************************************************/
29 OOP_Object
*get_planarbm_object(struct BitMap
*bitmap
, struct GfxBase
*GfxBase
)
33 DEBUG_PLANARBM(bug("get_planarbm_object()\n"));
34 pbm_obj
= obtain_cache_object(CDD(GfxBase
)->planarbm_cache
, GfxBase
);
39 DEBUG_PLANARBM(bug("Got cache object %p, class=%s, instoffset=%d\n"
41 , OOP_OCLASS(pbm_obj
)->ClassNode
.ln_Name
42 , OOP_OCLASS(pbm_obj
)->InstOffset
45 if (!HIDD_PlanarBM_SetBitMap(pbm_obj
, bitmap
))
47 DEBUG_PLANARBM(bug("!!! get_planarbm_object: HIDD_PlanarBM_SetBitMap FAILED !!!\n"));
48 release_cache_object(CDD(GfxBase
)->planarbm_cache
, pbm_obj
, GfxBase
);
55 DEBUG_PLANARBM(bug("!!! get_planarbm_object: obtain_cache_object FAILED !!!\n"));
61 /****************************************************************************************/
63 static ULONG
CallRenderFunc(RENDERFUNC render_func
, APTR funcdata
, WORD srcx
, WORD srcy
,
64 struct BitMap
*bm
, OOP_Object
*gc
, struct Rectangle
*rect
, BOOL do_update
,
65 struct GfxBase
*GfxBase
)
67 OOP_Object
*bm_obj
= OBTAIN_HIDD_BM(bm
);
73 pixwritten
= render_func(funcdata
, srcx
, srcy
, bm_obj
, gc
, rect
, GfxBase
);
76 update_bitmap(bm
, bm_obj
, rect
->MinX
, rect
->MinY
,
77 rect
->MaxX
- rect
->MinX
+ 1, rect
->MaxY
- rect
->MinY
+ 1,
80 RELEASE_HIDD_BM(bm_obj
, bm
);
84 ULONG
do_render_func(struct RastPort
*rp
, Point
*src
, struct Rectangle
*rr
,
85 RENDERFUNC render_func
, APTR funcdata
,
86 BOOL do_update
, BOOL get_special_info
, struct GfxBase
*GfxBase
)
88 OOP_Object
*gc
= GetDriverData(rp
, GfxBase
);
90 return do_render_with_gc(rp
, src
, rr
, render_func
, funcdata
, gc
, do_update
, get_special_info
, GfxBase
);
94 * GetDriverData() resets the GC to RastPort's values.
95 * This is another entry point which avoids that. Use it if you have already set up GC.
97 ULONG
do_render_with_gc(struct RastPort
*rp
, Point
*src
, struct Rectangle
*rr
,
98 RENDERFUNC render_func
, APTR funcdata
, OOP_Object
*gc
,
99 BOOL do_update
, BOOL get_special_info
, struct GfxBase
*GfxBase
)
102 struct BitMap
*bm
= rp
->BitMap
;
103 struct Layer
*L
= rp
->Layer
;
104 struct Rectangle rp_clip_rectangle
;
105 BOOL have_rp_cliprectangle
;
121 /* No layer, probably a screen, but may be a user inited bitmap */
122 struct Rectangle torender
= *rr
;
124 have_rp_cliprectangle
= GetRPClipRectangleForBitMap(rp
, bm
, &rp_clip_rectangle
, GfxBase
);
125 if (have_rp_cliprectangle
&& !(_AndRectRect(rr
, &rp_clip_rectangle
, &torender
)))
130 srcx
+= (torender
.MinX
- rr
->MinX
);
131 srcy
+= (torender
.MinY
- rr
->MinY
);
133 if (get_special_info
)
135 RSI(funcdata
)->curbm
= rp
->BitMap
;
138 pixwritten
= CallRenderFunc(render_func
, funcdata
, srcx
, srcy
,
139 bm
, gc
, &torender
, do_update
, GfxBase
);
146 struct Rectangle torender
, intersect
;
150 have_rp_cliprectangle
= GetRPClipRectangleForLayer(rp
, L
, &rp_clip_rectangle
, GfxBase
);
152 xrel
= L
->bounds
.MinX
;
153 yrel
= L
->bounds
.MinY
;
155 torender
.MinX
= rr
->MinX
+ xrel
- L
->Scroll_X
;
156 torender
.MinY
= rr
->MinY
+ yrel
- L
->Scroll_Y
;
157 torender
.MaxX
= rr
->MaxX
+ xrel
- L
->Scroll_X
;
158 torender
.MaxY
= rr
->MaxY
+ yrel
- L
->Scroll_Y
;
162 for (;NULL
!= CR
; CR
= CR
->Next
)
164 D(bug("Cliprect (%d, %d, %d, %d), lobs=%p\n",
165 CR
->bounds
.MinX
, CR
->bounds
.MinY
, CR
->bounds
.MaxX
, CR
->bounds
.MaxY
,
168 /* Does this cliprect intersect with area to rectfill ? */
169 if (_AndRectRect(&CR
->bounds
, &torender
, &intersect
))
171 if (!have_rp_cliprectangle
|| _AndRectRect(&rp_clip_rectangle
, &intersect
, &intersect
))
173 WORD xoffset
, yoffset
;
175 xoffset
= intersect
.MinX
- torender
.MinX
;
176 yoffset
= intersect
.MinY
- torender
.MinY
;
178 if (NULL
== CR
->lobs
)
180 if (get_special_info
)
182 RSI(funcdata
)->curbm
= bm
;
185 pixwritten
+= CallRenderFunc(render_func
, funcdata
, srcx
+ xoffset
, srcy
+ yoffset
,
186 bm
, gc
, &intersect
, do_update
, GfxBase
);
190 /* Render into offscreen cliprect bitmap */
191 if (L
->Flags
& LAYERSIMPLE
)
193 else if (L
->Flags
& LAYERSUPER
)
195 D(bug("do_render_func(): Superbitmap not handled yet\n"));
200 if (get_special_info
)
202 RSI(funcdata
)->curbm
= CR
->BitMap
;
205 intersect
.MinX
= intersect
.MinX
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
);
206 intersect
.MinY
= intersect
.MinY
- CR
->bounds
.MinY
;
207 intersect
.MaxX
= intersect
.MaxX
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
);
208 intersect
.MaxY
= intersect
.MaxY
- CR
->bounds
.MinY
;
210 pixwritten
+= CallRenderFunc(render_func
, funcdata
, srcx
+ xoffset
, srcy
+ yoffset
,
211 CR
->BitMap
, gc
, &intersect
, do_update
, GfxBase
);
214 } /* if (CR->lobs == NULL) */
216 } /* if it also intersects with possible rastport clip rectangle */
218 } /* if (cliprect intersects with area to render into) */
220 } /* for (each cliprect in the layer) */
223 } /* if (rp->Layer) */
228 /****************************************************************************************/
230 static LONG
CallPixelFunc(PIXELFUNC render_func
, APTR funcdata
, struct BitMap
*bm
, OOP_Object
*gc
,
231 WORD x
, WORD y
, BOOL do_update
, struct GfxBase
*GfxBase
)
233 OOP_Object
*bm_obj
= OBTAIN_HIDD_BM(bm
);
239 retval
= render_func(funcdata
, bm_obj
, gc
, x
, y
, GfxBase
);
242 update_bitmap(bm
, bm_obj
, x
, y
, 1, 1, GfxBase
);
244 RELEASE_HIDD_BM(bm_obj
, bm
);
248 ULONG
do_pixel_func(struct RastPort
*rp
250 , PIXELFUNC render_func
253 , struct GfxBase
*GfxBase
)
255 struct BitMap
*bm
= rp
->BitMap
;
256 struct Layer
*L
= rp
->Layer
;
258 struct Rectangle rp_clip_rectangle
;
259 BOOL have_rp_cliprectangle
;
262 gc
= GetDriverData(rp
, GfxBase
);
266 have_rp_cliprectangle
= GetRPClipRectangleForBitMap(rp
, bm
, &rp_clip_rectangle
, GfxBase
);
267 if (have_rp_cliprectangle
&& !_IsPointInRect(&rp_clip_rectangle
, x
, y
))
272 #if 0 /* With enabled BITMAP_CLIPPING this will be done automatically */
273 OOP_GetAttr(bm_obj
, aHidd_BitMap_Width
, &width
);
274 OOP_GetAttr(bm_obj
, aHidd_BitMap_Height
, &height
);
276 /* Check whether we it is inside the rastport */
286 /* This is a screen */
287 retval
= CallPixelFunc(render_func
, funcdata
, bm
, gc
, x
, y
, do_update
, GfxBase
);
296 have_rp_cliprectangle
= GetRPClipRectangleForLayer(rp
, L
, &rp_clip_rectangle
, GfxBase
);
300 absx
= x
+ L
->bounds
.MinX
- L
->Scroll_X
;
301 absy
= y
+ L
->bounds
.MinY
- L
->Scroll_Y
;
303 for (;NULL
!= CR
; CR
= CR
->Next
)
306 if ( absx
>= CR
->bounds
.MinX
307 && absy
>= CR
->bounds
.MinY
308 && absx
<= CR
->bounds
.MaxX
309 && absy
<= CR
->bounds
.MaxY
)
312 if (!have_rp_cliprectangle
|| _IsPointInRect(&rp_clip_rectangle
, absx
, absy
))
314 if (NULL
== CR
->lobs
)
316 retval
= CallPixelFunc(render_func
, funcdata
, bm
, gc
,
317 absx
, absy
, do_update
, GfxBase
);
321 /* This is the tricky one: render into offscreen cliprect bitmap */
322 if (L
->Flags
& LAYERSIMPLE
)
324 /* We cannot do anything */
328 else if (L
->Flags
& LAYERSUPER
)
330 D(bug("driver_WriteRGBPixel(): Superbitmap not handled yet\n"));
334 retval
= CallPixelFunc(render_func
, funcdata
, CR
->BitMap
, gc
,
335 absx
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
),
336 absy
- CR
->bounds
.MinY
,
338 } /* If (SMARTREFRESH cliprect) */
340 } /* if (intersecton inside hidden cliprect) */
342 } /* if point is also inside possible rastport clip rectangle */
344 /* The pixel was found and put inside one of the cliprects, just exit */
347 } /* if (cliprect intersects with area we want to draw to) */
349 } /* while (cliprects to examine) */
356 /****************************************************************************************/
358 ULONG
fillrect_render(APTR funcdata
, WORD srcx
, WORD srcy
,
359 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
,
360 struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
362 HIDD_BM_FillRect(dstbm_obj
, dst_gc
, rect
->MinX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
);
364 return (rect
->MaxX
- rect
->MinX
+ 1) * (rect
->MaxY
- rect
->MinY
+ 1);
367 /****************************************************************************************/
369 LONG
fillrect_pendrmd(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
,
370 HIDDT_Pixel pix
, HIDDT_DrawMode drmd
, BOOL do_update
, struct GfxBase
*GfxBase
)
375 gc
= GetDriverData(rp
, GfxBase
);
384 return do_render_with_gc(rp
, NULL
, &rr
, fillrect_render
, NULL
, gc
, do_update
, FALSE
, GfxBase
);
387 /****************************************************************************************/
389 BOOL
int_bltbitmap(struct BitMap
*srcBitMap
, OOP_Object
*srcbm_obj
, WORD xSrc
, WORD ySrc
,
390 struct BitMap
*dstBitMap
, OOP_Object
*dstbm_obj
, WORD xDest
, WORD yDest
,
391 WORD xSize
, WORD ySize
, ULONG minterm
, OOP_Object
*gfxhidd
, OOP_Object
*gc
,
392 struct GfxBase
*GfxBase
)
399 BOOL src_colmap_set
= FALSE
;
400 BOOL dst_colmap_set
= FALSE
;
402 BOOL colmaps_ok
= TRUE
;
404 drmd
= MINTERM_TO_GCDRMD(minterm
);
406 /* We must lock any HIDD_BM_SetColorMap calls */
409 /* Try to get a CLUT for the bitmaps */
410 if (IS_HIDD_BM(srcBitMap
))
412 //bug("driver_intbltbitmap: source is hidd bitmap\n");
413 if (NULL
!= HIDD_BM_COLMAP(srcBitMap
))
415 //bug("driver_intbltbitmap: source has colormap\n");
416 srcflags
|= FLG_HASCOLMAP
;
418 srcflags
|= GET_COLMOD_FLAGS(srcBitMap
);
422 //bug("driver_intbltbitmap: source is amiga bitmap\n");
424 srcflags
|= FLG_PALETTE
;
427 if (IS_HIDD_BM(dstBitMap
))
429 //bug("driver_intbltbitmap: dest is hidd bitmap\n");
430 if (NULL
!= HIDD_BM_COLMAP(dstBitMap
))
432 //bug("driver_intbltbitmap: dest has colormap\n");
433 dstflags
|= FLG_HASCOLMAP
;
435 dstflags
|= GET_COLMOD_FLAGS(dstBitMap
);
439 //bug("driver_intbltbitmap: dest is amiga bitmap\n");
441 dstflags
|= FLG_PALETTE
;
444 if ( (srcflags
== FLG_PALETTE
|| srcflags
== FLG_STATICPALETTE
))
446 /* palettized with no colmap. Neew to get a colmap from dest*/
447 if (dstflags
== FLG_TRUECOLOR
)
450 D(bug("!!! NO WAY GETTING PALETTE FOR src IN BltBitMap\n"));
455 else if (dstflags
== (FLG_TRUECOLOR
| FLG_HASCOLMAP
))
458 /* Use the dest colmap for src */
459 HIDD_BM_SetColorMap(srcbm_obj
, HIDD_BM_COLMAP(dstBitMap
));
461 src_colmap_set
= TRUE
;
467 for (idx = 0; idx < 256; idx ++)
468 bug("[%d]=%d ", idx, HIDD_CM_GetPixel(HIDD_BM_COLMAP(dstBitMap), idx));
474 if ( (dstflags
== FLG_PALETTE
|| dstflags
== FLG_STATICPALETTE
))
476 /* palettized with no pixtab. Nees to get a pixtab from dest*/
477 if (srcflags
== FLG_TRUECOLOR
)
479 D(bug("!!! NO WAY GETTING PALETTE FOR dst IN BltBitMap\n"));
484 else if (srcflags
== (FLG_TRUECOLOR
| FLG_HASCOLMAP
))
487 /* Use the src colmap for dst */
488 HIDD_BM_SetColorMap(dstbm_obj
, HIDD_BM_COLMAP(srcBitMap
));
490 dst_colmap_set
= TRUE
;
496 /* We need special treatment with drawmode Clear and
497 truecolor bitmaps, in order to set it to
498 colormap[0] instead of just 0
500 if ( (drmd
== vHidd_GC_DrawMode_Clear
)
501 && ( (dstflags
& (FLG_TRUECOLOR
| FLG_HASCOLMAP
)) == (FLG_TRUECOLOR
| FLG_HASCOLMAP
) ))
504 HIDDT_DrawMode old_drmd
;
507 struct TagItem frtags
[] =
509 { aHidd_GC_Foreground
, 0 },
510 { aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
514 OOP_GetAttr(gc
, aHidd_GC_DrawMode
, &old_drmd
);
515 OOP_GetAttr(gc
, aHidd_GC_Foreground
, &old_fg
);
517 frtags
[0].ti_Data
= HIDD_BM_PIXTAB(dstBitMap
)[0];
518 frtags
[1].ti_Data
= vHidd_GC_DrawMode_Copy
;
520 OOP_SetAttrs(gc
, frtags
);
522 HIDD_BM_FillRect(dstbm_obj
, gc
528 frtags
[0].ti_Data
= old_fg
;
529 frtags
[1].ti_Data
= old_drmd
;
534 HIDDT_DrawMode old_drmd
;
536 struct TagItem cbtags
[] =
538 { aHidd_GC_DrawMode
, 0 },
542 OOP_GetAttr(gc
, aHidd_GC_DrawMode
, &old_drmd
);
544 cbtags
[0].ti_Data
= drmd
;
546 OOP_SetAttrs(gc
, cbtags
);
547 HIDD_Gfx_CopyBox(gfxhidd
556 cbtags
[0].ti_Data
= drmd
;
557 OOP_SetAttrs(gc
, cbtags
);
560 } /* if (colmaps_ok) */
563 HIDD_BM_SetColorMap(srcbm_obj
, NULL
);
566 HIDD_BM_SetColorMap(dstbm_obj
, NULL
);
574 /****************************************************************************************/
576 struct wp8_render_data
580 HIDDT_PixelLUT
*pixlut
;
583 static ULONG
wp8_render(APTR wp8r_data
, WORD srcx
, WORD srcy
, OOP_Object
*dstbm_obj
,
584 OOP_Object
*dst_gc
, struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
586 struct wp8_render_data
*wp8rd
= wp8r_data
;
587 WORD width
= rect
->MaxX
- rect
->MinX
+ 1;
588 WORD height
= rect
->MaxY
- rect
->MinY
+ 1;
590 HIDD_BM_PutImageLUT(dstbm_obj
, dst_gc
,
591 wp8rd
->array
+ CHUNKY8_COORD_TO_BYTEIDX(srcx
, srcy
, wp8rd
->modulo
), wp8rd
->modulo
,
592 rect
->MinX
, rect
->MinY
, width
, height
, wp8rd
->pixlut
);
594 return width
* height
;
597 /****************************************************************************************/
599 LONG
write_pixels_8(struct RastPort
*rp
, UBYTE
*array
, ULONG modulo
,
600 WORD xstart
, WORD ystart
, WORD xstop
, WORD ystop
,
601 HIDDT_PixelLUT
*pixlut
, BOOL do_update
, struct GfxBase
*GfxBase
)
603 struct wp8_render_data wp8rd
;
606 HIDDT_PixelLUT bm_lut
;
608 /* If we haven't got a LUT, we obtain it from the bitmap */
609 if ((!pixlut
) && IS_HIDD_BM(rp
->BitMap
))
611 bm_lut
.entries
= AROS_PALETTE_SIZE
;
612 bm_lut
.pixels
= HIDD_BM_PIXTAB(rp
->BitMap
);
615 #ifdef RTG_SANITY_CHECK
616 if ((!bm_lut
.pixels
) && (HIDD_BM_REALDEPTH(rp
->BitMap
) > 8))
618 D(bug("write_pixels_8: can't work on hicolor/truecolor screen without LUT"));
624 gc
= GetDriverData(rp
, GfxBase
);
625 GC_DRMD(gc
) = vHidd_GC_DrawMode_Copy
;
627 wp8rd
.modulo
= modulo
;
629 wp8rd
.pixlut
= pixlut
;
636 return do_render_with_gc(rp
, NULL
, &rr
, wp8_render
, &wp8rd
, gc
, do_update
, FALSE
, GfxBase
);
639 /****************************************************************************************/
641 struct wtp8_render_data
645 HIDDT_PixelLUT
*pixlut
;
649 static ULONG
wtp8_render(APTR wtp8r_data
, WORD srcx
, WORD srcy
, OOP_Object
*dstbm_obj
,
650 OOP_Object
*dst_gc
, struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
652 struct wtp8_render_data
*wtp8rd
= wtp8r_data
;
653 WORD width
= rect
->MaxX
- rect
->MinX
+ 1;
654 WORD height
= rect
->MaxY
- rect
->MinY
+ 1;
656 HIDD_BM_PutTranspImageLUT(dstbm_obj
, dst_gc
,
657 wtp8rd
->array
+ CHUNKY8_COORD_TO_BYTEIDX(srcx
, srcy
, wtp8rd
->modulo
), wtp8rd
->modulo
,
658 rect
->MinX
, rect
->MinY
,width
, height
, wtp8rd
->pixlut
, wtp8rd
->transparent
);
660 return width
* height
;
662 /****************************************************************************************/
664 LONG
write_transp_pixels_8(struct RastPort
*rp
, UBYTE
*array
, ULONG modulo
,
665 WORD xstart
, WORD ystart
, WORD xstop
, WORD ystop
,
666 HIDDT_PixelLUT
*pixlut
, UBYTE transparent
,
667 BOOL do_update
, struct GfxBase
*GfxBase
)
669 struct wtp8_render_data wtp8rd
;
673 gc
= GetDriverData(rp
, GfxBase
);
674 GC_DRMD(gc
) = vHidd_GC_DrawMode_Copy
;
676 wtp8rd
.modulo
= modulo
;
677 wtp8rd
.array
= array
;
678 wtp8rd
.pixlut
= pixlut
;
679 wtp8rd
.transparent
= transparent
;
686 return do_render_with_gc(rp
, NULL
, &rr
, wtp8_render
, &wtp8rd
, gc
, do_update
, FALSE
, GfxBase
);
689 /****************************************************************************************/
692 ** General functions for moving blocks of data to or from HIDDs, be it pixelarrays
693 ** or bitmaps. They use a callback-function to get data from amiga/put data to amiga
694 ** bitmaps/pixelarrays
697 /****************************************************************************************/
699 /****************************************************************************************/
701 #define ENABLE_PROFILING 0
702 #define USE_OLD_MoveRaster 0
704 #define rdtscll(val) \
705 __asm__ __volatile__("rdtsc" : "=A" (val))
707 #if ENABLE_PROFILING && defined(__i386__)
710 #define AROS_BEGIN_PROFILING(context) \
712 unsigned long long _time1, _time2; \
713 char *_text = #context; \
717 #define AROS_END_PROFILING \
720 kprintf("%s: Ticks count: %u\n", _text, (unsigned long)(_time2 - _time1)); \
725 #define AROS_BEGIN_PROFILING(context)
726 #define AROS_END_PROFILING
730 BOOL
MoveRaster (struct RastPort
* rp
, WORD dx
, WORD dy
, WORD x1
, WORD y1
,
731 WORD x2
, WORD y2
, BOOL UpdateDamageList
, struct GfxBase
* GfxBase
)
733 struct Layer
*L
= rp
->Layer
;
734 struct Rectangle ScrollRect
;
735 struct Rectangle Rect
;
737 if (0 == dx
&& 0 == dy
)
740 ScrollRect
.MinX
= x1
;
741 ScrollRect
.MinY
= y1
;
742 ScrollRect
.MaxX
= x2
;
743 ScrollRect
.MaxY
= y2
;
748 TranslateRect(&Rect
, -dx
, -dy
);
749 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
751 BltBitMap(rp
->BitMap
,
757 Rect
.MaxX
- Rect
.MinX
+ 1,
758 Rect
.MaxY
- Rect
.MinY
+ 1,
766 struct ClipRect
*SrcCR
;
770 if (L
->Flags
& LAYERSIMPLE
&& UpdateDamageList
)
772 /* Scroll the old damagelist within the scroll area */
773 ScrollRegion(L
->DamageList
, &ScrollRect
, -dx
, -dy
);
776 /* The scrolling area is relative to the Layer, so make it relative to the screen */
777 TranslateRect(&ScrollRect
, MinX(L
), MinY(L
));
779 /* The damage list will be formed by the now hidden layer's parts that will become visible due
780 to the scrolling procedure, thus we procede this way:
782 1) Calculate the invisible region out of the visible one, subtracting it from the
785 2) Scroll the invisible region by (-dx, -dy) and then subtract from it the not scrolled equivalent
787 The regions that we obtain after (2) is the new damage list
790 if (L
->Flags
& LAYERSIMPLE
&& UpdateDamageList
)
794 TranslateRect(&Rect
, dx
, dy
);
796 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
798 struct Region
*Damage
= NewRegion();
803 BOOL res
= OrRectRegion(Damage
, &ScrollRect
);
805 BOOL res
= OrRectRegion(Damage
, &Rect
);
809 DisposeRegion(Damage
);
818 ClearRegionRegion(L
->VisibleRegion
, Damage
)
820 Damage
->RegionRectangle
825 We play sort of dirty here, by making assumptions about the internals of the
826 Region structure and the region handling functions, but we are allowed to do that,
832 TranslateRect(Bounds(Damage
), -dx
, -dy
);
836 ClearRegionRegion(&Tmp
, Damage
)
838 Damage
->RegionRectangle
842 AndRectRegion(Damage
, &ScrollRect
);
843 if (Damage
->RegionRectangle
)
847 /* Join the new damage list with the old one */
848 TranslateRect(Bounds(Damage
), -MinX(L
), -MinY(L
));
849 OrRegionRegion(Damage
, L
->DamageList
);
851 L
->Flags
|= LAYERREFRESH
;
856 DisposeRegion(Damage
);
861 AROS_BEGIN_PROFILING(SortLayerCR
)
863 #define LayersBase (struct LayersBase *)(GfxBase->gb_LayersBase)
864 SortLayerCR(L
, dx
, dy
);
869 AROS_BEGIN_PROFILING(Blitting loop
)
871 #if USE_OLDMoveRaster
874 struct ClipRect
*LastHiddenCR
;
876 for (LastHiddenCR
= NULL
, SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
878 SrcCR
->_p1
= LastHiddenCR
;
881 LastHiddenCR
= SrcCR
;
886 for (SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
890 if (SrcCR
->lobs
&& (L
->Flags
& LAYERSIMPLE
))
895 if (_AndRectRect(&ScrollRect
, Bounds(SrcCR
), &Rect
))
897 TranslateRect(&Rect
, -dx
, -dy
);
899 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
905 /* Rect.Min(X|Y) are the coordinates to wich the rectangle has to be moved
906 Rect.Max(X|Y) - Rect.Max(X|Y) - 1 are the dimensions of this rectangle */
907 if (!SrcCR
->_p1
&& !SrcCR
->lobs
)
909 /* there are no hidden/obscured rectangles this recrtangle has to deal with*/
918 Rect
.MaxX
- Rect
.MinX
+ 1,
919 Rect
.MaxY
- Rect
.MinY
+ 1,
927 struct BitMap
*srcbm
;
928 struct RegionRectangle
*rr
;
929 struct Region
*RectRegion
= NewRegion();
930 struct Rectangle Tmp
;
931 struct ClipRect
*HiddCR
;
932 WORD corrsrcx
, corrsrcy
;
938 if (!OrRectRegion(&Rect
, RectRegion
))
940 DisposeRegion(RectRegion
);
946 if (L
->Flags
& LAYERSUPER
)
948 corrsrcx
= - MinX(L
) - L
->Scroll_X
;
949 corrsrcy
= - MinY(L
) - L
->Scroll_Y
;
953 corrsrcx
= - MinX(SrcCR
) + ALIGN_OFFSET(MinX(SrcCR
));
954 corrsrcy
= - MinY(SrcCR
);
956 srcbm
= SrcCR
->BitMap
;
965 for (HiddCR
= SrcCR
->_p1
; HiddCR
; HiddCR
= HiddCR
->_p1
)
967 if (_AndRectRect(Bounds(RectRegion
), Bounds(HiddCR
), &Tmp
))
969 if (!(L
->Flags
& LAYERSIMPLE
))
971 WORD corrdstx
, corrdsty
;
973 if (L
->Flags
& LAYERSUPER
)
975 corrdstx
= - MinX(L
) - L
->Scroll_X
;
976 corrdsty
= - MinY(L
) - L
->Scroll_Y
;
981 corrdstx
= - MinX(HiddCR
) + ALIGN_OFFSET(MinX(HiddCR
));
982 corrdsty
= - MinY(HiddCR
);
989 Tmp
.MinX
+ corrsrcx
+ dx
,
990 Tmp
.MinY
+ corrsrcy
+ dy
,
994 Tmp
.MaxX
- Tmp
.MinX
+ 1,
995 Tmp
.MaxY
- Tmp
.MinY
+ 1,
1002 if (!ClearRectRegion(RectRegion
, &Tmp
))
1004 DisposeRegion(RectRegion
);
1010 if ((dosrcsrc
= _AndRectRect(Bounds(SrcCR
), &Rect
, &Tmp
)))
1012 if (!ClearRectRegion(RectRegion
, &Tmp
))
1014 DisposeRegion(RectRegion
);
1019 for (rr
= RectRegion
->RegionRectangle
; rr
; rr
= rr
->Next
)
1024 MinX(rr
) + MinX(RectRegion
) + corrsrcx
+ dx
,
1025 MinY(rr
) + MinY(RectRegion
) + corrsrcy
+ dy
,
1027 MinX(rr
) + MinX(RectRegion
),
1028 MinY(rr
) + MinY(RectRegion
),
1042 Tmp
.MinX
+ corrsrcx
+ dx
,
1043 Tmp
.MinY
+ corrsrcy
+ dy
,
1045 Tmp
.MinX
+ corrsrcx
,
1046 Tmp
.MinY
+ corrsrcy
,
1047 Tmp
.MaxX
- Tmp
.MinX
+ 1,
1048 Tmp
.MaxY
- Tmp
.MinY
+ 1,
1056 DisposeRegion(RectRegion
);
1063 for (SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
1065 if (_AndRectRect(&ScrollRect
, Bounds(SrcCR
), &Rect
))
1067 TranslateRect(&Rect
, -dx
, -dy
);
1069 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
1071 struct BitMap
*srcbm
;
1072 struct ClipRect
*DstCR
;
1073 WORD corrsrcx
, corrsrcy
;
1078 if (L
->Flags
& LAYERSIMPLE
) continue;
1080 if (L
->Flags
& LAYERSUPER
)
1082 corrsrcx
= - MinX(L
) - L
->Scroll_X
;
1083 corrsrcy
= - MinY(L
) - L
->Scroll_Y
;
1087 corrsrcx
= - MinX(SrcCR
) + ALIGN_OFFSET(MinX(SrcCR
));
1088 corrsrcy
= - MinY(SrcCR
);
1090 srcbm
= SrcCR
->BitMap
;
1099 area
= (Rect
.MaxX
- Rect
.MinX
+ 1) * (Rect
.MaxY
- Rect
.MinY
+ 1);
1101 for (DstCR
= L
->ClipRect
; area
&& DstCR
; DstCR
= DstCR
->Next
)
1103 struct Rectangle Rect2
;
1105 if (_AndRectRect(Bounds(DstCR
), &Rect
, &Rect2
))
1107 struct BitMap
*dstbm
;
1108 WORD corrdstx
, corrdsty
;
1110 area
-= (Rect2
.MaxX
- Rect2
.MinX
+ 1) * (Rect2
.MaxY
- Rect2
.MinY
+ 1);
1114 if (L
->Flags
& LAYERSIMPLE
) continue;
1116 if (L
->Flags
& LAYERSUPER
)
1118 corrdstx
= - MinX(L
) - L
->Scroll_X
;
1119 corrdsty
= - MinY(L
) - L
->Scroll_Y
;
1123 corrdstx
= - MinX(DstCR
) + ALIGN_OFFSET(MinX(DstCR
));
1124 corrdsty
= - MinY(DstCR
);
1126 dstbm
= DstCR
->BitMap
;
1138 Rect2
.MinX
+ corrsrcx
+ dx
,
1139 Rect2
.MinY
+ corrsrcy
+ dy
,
1141 Rect2
.MinX
+ corrdstx
,
1142 Rect2
.MinY
+ corrdsty
,
1143 Rect2
.MaxX
- Rect2
.MinX
+ 1,
1144 Rect2
.MaxY
- Rect2
.MinY
+ 1,
1163 /****************************************************************************************/
1165 BOOL
GetRPClipRectangleForRect(struct RastPort
*rp
, struct Rectangle
*rect
, struct Rectangle
*r
)
1167 struct gfx_driverdata
*dd
= ObtainDriverData(rp
);
1169 if (dd
&& dd
->dd_ClipRectangleFlags
& RPCRF_VALID
)
1171 *r
= dd
->dd_ClipRectangle
;
1173 if (dd
->dd_ClipRectangleFlags
& RPCRF_RELRIGHT
)
1175 r
->MaxX
+= rect
->MaxX
- rect
->MinX
;
1178 if (dd
->dd_ClipRectangleFlags
& RPCRF_RELBOTTOM
)
1180 r
->MaxY
+= rect
->MaxY
- rect
->MinY
;
1183 r
->MinX
+= rect
->MinX
;
1184 r
->MinY
+= rect
->MinY
;
1185 r
->MaxX
+= rect
->MinX
;
1186 r
->MaxY
+= rect
->MinY
;
1194 /****************************************************************************************/
1196 BOOL
GetRPClipRectangleForBitMap(struct RastPort
*rp
, struct BitMap
*bm
,
1197 struct Rectangle
*r
, struct GfxBase
*GfxBase
)
1199 struct Rectangle bm_rect
;
1204 bm_rect
.MaxX
= GetBitMapAttr(bm
, BMA_WIDTH
) - 1;
1205 bm_rect
.MaxY
= GetBitMapAttr(bm
, BMA_HEIGHT
) - 1;
1207 res
= GetRPClipRectangleForRect(rp
, &bm_rect
, r
);
1213 * Set the rectangle to total bitmap size. This prevents trashing memory
1214 * by hitting unallocated memory in HIDDs. They don't check bitmap bounds.