2 Copyright © 1995-2014, 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) DB2(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("%s: bitmap=%p\n", __func__
, bitmap
));
34 pbm_obj
= obtain_cache_object(CDD(GfxBase
)->planarbm_cache
, GfxBase
);
39 DEBUG_PLANARBM(bug("%s: cache object %p, class=%s, instoffset=%d\n"
42 , OOP_OCLASS(pbm_obj
)->ClassNode
.ln_Name
43 , OOP_OCLASS(pbm_obj
)->InstOffset
46 if (!HIDD_PlanarBM_SetBitMap(pbm_obj
, bitmap
))
48 DEBUG_PLANARBM(bug("!!! get_planarbm_object: HIDD_PlanarBM_SetBitMap FAILED !!!\n"));
49 release_cache_object(CDD(GfxBase
)->planarbm_cache
, pbm_obj
, GfxBase
);
56 DEBUG_PLANARBM(bug("!!! get_planarbm_object: obtain_cache_object FAILED !!!\n"));
62 /****************************************************************************************/
64 static ULONG
CallRenderFunc(RENDERFUNC render_func
, APTR funcdata
, WORD srcx
, WORD srcy
,
65 struct BitMap
*bm
, OOP_Object
*gc
, struct Rectangle
*rect
, BOOL do_update
,
66 struct GfxBase
*GfxBase
)
68 OOP_Object
*bm_obj
= OBTAIN_HIDD_BM(bm
);
74 pixwritten
= render_func(funcdata
, srcx
, srcy
, bm_obj
, gc
, rect
, GfxBase
);
77 update_bitmap(bm
, bm_obj
, rect
->MinX
, rect
->MinY
,
78 rect
->MaxX
- rect
->MinX
+ 1, rect
->MaxY
- rect
->MinY
+ 1,
81 RELEASE_HIDD_BM(bm_obj
, bm
);
85 ULONG
do_render_func(struct RastPort
*rp
, Point
*src
, struct Rectangle
*rr
,
86 RENDERFUNC render_func
, APTR funcdata
,
87 BOOL do_update
, BOOL get_special_info
, struct GfxBase
*GfxBase
)
89 OOP_Object
*gc
= GetDriverData(rp
, GfxBase
);
91 return do_render_with_gc(rp
, src
, rr
, render_func
, funcdata
, gc
, do_update
, get_special_info
, GfxBase
);
95 * GetDriverData() resets the GC to RastPort's values.
96 * This is another entry point which avoids that. Use it if you have already set up GC.
98 ULONG
do_render_with_gc(struct RastPort
*rp
, Point
*src
, struct Rectangle
*rr
,
99 RENDERFUNC render_func
, APTR funcdata
, OOP_Object
*gc
,
100 BOOL do_update
, BOOL get_special_info
, struct GfxBase
*GfxBase
)
103 struct BitMap
*bm
= rp
->BitMap
;
104 struct Layer
*L
= rp
->Layer
;
105 struct Rectangle rp_clip_rectangle
;
106 BOOL have_rp_cliprectangle
;
122 /* No layer, probably a screen, but may be a user inited bitmap */
123 struct Rectangle torender
= *rr
;
125 have_rp_cliprectangle
= GetRPClipRectangleForBitMap(rp
, bm
, &rp_clip_rectangle
, GfxBase
);
126 if (have_rp_cliprectangle
&& !(_AndRectRect(rr
, &rp_clip_rectangle
, &torender
)))
131 srcx
+= (torender
.MinX
- rr
->MinX
);
132 srcy
+= (torender
.MinY
- rr
->MinY
);
134 if (get_special_info
)
136 RSI(funcdata
)->curbm
= rp
->BitMap
;
139 pixwritten
= CallRenderFunc(render_func
, funcdata
, srcx
, srcy
,
140 bm
, gc
, &torender
, do_update
, GfxBase
);
147 struct Rectangle torender
, intersect
;
151 have_rp_cliprectangle
= GetRPClipRectangleForLayer(rp
, L
, &rp_clip_rectangle
, GfxBase
);
153 xrel
= L
->bounds
.MinX
;
154 yrel
= L
->bounds
.MinY
;
156 torender
.MinX
= rr
->MinX
+ xrel
- L
->Scroll_X
;
157 torender
.MinY
= rr
->MinY
+ yrel
- L
->Scroll_Y
;
158 torender
.MaxX
= rr
->MaxX
+ xrel
- L
->Scroll_X
;
159 torender
.MaxY
= rr
->MaxY
+ yrel
- L
->Scroll_Y
;
163 for (;NULL
!= CR
; CR
= CR
->Next
)
165 D(bug("Cliprect (%d, %d, %d, %d), lobs=%p\n",
166 CR
->bounds
.MinX
, CR
->bounds
.MinY
, CR
->bounds
.MaxX
, CR
->bounds
.MaxY
,
169 /* Does this cliprect intersect with area to rectfill ? */
170 if (_AndRectRect(&CR
->bounds
, &torender
, &intersect
))
172 if (!have_rp_cliprectangle
|| _AndRectRect(&rp_clip_rectangle
, &intersect
, &intersect
))
174 WORD xoffset
, yoffset
;
176 xoffset
= intersect
.MinX
- torender
.MinX
;
177 yoffset
= intersect
.MinY
- torender
.MinY
;
179 if (NULL
== CR
->lobs
)
181 if (get_special_info
)
183 RSI(funcdata
)->curbm
= bm
;
186 pixwritten
+= CallRenderFunc(render_func
, funcdata
, srcx
+ xoffset
, srcy
+ yoffset
,
187 bm
, gc
, &intersect
, do_update
, GfxBase
);
191 /* Render into offscreen cliprect bitmap */
192 if (L
->Flags
& LAYERSIMPLE
)
194 else if (L
->Flags
& LAYERSUPER
)
196 D(bug("do_render_func(): Superbitmap not handled yet\n"));
201 if (get_special_info
)
203 RSI(funcdata
)->curbm
= CR
->BitMap
;
206 intersect
.MinX
= intersect
.MinX
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
);
207 intersect
.MinY
= intersect
.MinY
- CR
->bounds
.MinY
;
208 intersect
.MaxX
= intersect
.MaxX
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
);
209 intersect
.MaxY
= intersect
.MaxY
- CR
->bounds
.MinY
;
211 pixwritten
+= CallRenderFunc(render_func
, funcdata
, srcx
+ xoffset
, srcy
+ yoffset
,
212 CR
->BitMap
, gc
, &intersect
, do_update
, GfxBase
);
215 } /* if (CR->lobs == NULL) */
217 } /* if it also intersects with possible rastport clip rectangle */
219 } /* if (cliprect intersects with area to render into) */
221 } /* for (each cliprect in the layer) */
224 } /* if (rp->Layer) */
229 /****************************************************************************************/
231 static LONG
CallPixelFunc(PIXELFUNC render_func
, APTR funcdata
, struct BitMap
*bm
, OOP_Object
*gc
,
232 WORD x
, WORD y
, BOOL do_update
, struct GfxBase
*GfxBase
)
234 OOP_Object
*bm_obj
= OBTAIN_HIDD_BM(bm
);
240 retval
= render_func(funcdata
, bm_obj
, gc
, x
, y
, GfxBase
);
243 update_bitmap(bm
, bm_obj
, x
, y
, 1, 1, GfxBase
);
245 RELEASE_HIDD_BM(bm_obj
, bm
);
249 ULONG
do_pixel_func(struct RastPort
*rp
251 , PIXELFUNC render_func
254 , struct GfxBase
*GfxBase
)
256 struct BitMap
*bm
= rp
->BitMap
;
257 struct Layer
*L
= rp
->Layer
;
259 struct Rectangle rp_clip_rectangle
;
260 BOOL have_rp_cliprectangle
;
263 gc
= GetDriverData(rp
, GfxBase
);
267 have_rp_cliprectangle
= GetRPClipRectangleForBitMap(rp
, bm
, &rp_clip_rectangle
, GfxBase
);
268 if (have_rp_cliprectangle
&& !_IsPointInRect(&rp_clip_rectangle
, x
, y
))
273 #if 0 /* With enabled BITMAP_CLIPPING this will be done automatically */
274 OOP_GetAttr(bm_obj
, aHidd_BitMap_Width
, &width
);
275 OOP_GetAttr(bm_obj
, aHidd_BitMap_Height
, &height
);
277 /* Check whether we it is inside the rastport */
287 /* This is a screen */
288 retval
= CallPixelFunc(render_func
, funcdata
, bm
, gc
, x
, y
, do_update
, GfxBase
);
297 have_rp_cliprectangle
= GetRPClipRectangleForLayer(rp
, L
, &rp_clip_rectangle
, GfxBase
);
301 absx
= x
+ L
->bounds
.MinX
- L
->Scroll_X
;
302 absy
= y
+ L
->bounds
.MinY
- L
->Scroll_Y
;
304 for (;NULL
!= CR
; CR
= CR
->Next
)
307 if ( absx
>= CR
->bounds
.MinX
308 && absy
>= CR
->bounds
.MinY
309 && absx
<= CR
->bounds
.MaxX
310 && absy
<= CR
->bounds
.MaxY
)
313 if (!have_rp_cliprectangle
|| _IsPointInRect(&rp_clip_rectangle
, absx
, absy
))
315 if (NULL
== CR
->lobs
)
317 retval
= CallPixelFunc(render_func
, funcdata
, bm
, gc
,
318 absx
, absy
, do_update
, GfxBase
);
322 /* This is the tricky one: render into offscreen cliprect bitmap */
323 if (L
->Flags
& LAYERSIMPLE
)
325 /* We cannot do anything */
329 else if (L
->Flags
& LAYERSUPER
)
331 D(bug("driver_WriteRGBPixel(): Superbitmap not handled yet\n"));
335 retval
= CallPixelFunc(render_func
, funcdata
, CR
->BitMap
, gc
,
336 absx
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
),
337 absy
- CR
->bounds
.MinY
,
339 } /* If (SMARTREFRESH cliprect) */
341 } /* if (intersecton inside hidden cliprect) */
343 } /* if point is also inside possible rastport clip rectangle */
345 /* The pixel was found and put inside one of the cliprects, just exit */
348 } /* if (cliprect intersects with area we want to draw to) */
350 } /* while (cliprects to examine) */
357 /****************************************************************************************/
359 ULONG
fillrect_render(APTR funcdata
, WORD srcx
, WORD srcy
,
360 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
,
361 struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
363 HIDD_BM_FillRect(dstbm_obj
, dst_gc
, rect
->MinX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
);
365 return (rect
->MaxX
- rect
->MinX
+ 1) * (rect
->MaxY
- rect
->MinY
+ 1);
368 /****************************************************************************************/
370 LONG
fillrect_pendrmd(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
,
371 HIDDT_Pixel pix
, HIDDT_DrawMode drmd
, BOOL do_update
, struct GfxBase
*GfxBase
)
376 gc
= GetDriverData(rp
, GfxBase
);
385 return do_render_with_gc(rp
, NULL
, &rr
, fillrect_render
, NULL
, gc
, do_update
, FALSE
, GfxBase
);
388 /****************************************************************************************/
390 BOOL
int_bltbitmap(struct BitMap
*srcBitMap
, OOP_Object
*srcbm_obj
, WORD xSrc
, WORD ySrc
,
391 struct BitMap
*dstBitMap
, OOP_Object
*dstbm_obj
, WORD xDest
, WORD yDest
,
392 WORD xSize
, WORD ySize
, ULONG minterm
, OOP_Object
*gfxhidd
, OOP_Object
*gc
,
393 struct GfxBase
*GfxBase
)
400 BOOL src_colmap_set
= FALSE
;
401 BOOL dst_colmap_set
= FALSE
;
403 BOOL colmaps_ok
= TRUE
;
405 drmd
= MINTERM_TO_GCDRMD(minterm
);
407 /* We must lock any HIDD_BM_SetColorMap calls */
410 /* Try to get a CLUT for the bitmaps */
411 if (IS_HIDD_BM(srcBitMap
))
413 //bug("driver_intbltbitmap: source is hidd bitmap\n");
414 if (NULL
!= HIDD_BM_COLMAP(srcBitMap
))
416 //bug("driver_intbltbitmap: source has colormap\n");
417 srcflags
|= FLG_HASCOLMAP
;
419 srcflags
|= GET_COLMOD_FLAGS(srcBitMap
);
423 //bug("driver_intbltbitmap: source is amiga bitmap\n");
425 srcflags
|= FLG_PALETTE
;
428 if (IS_HIDD_BM(dstBitMap
))
430 //bug("driver_intbltbitmap: dest is hidd bitmap\n");
431 if (NULL
!= HIDD_BM_COLMAP(dstBitMap
))
433 //bug("driver_intbltbitmap: dest has colormap\n");
434 dstflags
|= FLG_HASCOLMAP
;
436 dstflags
|= GET_COLMOD_FLAGS(dstBitMap
);
440 //bug("driver_intbltbitmap: dest is amiga bitmap\n");
442 dstflags
|= FLG_PALETTE
;
445 if ( (srcflags
== FLG_PALETTE
|| srcflags
== FLG_STATICPALETTE
))
447 /* palettized with no colmap. Need to get a colmap from dest */
448 if (dstflags
== FLG_TRUECOLOR
)
451 D(bug("!!! NO WAY GETTING PALETTE FOR src IN BltBitMap\n"));
456 else if (dstflags
== (FLG_TRUECOLOR
| FLG_HASCOLMAP
))
459 /* Use the dest colmap for src */
460 HIDD_BM_SetColorMap(srcbm_obj
, HIDD_BM_COLMAP(dstBitMap
));
462 src_colmap_set
= TRUE
;
468 for (idx = 0; idx < 256; idx ++)
469 bug("[%d]=%d ", idx, HIDD_CM_GetPixel(HIDD_BM_COLMAP(dstBitMap), idx));
475 if ( (dstflags
== FLG_PALETTE
|| dstflags
== FLG_STATICPALETTE
))
477 /* palettized with no pixtab. Nees to get a pixtab from dest*/
478 if (srcflags
== FLG_TRUECOLOR
)
480 D(bug("!!! NO WAY GETTING PALETTE FOR dst IN BltBitMap\n"));
485 else if (srcflags
== (FLG_TRUECOLOR
| FLG_HASCOLMAP
))
488 /* Use the src colmap for dst */
489 HIDD_BM_SetColorMap(dstbm_obj
, HIDD_BM_COLMAP(srcBitMap
));
491 dst_colmap_set
= TRUE
;
497 /* We need special treatment with drawmode Clear and
498 truecolor bitmaps, in order to set it to
499 colormap[0] instead of just 0
501 if ( (drmd
== vHidd_GC_DrawMode_Clear
)
502 && ( (dstflags
& (FLG_TRUECOLOR
| FLG_HASCOLMAP
)) == (FLG_TRUECOLOR
| FLG_HASCOLMAP
) ))
505 HIDDT_DrawMode old_drmd
;
508 struct TagItem frtags
[] =
510 { aHidd_GC_Foreground
, 0 },
511 { aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
515 OOP_GetAttr(gc
, aHidd_GC_DrawMode
, &old_drmd
);
516 OOP_GetAttr(gc
, aHidd_GC_Foreground
, &old_fg
);
518 frtags
[0].ti_Data
= HIDD_BM_PIXTAB(dstBitMap
)[0];
519 frtags
[1].ti_Data
= vHidd_GC_DrawMode_Copy
;
521 OOP_SetAttrs(gc
, frtags
);
523 HIDD_BM_FillRect(dstbm_obj
, gc
529 frtags
[0].ti_Data
= old_fg
;
530 frtags
[1].ti_Data
= old_drmd
;
535 HIDDT_DrawMode old_drmd
;
537 struct TagItem cbtags
[] =
539 { aHidd_GC_DrawMode
, 0 },
543 OOP_GetAttr(gc
, aHidd_GC_DrawMode
, &old_drmd
);
545 cbtags
[0].ti_Data
= drmd
;
547 OOP_SetAttrs(gc
, cbtags
);
548 HIDD_Gfx_CopyBox(gfxhidd
557 cbtags
[0].ti_Data
= drmd
;
558 OOP_SetAttrs(gc
, cbtags
);
561 } /* if (colmaps_ok) */
564 HIDD_BM_SetColorMap(srcbm_obj
, NULL
);
567 HIDD_BM_SetColorMap(dstbm_obj
, NULL
);
575 /****************************************************************************************/
577 struct wp8_render_data
581 HIDDT_PixelLUT
*pixlut
;
584 static ULONG
wp8_render(APTR wp8r_data
, WORD srcx
, WORD srcy
, OOP_Object
*dstbm_obj
,
585 OOP_Object
*dst_gc
, struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
587 struct wp8_render_data
*wp8rd
= wp8r_data
;
588 WORD width
= rect
->MaxX
- rect
->MinX
+ 1;
589 WORD height
= rect
->MaxY
- rect
->MinY
+ 1;
591 HIDD_BM_PutImageLUT(dstbm_obj
, dst_gc
,
592 wp8rd
->array
+ CHUNKY8_COORD_TO_BYTEIDX(srcx
, srcy
, wp8rd
->modulo
), wp8rd
->modulo
,
593 rect
->MinX
, rect
->MinY
, width
, height
, wp8rd
->pixlut
);
595 return width
* height
;
598 /****************************************************************************************/
600 LONG
write_pixels_8(struct RastPort
*rp
, UBYTE
*array
, ULONG modulo
,
601 WORD xstart
, WORD ystart
, WORD xstop
, WORD ystop
,
602 HIDDT_PixelLUT
*pixlut
, BOOL do_update
, struct GfxBase
*GfxBase
)
604 struct wp8_render_data wp8rd
;
607 HIDDT_PixelLUT bm_lut
;
609 /* If we haven't got a LUT, we obtain it from the bitmap */
610 if ((!pixlut
) && IS_HIDD_BM(rp
->BitMap
))
612 bm_lut
.entries
= AROS_PALETTE_SIZE
;
613 bm_lut
.pixels
= HIDD_BM_PIXTAB(rp
->BitMap
);
616 #ifdef RTG_SANITY_CHECK
617 if ((!bm_lut
.pixels
) && (HIDD_BM_REALDEPTH(rp
->BitMap
) > 8))
619 D(bug("write_pixels_8: can't work on hicolor/truecolor screen without LUT"));
625 gc
= GetDriverData(rp
, GfxBase
);
626 GC_DRMD(gc
) = vHidd_GC_DrawMode_Copy
;
628 wp8rd
.modulo
= modulo
;
630 wp8rd
.pixlut
= pixlut
;
637 return do_render_with_gc(rp
, NULL
, &rr
, wp8_render
, &wp8rd
, gc
, do_update
, FALSE
, GfxBase
);
640 /****************************************************************************************/
642 struct wtp8_render_data
646 HIDDT_PixelLUT
*pixlut
;
650 static ULONG
wtp8_render(APTR wtp8r_data
, WORD srcx
, WORD srcy
, OOP_Object
*dstbm_obj
,
651 OOP_Object
*dst_gc
, struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
653 struct wtp8_render_data
*wtp8rd
= wtp8r_data
;
654 WORD width
= rect
->MaxX
- rect
->MinX
+ 1;
655 WORD height
= rect
->MaxY
- rect
->MinY
+ 1;
657 HIDD_BM_PutTranspImageLUT(dstbm_obj
, dst_gc
,
658 wtp8rd
->array
+ CHUNKY8_COORD_TO_BYTEIDX(srcx
, srcy
, wtp8rd
->modulo
), wtp8rd
->modulo
,
659 rect
->MinX
, rect
->MinY
,width
, height
, wtp8rd
->pixlut
, wtp8rd
->transparent
);
661 return width
* height
;
663 /****************************************************************************************/
665 LONG
write_transp_pixels_8(struct RastPort
*rp
, UBYTE
*array
, ULONG modulo
,
666 WORD xstart
, WORD ystart
, WORD xstop
, WORD ystop
,
667 HIDDT_PixelLUT
*pixlut
, UBYTE transparent
,
668 BOOL do_update
, struct GfxBase
*GfxBase
)
670 struct wtp8_render_data wtp8rd
;
674 gc
= GetDriverData(rp
, GfxBase
);
675 GC_DRMD(gc
) = vHidd_GC_DrawMode_Copy
;
677 wtp8rd
.modulo
= modulo
;
678 wtp8rd
.array
= array
;
679 wtp8rd
.pixlut
= pixlut
;
680 wtp8rd
.transparent
= transparent
;
687 return do_render_with_gc(rp
, NULL
, &rr
, wtp8_render
, &wtp8rd
, gc
, do_update
, FALSE
, GfxBase
);
690 /****************************************************************************************/
693 ** General functions for moving blocks of data to or from HIDDs, be it pixelarrays
694 ** or bitmaps. They use a callback-function to get data from amiga/put data to amiga
695 ** bitmaps/pixelarrays
698 /****************************************************************************************/
700 /****************************************************************************************/
702 #define ENABLE_PROFILING 0
703 #define USE_OLD_MoveRaster 0
705 #define rdtscll(val) \
706 __asm__ __volatile__("rdtsc" : "=A" (val))
708 #if ENABLE_PROFILING && defined(__i386__)
711 #define AROS_BEGIN_PROFILING(context) \
713 unsigned long long _time1, _time2; \
714 char *_text = #context; \
718 #define AROS_END_PROFILING \
721 kprintf("%s: Ticks count: %u\n", _text, (unsigned long)(_time2 - _time1)); \
726 #define AROS_BEGIN_PROFILING(context)
727 #define AROS_END_PROFILING
731 BOOL
MoveRaster (struct RastPort
* rp
, WORD dx
, WORD dy
, WORD x1
, WORD y1
,
732 WORD x2
, WORD y2
, BOOL UpdateDamageList
, struct GfxBase
* GfxBase
)
734 struct Layer
*L
= rp
->Layer
;
735 struct Rectangle ScrollRect
;
736 struct Rectangle Rect
;
738 if (0 == dx
&& 0 == dy
)
741 ScrollRect
.MinX
= x1
;
742 ScrollRect
.MinY
= y1
;
743 ScrollRect
.MaxX
= x2
;
744 ScrollRect
.MaxY
= y2
;
749 TranslateRect(&Rect
, -dx
, -dy
);
750 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
752 BltBitMap(rp
->BitMap
,
758 Rect
.MaxX
- Rect
.MinX
+ 1,
759 Rect
.MaxY
- Rect
.MinY
+ 1,
767 struct ClipRect
*SrcCR
;
771 if (L
->Flags
& LAYERSIMPLE
&& UpdateDamageList
)
773 /* Scroll the old damagelist within the scroll area */
774 ScrollRegion(L
->DamageList
, &ScrollRect
, -dx
, -dy
);
777 /* The scrolling area is relative to the Layer, so make it relative to the screen */
778 TranslateRect(&ScrollRect
, MinX(L
), MinY(L
));
780 /* The damage list will be formed by the now hidden layer's parts that will become visible due
781 to the scrolling procedure, thus we procede this way:
783 1) Calculate the invisible region out of the visible one, subtracting it from the
786 2) Scroll the invisible region by (-dx, -dy) and then subtract from it the not scrolled equivalent
788 The regions that we obtain after (2) is the new damage list
791 if (L
->Flags
& LAYERSIMPLE
&& UpdateDamageList
)
795 TranslateRect(&Rect
, dx
, dy
);
797 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
799 struct Region
*Damage
= NewRegion();
804 BOOL res
= OrRectRegion(Damage
, &ScrollRect
);
806 BOOL res
= OrRectRegion(Damage
, &Rect
);
810 DisposeRegion(Damage
);
819 ClearRegionRegion(L
->VisibleRegion
, Damage
)
821 Damage
->RegionRectangle
826 We play sort of dirty here, by making assumptions about the internals of the
827 Region structure and the region handling functions, but we are allowed to do that,
833 TranslateRect(Bounds(Damage
), -dx
, -dy
);
837 ClearRegionRegion(&Tmp
, Damage
)
839 Damage
->RegionRectangle
843 AndRectRegion(Damage
, &ScrollRect
);
844 if (Damage
->RegionRectangle
)
848 /* Join the new damage list with the old one */
849 TranslateRect(Bounds(Damage
), -MinX(L
), -MinY(L
));
850 OrRegionRegion(Damage
, L
->DamageList
);
852 L
->Flags
|= LAYERREFRESH
;
857 DisposeRegion(Damage
);
862 AROS_BEGIN_PROFILING(SortLayerCR
)
865 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.