2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
6 /****************************************************************************************/
7 #include <aros/debug.h>
9 #include <cybergraphx/cybergraphics.h>
10 #include <graphics/rpattr.h>
11 #include <proto/layers.h>
12 #include <proto/exec.h>
13 #include <proto/graphics.h>
14 #include <proto/oop.h>
15 #include <clib/macros.h>
17 #include "graphics_intern.h"
19 #include "intregions.h"
20 #include "gfxfuncsupport.h"
21 #include "graphics_driver.h"
23 #define DEBUG_PLANARBM(x)
25 #define LayersBase (struct LayersBase *)(GfxBase->gb_LayersBase)
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
)
864 SortLayerCR(L
, dx
, dy
);
868 AROS_BEGIN_PROFILING(Blitting loop
)
870 #if USE_OLDMoveRaster
873 struct ClipRect
*LastHiddenCR
;
875 for (LastHiddenCR
= NULL
, SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
877 SrcCR
->_p1
= LastHiddenCR
;
880 LastHiddenCR
= SrcCR
;
885 for (SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
889 if (SrcCR
->lobs
&& (L
->Flags
& LAYERSIMPLE
))
894 if (_AndRectRect(&ScrollRect
, Bounds(SrcCR
), &Rect
))
896 TranslateRect(&Rect
, -dx
, -dy
);
898 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
904 /* Rect.Min(X|Y) are the coordinates to wich the rectangle has to be moved
905 Rect.Max(X|Y) - Rect.Max(X|Y) - 1 are the dimensions of this rectangle */
906 if (!SrcCR
->_p1
&& !SrcCR
->lobs
)
908 /* there are no hidden/obscured rectangles this recrtangle has to deal with*/
917 Rect
.MaxX
- Rect
.MinX
+ 1,
918 Rect
.MaxY
- Rect
.MinY
+ 1,
926 struct BitMap
*srcbm
;
927 struct RegionRectangle
*rr
;
928 struct Region
*RectRegion
= NewRegion();
929 struct Rectangle Tmp
;
930 struct ClipRect
*HiddCR
;
931 WORD corrsrcx
, corrsrcy
;
937 if (!OrRectRegion(&Rect
, RectRegion
))
939 DisposeRegion(RectRegion
);
945 if (L
->Flags
& LAYERSUPER
)
947 corrsrcx
= - MinX(L
) - L
->Scroll_X
;
948 corrsrcy
= - MinY(L
) - L
->Scroll_Y
;
952 corrsrcx
= - MinX(SrcCR
) + ALIGN_OFFSET(MinX(SrcCR
));
953 corrsrcy
= - MinY(SrcCR
);
955 srcbm
= SrcCR
->BitMap
;
964 for (HiddCR
= SrcCR
->_p1
; HiddCR
; HiddCR
= HiddCR
->_p1
)
966 if (_AndRectRect(Bounds(RectRegion
), Bounds(HiddCR
), &Tmp
))
968 if (!(L
->Flags
& LAYERSIMPLE
))
970 WORD corrdstx
, corrdsty
;
972 if (L
->Flags
& LAYERSUPER
)
974 corrdstx
= - MinX(L
) - L
->Scroll_X
;
975 corrdsty
= - MinY(L
) - L
->Scroll_Y
;
980 corrdstx
= - MinX(HiddCR
) + ALIGN_OFFSET(MinX(HiddCR
));
981 corrdsty
= - MinY(HiddCR
);
988 Tmp
.MinX
+ corrsrcx
+ dx
,
989 Tmp
.MinY
+ corrsrcy
+ dy
,
993 Tmp
.MaxX
- Tmp
.MinX
+ 1,
994 Tmp
.MaxY
- Tmp
.MinY
+ 1,
1001 if (!ClearRectRegion(RectRegion
, &Tmp
))
1003 DisposeRegion(RectRegion
);
1009 if ((dosrcsrc
= _AndRectRect(Bounds(SrcCR
), &Rect
, &Tmp
)))
1011 if (!ClearRectRegion(RectRegion
, &Tmp
))
1013 DisposeRegion(RectRegion
);
1018 for (rr
= RectRegion
->RegionRectangle
; rr
; rr
= rr
->Next
)
1023 MinX(rr
) + MinX(RectRegion
) + corrsrcx
+ dx
,
1024 MinY(rr
) + MinY(RectRegion
) + corrsrcy
+ dy
,
1026 MinX(rr
) + MinX(RectRegion
),
1027 MinY(rr
) + MinY(RectRegion
),
1041 Tmp
.MinX
+ corrsrcx
+ dx
,
1042 Tmp
.MinY
+ corrsrcy
+ dy
,
1044 Tmp
.MinX
+ corrsrcx
,
1045 Tmp
.MinY
+ corrsrcy
,
1046 Tmp
.MaxX
- Tmp
.MinX
+ 1,
1047 Tmp
.MaxY
- Tmp
.MinY
+ 1,
1055 DisposeRegion(RectRegion
);
1062 for (SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
1064 if (_AndRectRect(&ScrollRect
, Bounds(SrcCR
), &Rect
))
1066 TranslateRect(&Rect
, -dx
, -dy
);
1068 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
1070 struct BitMap
*srcbm
;
1071 struct ClipRect
*DstCR
;
1072 WORD corrsrcx
, corrsrcy
;
1077 if (L
->Flags
& LAYERSIMPLE
) continue;
1079 if (L
->Flags
& LAYERSUPER
)
1081 corrsrcx
= - MinX(L
) - L
->Scroll_X
;
1082 corrsrcy
= - MinY(L
) - L
->Scroll_Y
;
1086 corrsrcx
= - MinX(SrcCR
) + ALIGN_OFFSET(MinX(SrcCR
));
1087 corrsrcy
= - MinY(SrcCR
);
1089 srcbm
= SrcCR
->BitMap
;
1098 area
= (Rect
.MaxX
- Rect
.MinX
+ 1) * (Rect
.MaxY
- Rect
.MinY
+ 1);
1100 for (DstCR
= L
->ClipRect
; area
&& DstCR
; DstCR
= DstCR
->Next
)
1102 struct Rectangle Rect2
;
1104 if (_AndRectRect(Bounds(DstCR
), &Rect
, &Rect2
))
1106 struct BitMap
*dstbm
;
1107 WORD corrdstx
, corrdsty
;
1109 area
-= (Rect2
.MaxX
- Rect2
.MinX
+ 1) * (Rect2
.MaxY
- Rect2
.MinY
+ 1);
1113 if (L
->Flags
& LAYERSIMPLE
) continue;
1115 if (L
->Flags
& LAYERSUPER
)
1117 corrdstx
= - MinX(L
) - L
->Scroll_X
;
1118 corrdsty
= - MinY(L
) - L
->Scroll_Y
;
1122 corrdstx
= - MinX(DstCR
) + ALIGN_OFFSET(MinX(DstCR
));
1123 corrdsty
= - MinY(DstCR
);
1125 dstbm
= DstCR
->BitMap
;
1137 Rect2
.MinX
+ corrsrcx
+ dx
,
1138 Rect2
.MinY
+ corrsrcy
+ dy
,
1140 Rect2
.MinX
+ corrdstx
,
1141 Rect2
.MinY
+ corrdsty
,
1142 Rect2
.MaxX
- Rect2
.MinX
+ 1,
1143 Rect2
.MaxY
- Rect2
.MinY
+ 1,
1162 /****************************************************************************************/
1164 BOOL
GetRPClipRectangleForRect(struct RastPort
*rp
, struct Rectangle
*rect
, struct Rectangle
*r
)
1166 struct gfx_driverdata
*dd
= ObtainDriverData(rp
);
1168 if (dd
&& dd
->dd_ClipRectangleFlags
& RPCRF_VALID
)
1170 *r
= dd
->dd_ClipRectangle
;
1172 if (dd
->dd_ClipRectangleFlags
& RPCRF_RELRIGHT
)
1174 r
->MaxX
+= rect
->MaxX
- rect
->MinX
;
1177 if (dd
->dd_ClipRectangleFlags
& RPCRF_RELBOTTOM
)
1179 r
->MaxY
+= rect
->MaxY
- rect
->MinY
;
1182 r
->MinX
+= rect
->MinX
;
1183 r
->MinY
+= rect
->MinY
;
1184 r
->MaxX
+= rect
->MinX
;
1185 r
->MaxY
+= rect
->MinY
;
1193 /****************************************************************************************/
1195 BOOL
GetRPClipRectangleForBitMap(struct RastPort
*rp
, struct BitMap
*bm
,
1196 struct Rectangle
*r
, struct GfxBase
*GfxBase
)
1198 struct Rectangle bm_rect
;
1203 bm_rect
.MaxX
= GetBitMapAttr(bm
, BMA_WIDTH
) - 1;
1204 bm_rect
.MaxY
= GetBitMapAttr(bm
, BMA_HEIGHT
) - 1;
1206 res
= GetRPClipRectangleForRect(rp
, &bm_rect
, r
);
1212 * Set the rectangle to total bitmap size. This prevents trashing memory
1213 * by hitting unallocated memory in HIDDs. They don't check bitmap bounds.