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/layers.h>
11 #include <proto/exec.h>
12 #include <proto/graphics.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 #define LayersBase (struct LayersBase *)(GfxBase->gb_LayersBase)
29 /****************************************************************************************/
31 OOP_Object
*get_planarbm_object(struct BitMap
*bitmap
, struct GfxBase
*GfxBase
)
35 DEBUG_PLANARBM(bug("get_planarbm_object()\n"));
36 pbm_obj
= obtain_cache_object(CDD(GfxBase
)->planarbm_cache
, GfxBase
);
41 DEBUG_PLANARBM(bug("Got cache object %p, class=%s, instoffset=%d\n"
43 , OOP_OCLASS(pbm_obj
)->ClassNode
.ln_Name
44 , OOP_OCLASS(pbm_obj
)->InstOffset
47 if (!HIDD_PlanarBM_SetBitMap(pbm_obj
, bitmap
))
49 DEBUG_PLANARBM(bug("!!! get_planarbm_object: HIDD_PlanarBM_SetBitMap FAILED !!!\n"));
50 release_cache_object(CDD(GfxBase
)->planarbm_cache
, pbm_obj
, GfxBase
);
57 DEBUG_PLANARBM(bug("!!! get_planarbm_object: obtain_cache_object FAILED !!!\n"));
63 /****************************************************************************************/
65 static ULONG
CallRenderFunc(RENDERFUNC render_func
, APTR funcdata
, WORD srcx
, WORD srcy
,
66 struct BitMap
*bm
, OOP_Object
*gc
, struct Rectangle
*rect
, BOOL do_update
,
67 struct GfxBase
*GfxBase
)
69 OOP_Object
*bm_obj
= OBTAIN_HIDD_BM(bm
);
75 pixwritten
= render_func(funcdata
, srcx
, srcy
, bm_obj
, gc
, rect
, GfxBase
);
78 update_bitmap(bm
, bm_obj
, rect
->MinX
, rect
->MinY
,
79 rect
->MaxX
- rect
->MinX
+ 1, rect
->MaxY
- rect
->MinY
+ 1,
82 RELEASE_HIDD_BM(bm_obj
, bm
);
86 ULONG
do_render_func(struct RastPort
*rp
, Point
*src
, struct Rectangle
*rr
,
87 RENDERFUNC render_func
, APTR funcdata
,
88 BOOL do_update
, BOOL get_special_info
, struct GfxBase
*GfxBase
)
90 OOP_Object
*gc
= GetDriverData(rp
, GfxBase
);
92 return do_render_with_gc(rp
, src
, rr
, render_func
, funcdata
, gc
, do_update
, get_special_info
, GfxBase
);
96 * GetDriverData() resets the GC to RastPort's values.
97 * This is another entry point which avoids that. Use it if you have already set up GC.
99 ULONG
do_render_with_gc(struct RastPort
*rp
, Point
*src
, struct Rectangle
*rr
,
100 RENDERFUNC render_func
, APTR funcdata
, OOP_Object
*gc
,
101 BOOL do_update
, BOOL get_special_info
, struct GfxBase
*GfxBase
)
104 struct BitMap
*bm
= rp
->BitMap
;
105 struct Layer
*L
= rp
->Layer
;
106 struct Rectangle rp_clip_rectangle
;
107 BOOL have_rp_cliprectangle
;
123 /* No layer, probably a screen, but may be a user inited bitmap */
124 struct Rectangle torender
= *rr
;
126 have_rp_cliprectangle
= GetRPClipRectangleForBitMap(rp
, bm
, &rp_clip_rectangle
, GfxBase
);
127 if (have_rp_cliprectangle
&& !(_AndRectRect(rr
, &rp_clip_rectangle
, &torender
)))
132 srcx
+= (torender
.MinX
- rr
->MinX
);
133 srcy
+= (torender
.MinY
- rr
->MinY
);
135 if (get_special_info
)
137 RSI(funcdata
)->curbm
= rp
->BitMap
;
140 pixwritten
= CallRenderFunc(render_func
, funcdata
, srcx
, srcy
,
141 bm
, gc
, &torender
, do_update
, GfxBase
);
148 struct Rectangle torender
, intersect
;
152 have_rp_cliprectangle
= GetRPClipRectangleForLayer(rp
, L
, &rp_clip_rectangle
, GfxBase
);
154 xrel
= L
->bounds
.MinX
;
155 yrel
= L
->bounds
.MinY
;
157 torender
.MinX
= rr
->MinX
+ xrel
- L
->Scroll_X
;
158 torender
.MinY
= rr
->MinY
+ yrel
- L
->Scroll_Y
;
159 torender
.MaxX
= rr
->MaxX
+ xrel
- L
->Scroll_X
;
160 torender
.MaxY
= rr
->MaxY
+ yrel
- L
->Scroll_Y
;
164 for (;NULL
!= CR
; CR
= CR
->Next
)
166 D(bug("Cliprect (%d, %d, %d, %d), lobs=%p\n",
167 CR
->bounds
.MinX
, CR
->bounds
.MinY
, CR
->bounds
.MaxX
, CR
->bounds
.MaxY
,
170 /* Does this cliprect intersect with area to rectfill ? */
171 if (_AndRectRect(&CR
->bounds
, &torender
, &intersect
))
173 if (!have_rp_cliprectangle
|| _AndRectRect(&rp_clip_rectangle
, &intersect
, &intersect
))
175 WORD xoffset
, yoffset
;
177 xoffset
= intersect
.MinX
- torender
.MinX
;
178 yoffset
= intersect
.MinY
- torender
.MinY
;
180 if (NULL
== CR
->lobs
)
182 if (get_special_info
)
184 RSI(funcdata
)->curbm
= bm
;
187 pixwritten
+= CallRenderFunc(render_func
, funcdata
, srcx
+ xoffset
, srcy
+ yoffset
,
188 bm
, gc
, &intersect
, do_update
, GfxBase
);
192 /* Render into offscreen cliprect bitmap */
193 if (L
->Flags
& LAYERSIMPLE
)
195 else if (L
->Flags
& LAYERSUPER
)
197 D(bug("do_render_func(): Superbitmap not handled yet\n"));
202 if (get_special_info
)
204 RSI(funcdata
)->curbm
= CR
->BitMap
;
207 intersect
.MinX
= intersect
.MinX
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
);
208 intersect
.MinY
= intersect
.MinY
- CR
->bounds
.MinY
;
209 intersect
.MaxX
= intersect
.MaxX
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
);
210 intersect
.MaxY
= intersect
.MaxY
- CR
->bounds
.MinY
;
212 pixwritten
+= CallRenderFunc(render_func
, funcdata
, srcx
+ xoffset
, srcy
+ yoffset
,
213 CR
->BitMap
, gc
, &intersect
, do_update
, GfxBase
);
216 } /* if (CR->lobs == NULL) */
218 } /* if it also intersects with possible rastport clip rectangle */
220 } /* if (cliprect intersects with area to render into) */
222 } /* for (each cliprect in the layer) */
225 } /* if (rp->Layer) */
230 /****************************************************************************************/
232 static LONG
CallPixelFunc(PIXELFUNC render_func
, APTR funcdata
, struct BitMap
*bm
, OOP_Object
*gc
,
233 WORD x
, WORD y
, BOOL do_update
, struct GfxBase
*GfxBase
)
235 OOP_Object
*bm_obj
= OBTAIN_HIDD_BM(bm
);
241 retval
= render_func(funcdata
, bm_obj
, gc
, x
, y
, GfxBase
);
244 update_bitmap(bm
, bm_obj
, x
, y
, 1, 1, GfxBase
);
246 RELEASE_HIDD_BM(bm_obj
, bm
);
250 ULONG
do_pixel_func(struct RastPort
*rp
252 , PIXELFUNC render_func
255 , struct GfxBase
*GfxBase
)
257 struct BitMap
*bm
= rp
->BitMap
;
258 struct Layer
*L
= rp
->Layer
;
260 struct Rectangle rp_clip_rectangle
;
261 BOOL have_rp_cliprectangle
;
264 gc
= GetDriverData(rp
, GfxBase
);
268 have_rp_cliprectangle
= GetRPClipRectangleForBitMap(rp
, bm
, &rp_clip_rectangle
, GfxBase
);
269 if (have_rp_cliprectangle
&& !_IsPointInRect(&rp_clip_rectangle
, x
, y
))
274 #if 0 /* With enabled BITMAP_CLIPPING this will be done automatically */
275 OOP_GetAttr(bm_obj
, aHidd_BitMap_Width
, &width
);
276 OOP_GetAttr(bm_obj
, aHidd_BitMap_Height
, &height
);
278 /* Check whether we it is inside the rastport */
288 /* This is a screen */
289 retval
= CallPixelFunc(render_func
, funcdata
, bm
, gc
, x
, y
, do_update
, GfxBase
);
298 have_rp_cliprectangle
= GetRPClipRectangleForLayer(rp
, L
, &rp_clip_rectangle
, GfxBase
);
302 absx
= x
+ L
->bounds
.MinX
- L
->Scroll_X
;
303 absy
= y
+ L
->bounds
.MinY
- L
->Scroll_Y
;
305 for (;NULL
!= CR
; CR
= CR
->Next
)
308 if ( absx
>= CR
->bounds
.MinX
309 && absy
>= CR
->bounds
.MinY
310 && absx
<= CR
->bounds
.MaxX
311 && absy
<= CR
->bounds
.MaxY
)
314 if (!have_rp_cliprectangle
|| _IsPointInRect(&rp_clip_rectangle
, absx
, absy
))
316 if (NULL
== CR
->lobs
)
318 retval
= CallPixelFunc(render_func
, funcdata
, bm
, gc
,
319 absx
, absy
, do_update
, GfxBase
);
323 /* This is the tricky one: render into offscreen cliprect bitmap */
324 if (L
->Flags
& LAYERSIMPLE
)
326 /* We cannot do anything */
330 else if (L
->Flags
& LAYERSUPER
)
332 D(bug("driver_WriteRGBPixel(): Superbitmap not handled yet\n"));
336 retval
= CallPixelFunc(render_func
, funcdata
, CR
->BitMap
, gc
,
337 absx
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
),
338 absy
- CR
->bounds
.MinY
,
340 } /* If (SMARTREFRESH cliprect) */
342 } /* if (intersecton inside hidden cliprect) */
344 } /* if point is also inside possible rastport clip rectangle */
346 /* The pixel was found and put inside one of the cliprects, just exit */
349 } /* if (cliprect intersects with area we want to draw to) */
351 } /* while (cliprects to examine) */
358 /****************************************************************************************/
360 ULONG
fillrect_render(APTR funcdata
, WORD srcx
, WORD srcy
,
361 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
,
362 struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
364 HIDD_BM_FillRect(dstbm_obj
, dst_gc
, rect
->MinX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
);
366 return (rect
->MaxX
- rect
->MinX
+ 1) * (rect
->MaxY
- rect
->MinY
+ 1);
369 /****************************************************************************************/
371 LONG
fillrect_pendrmd(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
,
372 HIDDT_Pixel pix
, HIDDT_DrawMode drmd
, BOOL do_update
, struct GfxBase
*GfxBase
)
377 gc
= GetDriverData(rp
, GfxBase
);
386 return do_render_with_gc(rp
, NULL
, &rr
, fillrect_render
, NULL
, gc
, do_update
, FALSE
, GfxBase
);
389 /****************************************************************************************/
391 BOOL
int_bltbitmap(struct BitMap
*srcBitMap
, OOP_Object
*srcbm_obj
, WORD xSrc
, WORD ySrc
,
392 struct BitMap
*dstBitMap
, OOP_Object
*dstbm_obj
, WORD xDest
, WORD yDest
,
393 WORD xSize
, WORD ySize
, ULONG minterm
, OOP_Object
*gfxhidd
, OOP_Object
*gc
,
394 struct GfxBase
*GfxBase
)
401 BOOL src_colmap_set
= FALSE
;
402 BOOL dst_colmap_set
= FALSE
;
404 BOOL colmaps_ok
= TRUE
;
406 drmd
= MINTERM_TO_GCDRMD(minterm
);
408 /* We must lock any HIDD_BM_SetColorMap calls */
411 /* Try to get a CLUT for the bitmaps */
412 if (IS_HIDD_BM(srcBitMap
))
414 //bug("driver_intbltbitmap: source is hidd bitmap\n");
415 if (NULL
!= HIDD_BM_COLMAP(srcBitMap
))
417 //bug("driver_intbltbitmap: source has colormap\n");
418 srcflags
|= FLG_HASCOLMAP
;
420 srcflags
|= GET_COLMOD_FLAGS(srcBitMap
);
424 //bug("driver_intbltbitmap: source is amiga bitmap\n");
426 srcflags
|= FLG_PALETTE
;
429 if (IS_HIDD_BM(dstBitMap
))
431 //bug("driver_intbltbitmap: dest is hidd bitmap\n");
432 if (NULL
!= HIDD_BM_COLMAP(dstBitMap
))
434 //bug("driver_intbltbitmap: dest has colormap\n");
435 dstflags
|= FLG_HASCOLMAP
;
437 dstflags
|= GET_COLMOD_FLAGS(dstBitMap
);
441 //bug("driver_intbltbitmap: dest is amiga bitmap\n");
443 dstflags
|= FLG_PALETTE
;
446 if ( (srcflags
== FLG_PALETTE
|| srcflags
== FLG_STATICPALETTE
))
448 /* palettized with no colmap. Neew to get a colmap from dest*/
449 if (dstflags
== FLG_TRUECOLOR
)
452 D(bug("!!! NO WAY GETTING PALETTE FOR src IN BltBitMap\n"));
457 else if (dstflags
== (FLG_TRUECOLOR
| FLG_HASCOLMAP
))
460 /* Use the dest colmap for src */
461 HIDD_BM_SetColorMap(srcbm_obj
, HIDD_BM_COLMAP(dstBitMap
));
463 src_colmap_set
= TRUE
;
469 for (idx = 0; idx < 256; idx ++)
470 bug("[%d]=%d ", idx, HIDD_CM_GetPixel(HIDD_BM_COLMAP(dstBitMap), idx));
476 if ( (dstflags
== FLG_PALETTE
|| dstflags
== FLG_STATICPALETTE
))
478 /* palettized with no pixtab. Nees to get a pixtab from dest*/
479 if (srcflags
== FLG_TRUECOLOR
)
481 D(bug("!!! NO WAY GETTING PALETTE FOR dst IN BltBitMap\n"));
486 else if (srcflags
== (FLG_TRUECOLOR
| FLG_HASCOLMAP
))
489 /* Use the src colmap for dst */
490 HIDD_BM_SetColorMap(dstbm_obj
, HIDD_BM_COLMAP(srcBitMap
));
492 dst_colmap_set
= TRUE
;
498 /* We need special treatment with drawmode Clear and
499 truecolor bitmaps, in order to set it to
500 colormap[0] instead of just 0
502 if ( (drmd
== vHidd_GC_DrawMode_Clear
)
503 && ( (dstflags
& (FLG_TRUECOLOR
| FLG_HASCOLMAP
)) == (FLG_TRUECOLOR
| FLG_HASCOLMAP
) ))
506 HIDDT_DrawMode old_drmd
;
509 struct TagItem frtags
[] =
511 { aHidd_GC_Foreground
, 0 },
512 { aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
516 OOP_GetAttr(gc
, aHidd_GC_DrawMode
, &old_drmd
);
517 OOP_GetAttr(gc
, aHidd_GC_Foreground
, &old_fg
);
519 frtags
[0].ti_Data
= HIDD_BM_PIXTAB(dstBitMap
)[0];
520 frtags
[1].ti_Data
= vHidd_GC_DrawMode_Copy
;
522 OOP_SetAttrs(gc
, frtags
);
524 HIDD_BM_FillRect(dstbm_obj
, gc
530 frtags
[0].ti_Data
= old_fg
;
531 frtags
[1].ti_Data
= old_drmd
;
536 HIDDT_DrawMode old_drmd
;
538 struct TagItem cbtags
[] =
540 { aHidd_GC_DrawMode
, 0 },
544 OOP_GetAttr(gc
, aHidd_GC_DrawMode
, &old_drmd
);
546 cbtags
[0].ti_Data
= drmd
;
548 OOP_SetAttrs(gc
, cbtags
);
549 HIDD_Gfx_CopyBox(gfxhidd
558 cbtags
[0].ti_Data
= drmd
;
559 OOP_SetAttrs(gc
, cbtags
);
562 } /* if (colmaps_ok) */
565 HIDD_BM_SetColorMap(srcbm_obj
, NULL
);
568 HIDD_BM_SetColorMap(dstbm_obj
, NULL
);
576 /****************************************************************************************/
578 struct wp8_render_data
582 HIDDT_PixelLUT
*pixlut
;
585 static ULONG
wp8_render(APTR wp8r_data
, WORD srcx
, WORD srcy
, OOP_Object
*dstbm_obj
,
586 OOP_Object
*dst_gc
, struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
588 struct wp8_render_data
*wp8rd
= wp8r_data
;
589 WORD width
= rect
->MaxX
- rect
->MinX
+ 1;
590 WORD height
= rect
->MaxY
- rect
->MinY
+ 1;
592 HIDD_BM_PutImageLUT(dstbm_obj
, dst_gc
,
593 wp8rd
->array
+ CHUNKY8_COORD_TO_BYTEIDX(srcx
, srcy
, wp8rd
->modulo
), wp8rd
->modulo
,
594 rect
->MinX
, rect
->MinY
, width
, height
, wp8rd
->pixlut
);
596 return width
* height
;
599 /****************************************************************************************/
601 LONG
write_pixels_8(struct RastPort
*rp
, UBYTE
*array
, ULONG modulo
,
602 WORD xstart
, WORD ystart
, WORD xstop
, WORD ystop
,
603 HIDDT_PixelLUT
*pixlut
, BOOL do_update
, struct GfxBase
*GfxBase
)
605 struct wp8_render_data wp8rd
;
608 HIDDT_PixelLUT bm_lut
;
610 /* If we haven't got a LUT, we obtain it from the bitmap */
611 if ((!pixlut
) && IS_HIDD_BM(rp
->BitMap
))
613 bm_lut
.entries
= AROS_PALETTE_SIZE
;
614 bm_lut
.pixels
= HIDD_BM_PIXTAB(rp
->BitMap
);
617 #ifdef RTG_SANITY_CHECK
618 if ((!bm_lut
.pixels
) && (HIDD_BM_REALDEPTH(rp
->BitMap
) > 8))
620 D(bug("write_pixels_8: can't work on hicolor/truecolor screen without LUT"));
626 gc
= GetDriverData(rp
, GfxBase
);
627 GC_DRMD(gc
) = vHidd_GC_DrawMode_Copy
;
629 wp8rd
.modulo
= modulo
;
631 wp8rd
.pixlut
= pixlut
;
638 return do_render_with_gc(rp
, NULL
, &rr
, wp8_render
, &wp8rd
, gc
, do_update
, FALSE
, GfxBase
);
641 /****************************************************************************************/
643 struct wtp8_render_data
647 HIDDT_PixelLUT
*pixlut
;
651 static ULONG
wtp8_render(APTR wtp8r_data
, WORD srcx
, WORD srcy
, OOP_Object
*dstbm_obj
,
652 OOP_Object
*dst_gc
, struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
654 struct wtp8_render_data
*wtp8rd
= wtp8r_data
;
655 WORD width
= rect
->MaxX
- rect
->MinX
+ 1;
656 WORD height
= rect
->MaxY
- rect
->MinY
+ 1;
658 HIDD_BM_PutTranspImageLUT(dstbm_obj
, dst_gc
,
659 wtp8rd
->array
+ CHUNKY8_COORD_TO_BYTEIDX(srcx
, srcy
, wtp8rd
->modulo
), wtp8rd
->modulo
,
660 rect
->MinX
, rect
->MinY
,width
, height
, wtp8rd
->pixlut
, wtp8rd
->transparent
);
662 return width
* height
;
664 /****************************************************************************************/
666 LONG
write_transp_pixels_8(struct RastPort
*rp
, UBYTE
*array
, ULONG modulo
,
667 WORD xstart
, WORD ystart
, WORD xstop
, WORD ystop
,
668 HIDDT_PixelLUT
*pixlut
, UBYTE transparent
,
669 BOOL do_update
, struct GfxBase
*GfxBase
)
671 struct wtp8_render_data wtp8rd
;
675 gc
= GetDriverData(rp
, GfxBase
);
676 GC_DRMD(gc
) = vHidd_GC_DrawMode_Copy
;
678 wtp8rd
.modulo
= modulo
;
679 wtp8rd
.array
= array
;
680 wtp8rd
.pixlut
= pixlut
;
681 wtp8rd
.transparent
= transparent
;
688 return do_render_with_gc(rp
, NULL
, &rr
, wtp8_render
, &wtp8rd
, gc
, do_update
, FALSE
, GfxBase
);
691 /****************************************************************************************/
694 ** General functions for moving blocks of data to or from HIDDs, be it pixelarrays
695 ** or bitmaps. They use a callback-function to get data from amiga/put data to amiga
696 ** bitmaps/pixelarrays
699 /****************************************************************************************/
701 /****************************************************************************************/
703 #define ENABLE_PROFILING 0
704 #define USE_OLD_MoveRaster 0
706 #define rdtscll(val) \
707 __asm__ __volatile__("rdtsc" : "=A" (val))
709 #if ENABLE_PROFILING && defined(__i386__)
712 #define AROS_BEGIN_PROFILING(context) \
714 unsigned long long _time1, _time2; \
715 char *_text = #context; \
719 #define AROS_END_PROFILING \
722 kprintf("%s: Ticks count: %u\n", _text, (unsigned long)(_time2 - _time1)); \
727 #define AROS_BEGIN_PROFILING(context)
728 #define AROS_END_PROFILING
732 BOOL
MoveRaster (struct RastPort
* rp
, WORD dx
, WORD dy
, WORD x1
, WORD y1
,
733 WORD x2
, WORD y2
, BOOL UpdateDamageList
, struct GfxBase
* GfxBase
)
735 struct Layer
*L
= rp
->Layer
;
736 struct Rectangle ScrollRect
;
737 struct Rectangle Rect
;
739 if (0 == dx
&& 0 == dy
)
742 ScrollRect
.MinX
= x1
;
743 ScrollRect
.MinY
= y1
;
744 ScrollRect
.MaxX
= x2
;
745 ScrollRect
.MaxY
= y2
;
750 TranslateRect(&Rect
, -dx
, -dy
);
751 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
753 BltBitMap(rp
->BitMap
,
759 Rect
.MaxX
- Rect
.MinX
+ 1,
760 Rect
.MaxY
- Rect
.MinY
+ 1,
768 struct ClipRect
*SrcCR
;
772 if (L
->Flags
& LAYERSIMPLE
&& UpdateDamageList
)
774 /* Scroll the old damagelist within the scroll area */
775 ScrollRegion(L
->DamageList
, &ScrollRect
, -dx
, -dy
);
778 /* The scrolling area is relative to the Layer, so make it relative to the screen */
779 TranslateRect(&ScrollRect
, MinX(L
), MinY(L
));
781 /* The damage list will be formed by the now hidden layer's parts that will become visible due
782 to the scrolling procedure, thus we procede this way:
784 1) Calculate the invisible region out of the visible one, subtracting it from the
787 2) Scroll the invisible region by (-dx, -dy) and then subtract from it the not scrolled equivalent
789 The regions that we obtain after (2) is the new damage list
792 if (L
->Flags
& LAYERSIMPLE
&& UpdateDamageList
)
796 TranslateRect(&Rect
, dx
, dy
);
798 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
800 struct Region
*Damage
= NewRegion();
805 BOOL res
= OrRectRegion(Damage
, &ScrollRect
);
807 BOOL res
= OrRectRegion(Damage
, &Rect
);
811 DisposeRegion(Damage
);
820 ClearRegionRegion(L
->VisibleRegion
, Damage
)
822 Damage
->RegionRectangle
827 We play sort of dirty here, by making assumptions about the internals of the
828 Region structure and the region handling functions, but we are allowed to do that,
834 TranslateRect(Bounds(Damage
), -dx
, -dy
);
838 ClearRegionRegion(&Tmp
, Damage
)
840 Damage
->RegionRectangle
844 AndRectRegion(Damage
, &ScrollRect
);
845 if (Damage
->RegionRectangle
)
849 /* Join the new damage list with the old one */
850 TranslateRect(Bounds(Damage
), -MinX(L
), -MinY(L
));
851 OrRegionRegion(Damage
, L
->DamageList
);
853 L
->Flags
|= LAYERREFRESH
;
858 DisposeRegion(Damage
);
863 AROS_BEGIN_PROFILING(SortLayerCR
)
866 SortLayerCR(L
, dx
, dy
);
870 AROS_BEGIN_PROFILING(Blitting loop
)
872 #if USE_OLDMoveRaster
875 struct ClipRect
*LastHiddenCR
;
877 for (LastHiddenCR
= NULL
, SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
879 SrcCR
->_p1
= LastHiddenCR
;
882 LastHiddenCR
= SrcCR
;
887 for (SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
891 if (SrcCR
->lobs
&& (L
->Flags
& LAYERSIMPLE
))
896 if (_AndRectRect(&ScrollRect
, Bounds(SrcCR
), &Rect
))
898 TranslateRect(&Rect
, -dx
, -dy
);
900 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
906 /* Rect.Min(X|Y) are the coordinates to wich the rectangle has to be moved
907 Rect.Max(X|Y) - Rect.Max(X|Y) - 1 are the dimensions of this rectangle */
908 if (!SrcCR
->_p1
&& !SrcCR
->lobs
)
910 /* there are no hidden/obscured rectangles this recrtangle has to deal with*/
919 Rect
.MaxX
- Rect
.MinX
+ 1,
920 Rect
.MaxY
- Rect
.MinY
+ 1,
928 struct BitMap
*srcbm
;
929 struct RegionRectangle
*rr
;
930 struct Region
*RectRegion
= NewRegion();
931 struct Rectangle Tmp
;
932 struct ClipRect
*HiddCR
;
933 WORD corrsrcx
, corrsrcy
;
939 if (!OrRectRegion(&Rect
, RectRegion
))
941 DisposeRegion(RectRegion
);
947 if (L
->Flags
& LAYERSUPER
)
949 corrsrcx
= - MinX(L
) - L
->Scroll_X
;
950 corrsrcy
= - MinY(L
) - L
->Scroll_Y
;
954 corrsrcx
= - MinX(SrcCR
) + ALIGN_OFFSET(MinX(SrcCR
));
955 corrsrcy
= - MinY(SrcCR
);
957 srcbm
= SrcCR
->BitMap
;
966 for (HiddCR
= SrcCR
->_p1
; HiddCR
; HiddCR
= HiddCR
->_p1
)
968 if (_AndRectRect(Bounds(RectRegion
), Bounds(HiddCR
), &Tmp
))
970 if (!(L
->Flags
& LAYERSIMPLE
))
972 WORD corrdstx
, corrdsty
;
974 if (L
->Flags
& LAYERSUPER
)
976 corrdstx
= - MinX(L
) - L
->Scroll_X
;
977 corrdsty
= - MinY(L
) - L
->Scroll_Y
;
982 corrdstx
= - MinX(HiddCR
) + ALIGN_OFFSET(MinX(HiddCR
));
983 corrdsty
= - MinY(HiddCR
);
990 Tmp
.MinX
+ corrsrcx
+ dx
,
991 Tmp
.MinY
+ corrsrcy
+ dy
,
995 Tmp
.MaxX
- Tmp
.MinX
+ 1,
996 Tmp
.MaxY
- Tmp
.MinY
+ 1,
1003 if (!ClearRectRegion(RectRegion
, &Tmp
))
1005 DisposeRegion(RectRegion
);
1011 if ((dosrcsrc
= _AndRectRect(Bounds(SrcCR
), &Rect
, &Tmp
)))
1013 if (!ClearRectRegion(RectRegion
, &Tmp
))
1015 DisposeRegion(RectRegion
);
1020 for (rr
= RectRegion
->RegionRectangle
; rr
; rr
= rr
->Next
)
1025 MinX(rr
) + MinX(RectRegion
) + corrsrcx
+ dx
,
1026 MinY(rr
) + MinY(RectRegion
) + corrsrcy
+ dy
,
1028 MinX(rr
) + MinX(RectRegion
),
1029 MinY(rr
) + MinY(RectRegion
),
1043 Tmp
.MinX
+ corrsrcx
+ dx
,
1044 Tmp
.MinY
+ corrsrcy
+ dy
,
1046 Tmp
.MinX
+ corrsrcx
,
1047 Tmp
.MinY
+ corrsrcy
,
1048 Tmp
.MaxX
- Tmp
.MinX
+ 1,
1049 Tmp
.MaxY
- Tmp
.MinY
+ 1,
1057 DisposeRegion(RectRegion
);
1064 for (SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
1066 if (_AndRectRect(&ScrollRect
, Bounds(SrcCR
), &Rect
))
1068 TranslateRect(&Rect
, -dx
, -dy
);
1070 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
1072 struct BitMap
*srcbm
;
1073 struct ClipRect
*DstCR
;
1074 WORD corrsrcx
, corrsrcy
;
1079 if (L
->Flags
& LAYERSIMPLE
) continue;
1081 if (L
->Flags
& LAYERSUPER
)
1083 corrsrcx
= - MinX(L
) - L
->Scroll_X
;
1084 corrsrcy
= - MinY(L
) - L
->Scroll_Y
;
1088 corrsrcx
= - MinX(SrcCR
) + ALIGN_OFFSET(MinX(SrcCR
));
1089 corrsrcy
= - MinY(SrcCR
);
1091 srcbm
= SrcCR
->BitMap
;
1100 area
= (Rect
.MaxX
- Rect
.MinX
+ 1) * (Rect
.MaxY
- Rect
.MinY
+ 1);
1102 for (DstCR
= L
->ClipRect
; area
&& DstCR
; DstCR
= DstCR
->Next
)
1104 struct Rectangle Rect2
;
1106 if (_AndRectRect(Bounds(DstCR
), &Rect
, &Rect2
))
1108 struct BitMap
*dstbm
;
1109 WORD corrdstx
, corrdsty
;
1111 area
-= (Rect2
.MaxX
- Rect2
.MinX
+ 1) * (Rect2
.MaxY
- Rect2
.MinY
+ 1);
1115 if (L
->Flags
& LAYERSIMPLE
) continue;
1117 if (L
->Flags
& LAYERSUPER
)
1119 corrdstx
= - MinX(L
) - L
->Scroll_X
;
1120 corrdsty
= - MinY(L
) - L
->Scroll_Y
;
1124 corrdstx
= - MinX(DstCR
) + ALIGN_OFFSET(MinX(DstCR
));
1125 corrdsty
= - MinY(DstCR
);
1127 dstbm
= DstCR
->BitMap
;
1139 Rect2
.MinX
+ corrsrcx
+ dx
,
1140 Rect2
.MinY
+ corrsrcy
+ dy
,
1142 Rect2
.MinX
+ corrdstx
,
1143 Rect2
.MinY
+ corrdsty
,
1144 Rect2
.MaxX
- Rect2
.MinX
+ 1,
1145 Rect2
.MaxY
- Rect2
.MinY
+ 1,
1164 /****************************************************************************************/
1166 BOOL
GetRPClipRectangleForRect(struct RastPort
*rp
, struct Rectangle
*rect
, struct Rectangle
*r
)
1168 struct gfx_driverdata
*dd
= ObtainDriverData(rp
);
1170 if (dd
&& dd
->dd_ClipRectangleFlags
& RPCRF_VALID
)
1172 *r
= dd
->dd_ClipRectangle
;
1174 if (dd
->dd_ClipRectangleFlags
& RPCRF_RELRIGHT
)
1176 r
->MaxX
+= rect
->MaxX
- rect
->MinX
;
1179 if (dd
->dd_ClipRectangleFlags
& RPCRF_RELBOTTOM
)
1181 r
->MaxY
+= rect
->MaxY
- rect
->MinY
;
1184 r
->MinX
+= rect
->MinX
;
1185 r
->MinY
+= rect
->MinY
;
1186 r
->MaxX
+= rect
->MinX
;
1187 r
->MaxY
+= rect
->MinY
;
1195 /****************************************************************************************/
1197 BOOL
GetRPClipRectangleForBitMap(struct RastPort
*rp
, struct BitMap
*bm
,
1198 struct Rectangle
*r
, struct GfxBase
*GfxBase
)
1200 struct Rectangle bm_rect
;
1205 bm_rect
.MaxX
= GetBitMapAttr(bm
, BMA_WIDTH
) - 1;
1206 bm_rect
.MaxY
= GetBitMapAttr(bm
, BMA_HEIGHT
) - 1;
1208 res
= GetRPClipRectangleForRect(rp
, &bm_rect
, r
);
1214 * Set the rectangle to total bitmap size. This prevents trashing memory
1215 * by hitting unallocated memory in HIDDs. They don't check bitmap bounds.