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
;
110 if ((rr
->MaxX
< rr
->MinX
) || (rr
->MaxY
< rr
->MinY
)) return 0;
124 /* No layer, probably a screen, but may be a user inited bitmap */
125 struct Rectangle torender
= *rr
;
127 have_rp_cliprectangle
= GetRPClipRectangleForBitMap(rp
, bm
, &rp_clip_rectangle
, GfxBase
);
128 if (have_rp_cliprectangle
&& !(_AndRectRect(rr
, &rp_clip_rectangle
, &torender
)))
133 srcx
+= (torender
.MinX
- rr
->MinX
);
134 srcy
+= (torender
.MinY
- rr
->MinY
);
136 if (get_special_info
)
138 RSI(funcdata
)->curbm
= rp
->BitMap
;
141 pixwritten
= CallRenderFunc(render_func
, funcdata
, srcx
, srcy
,
142 bm
, gc
, &torender
, do_update
, GfxBase
);
149 struct Rectangle torender
, intersect
;
153 have_rp_cliprectangle
= GetRPClipRectangleForLayer(rp
, L
, &rp_clip_rectangle
, GfxBase
);
155 xrel
= L
->bounds
.MinX
;
156 yrel
= L
->bounds
.MinY
;
158 torender
.MinX
= rr
->MinX
+ xrel
- L
->Scroll_X
;
159 torender
.MinY
= rr
->MinY
+ yrel
- L
->Scroll_Y
;
160 torender
.MaxX
= rr
->MaxX
+ xrel
- L
->Scroll_X
;
161 torender
.MaxY
= rr
->MaxY
+ yrel
- L
->Scroll_Y
;
165 for (;NULL
!= CR
; CR
= CR
->Next
)
167 D(bug("Cliprect (%d, %d, %d, %d), lobs=%p\n",
168 CR
->bounds
.MinX
, CR
->bounds
.MinY
, CR
->bounds
.MaxX
, CR
->bounds
.MaxY
,
171 /* Does this cliprect intersect with area to rectfill ? */
172 if (_AndRectRect(&CR
->bounds
, &torender
, &intersect
))
174 if (!have_rp_cliprectangle
|| _AndRectRect(&rp_clip_rectangle
, &intersect
, &intersect
))
176 WORD xoffset
, yoffset
;
178 xoffset
= intersect
.MinX
- torender
.MinX
;
179 yoffset
= intersect
.MinY
- torender
.MinY
;
181 if (NULL
== CR
->lobs
)
183 if (get_special_info
)
185 RSI(funcdata
)->curbm
= bm
;
188 pixwritten
+= CallRenderFunc(render_func
, funcdata
, srcx
+ xoffset
, srcy
+ yoffset
,
189 bm
, gc
, &intersect
, do_update
, GfxBase
);
193 /* Render into offscreen cliprect bitmap */
194 if (L
->Flags
& LAYERSIMPLE
)
196 else if (L
->Flags
& LAYERSUPER
)
198 D(bug("do_render_func(): Superbitmap not handled yet\n"));
203 if (get_special_info
)
205 RSI(funcdata
)->curbm
= CR
->BitMap
;
208 intersect
.MinX
= intersect
.MinX
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
);
209 intersect
.MinY
= intersect
.MinY
- CR
->bounds
.MinY
;
210 intersect
.MaxX
= intersect
.MaxX
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
);
211 intersect
.MaxY
= intersect
.MaxY
- CR
->bounds
.MinY
;
213 pixwritten
+= CallRenderFunc(render_func
, funcdata
, srcx
+ xoffset
, srcy
+ yoffset
,
214 CR
->BitMap
, gc
, &intersect
, do_update
, GfxBase
);
217 } /* if (CR->lobs == NULL) */
219 } /* if it also intersects with possible rastport clip rectangle */
221 } /* if (cliprect intersects with area to render into) */
223 } /* for (each cliprect in the layer) */
226 } /* if (rp->Layer) */
231 /****************************************************************************************/
233 static LONG
CallPixelFunc(PIXELFUNC render_func
, APTR funcdata
, struct BitMap
*bm
, OOP_Object
*gc
,
234 WORD x
, WORD y
, BOOL do_update
, struct GfxBase
*GfxBase
)
236 OOP_Object
*bm_obj
= OBTAIN_HIDD_BM(bm
);
242 retval
= render_func(funcdata
, bm_obj
, gc
, x
, y
, GfxBase
);
245 update_bitmap(bm
, bm_obj
, x
, y
, 1, 1, GfxBase
);
247 RELEASE_HIDD_BM(bm_obj
, bm
);
251 ULONG
do_pixel_func(struct RastPort
*rp
253 , PIXELFUNC render_func
256 , struct GfxBase
*GfxBase
)
258 struct BitMap
*bm
= rp
->BitMap
;
259 struct Layer
*L
= rp
->Layer
;
261 struct Rectangle rp_clip_rectangle
;
262 BOOL have_rp_cliprectangle
;
265 gc
= GetDriverData(rp
, GfxBase
);
269 have_rp_cliprectangle
= GetRPClipRectangleForBitMap(rp
, bm
, &rp_clip_rectangle
, GfxBase
);
270 if (have_rp_cliprectangle
&& !_IsPointInRect(&rp_clip_rectangle
, x
, y
))
275 #if 0 /* With enabled BITMAP_CLIPPING this will be done automatically */
276 OOP_GetAttr(bm_obj
, aHidd_BitMap_Width
, &width
);
277 OOP_GetAttr(bm_obj
, aHidd_BitMap_Height
, &height
);
279 /* Check whether we it is inside the rastport */
289 /* This is a screen */
290 retval
= CallPixelFunc(render_func
, funcdata
, bm
, gc
, x
, y
, do_update
, GfxBase
);
299 have_rp_cliprectangle
= GetRPClipRectangleForLayer(rp
, L
, &rp_clip_rectangle
, GfxBase
);
303 absx
= x
+ L
->bounds
.MinX
- L
->Scroll_X
;
304 absy
= y
+ L
->bounds
.MinY
- L
->Scroll_Y
;
306 for (;NULL
!= CR
; CR
= CR
->Next
)
309 if ( absx
>= CR
->bounds
.MinX
310 && absy
>= CR
->bounds
.MinY
311 && absx
<= CR
->bounds
.MaxX
312 && absy
<= CR
->bounds
.MaxY
)
315 if (!have_rp_cliprectangle
|| _IsPointInRect(&rp_clip_rectangle
, absx
, absy
))
317 if (NULL
== CR
->lobs
)
319 retval
= CallPixelFunc(render_func
, funcdata
, bm
, gc
,
320 absx
, absy
, do_update
, GfxBase
);
324 /* This is the tricky one: render into offscreen cliprect bitmap */
325 if (L
->Flags
& LAYERSIMPLE
)
327 /* We cannot do anything */
331 else if (L
->Flags
& LAYERSUPER
)
333 D(bug("driver_WriteRGBPixel(): Superbitmap not handled yet\n"));
337 retval
= CallPixelFunc(render_func
, funcdata
, CR
->BitMap
, gc
,
338 absx
- CR
->bounds
.MinX
+ ALIGN_OFFSET(CR
->bounds
.MinX
),
339 absy
- CR
->bounds
.MinY
,
341 } /* If (SMARTREFRESH cliprect) */
343 } /* if (intersecton inside hidden cliprect) */
345 } /* if point is also inside possible rastport clip rectangle */
347 /* The pixel was found and put inside one of the cliprects, just exit */
350 } /* if (cliprect intersects with area we want to draw to) */
352 } /* while (cliprects to examine) */
359 /****************************************************************************************/
361 ULONG
fillrect_render(APTR funcdata
, WORD srcx
, WORD srcy
,
362 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
,
363 struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
365 HIDD_BM_FillRect(dstbm_obj
, dst_gc
, rect
->MinX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
);
367 return (rect
->MaxX
- rect
->MinX
+ 1) * (rect
->MaxY
- rect
->MinY
+ 1);
370 /****************************************************************************************/
372 LONG
fillrect_pendrmd(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
,
373 HIDDT_Pixel pix
, HIDDT_DrawMode drmd
, BOOL do_update
, struct GfxBase
*GfxBase
)
378 gc
= GetDriverData(rp
, GfxBase
);
387 return do_render_with_gc(rp
, NULL
, &rr
, fillrect_render
, NULL
, gc
, do_update
, FALSE
, GfxBase
);
390 /****************************************************************************************/
392 BOOL
int_bltbitmap(struct BitMap
*srcBitMap
, OOP_Object
*srcbm_obj
, WORD xSrc
, WORD ySrc
,
393 struct BitMap
*dstBitMap
, OOP_Object
*dstbm_obj
, WORD xDest
, WORD yDest
,
394 WORD xSize
, WORD ySize
, ULONG minterm
, OOP_Object
*gfxhidd
, OOP_Object
*gc
,
395 struct GfxBase
*GfxBase
)
402 BOOL src_colmap_set
= FALSE
;
403 BOOL dst_colmap_set
= FALSE
;
405 BOOL colmaps_ok
= TRUE
;
407 drmd
= MINTERM_TO_GCDRMD(minterm
);
409 /* We must lock any HIDD_BM_SetColorMap calls */
412 /* Try to get a CLUT for the bitmaps */
413 if (IS_HIDD_BM(srcBitMap
))
415 //bug("driver_intbltbitmap: source is hidd bitmap\n");
416 if (NULL
!= HIDD_BM_COLMAP(srcBitMap
))
418 //bug("driver_intbltbitmap: source has colormap\n");
419 srcflags
|= FLG_HASCOLMAP
;
421 srcflags
|= GET_COLMOD_FLAGS(srcBitMap
);
425 //bug("driver_intbltbitmap: source is amiga bitmap\n");
427 srcflags
|= FLG_PALETTE
;
430 if (IS_HIDD_BM(dstBitMap
))
432 //bug("driver_intbltbitmap: dest is hidd bitmap\n");
433 if (NULL
!= HIDD_BM_COLMAP(dstBitMap
))
435 //bug("driver_intbltbitmap: dest has colormap\n");
436 dstflags
|= FLG_HASCOLMAP
;
438 dstflags
|= GET_COLMOD_FLAGS(dstBitMap
);
442 //bug("driver_intbltbitmap: dest is amiga bitmap\n");
444 dstflags
|= FLG_PALETTE
;
447 if ( (srcflags
== FLG_PALETTE
|| srcflags
== FLG_STATICPALETTE
))
449 /* palettized with no colmap. Need to get a colmap from dest */
450 if (dstflags
== FLG_TRUECOLOR
)
453 D(bug("!!! NO WAY GETTING PALETTE FOR src IN BltBitMap\n"));
458 else if (dstflags
== (FLG_TRUECOLOR
| FLG_HASCOLMAP
))
461 /* Use the dest colmap for src */
462 HIDD_BM_SetColorMap(srcbm_obj
, HIDD_BM_COLMAP(dstBitMap
));
464 src_colmap_set
= TRUE
;
470 for (idx = 0; idx < 256; idx ++)
471 bug("[%d]=%d ", idx, HIDD_CM_GetPixel(HIDD_BM_COLMAP(dstBitMap), idx));
477 if ( (dstflags
== FLG_PALETTE
|| dstflags
== FLG_STATICPALETTE
))
479 /* palettized with no pixtab. Nees to get a pixtab from dest*/
480 if (srcflags
== FLG_TRUECOLOR
)
482 D(bug("!!! NO WAY GETTING PALETTE FOR dst IN BltBitMap\n"));
487 else if (srcflags
== (FLG_TRUECOLOR
| FLG_HASCOLMAP
))
490 /* Use the src colmap for dst */
491 HIDD_BM_SetColorMap(dstbm_obj
, HIDD_BM_COLMAP(srcBitMap
));
493 dst_colmap_set
= TRUE
;
499 /* We need special treatment with drawmode Clear and
500 truecolor bitmaps, in order to set it to
501 colormap[0] instead of just 0
503 if ( (drmd
== vHidd_GC_DrawMode_Clear
)
504 && ( (dstflags
& (FLG_TRUECOLOR
| FLG_HASCOLMAP
)) == (FLG_TRUECOLOR
| FLG_HASCOLMAP
) ))
507 HIDDT_DrawMode old_drmd
;
510 struct TagItem frtags
[] =
512 { aHidd_GC_Foreground
, 0 },
513 { aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
517 OOP_GetAttr(gc
, aHidd_GC_DrawMode
, &old_drmd
);
518 OOP_GetAttr(gc
, aHidd_GC_Foreground
, &old_fg
);
520 frtags
[0].ti_Data
= HIDD_BM_PIXTAB(dstBitMap
)[0];
521 frtags
[1].ti_Data
= vHidd_GC_DrawMode_Copy
;
523 OOP_SetAttrs(gc
, frtags
);
525 HIDD_BM_FillRect(dstbm_obj
, gc
531 frtags
[0].ti_Data
= old_fg
;
532 frtags
[1].ti_Data
= old_drmd
;
537 HIDDT_DrawMode old_drmd
;
539 struct TagItem cbtags
[] =
541 { aHidd_GC_DrawMode
, 0 },
545 OOP_GetAttr(gc
, aHidd_GC_DrawMode
, &old_drmd
);
547 cbtags
[0].ti_Data
= drmd
;
549 OOP_SetAttrs(gc
, cbtags
);
550 HIDD_Gfx_CopyBox(gfxhidd
559 cbtags
[0].ti_Data
= drmd
;
560 OOP_SetAttrs(gc
, cbtags
);
563 } /* if (colmaps_ok) */
566 HIDD_BM_SetColorMap(srcbm_obj
, NULL
);
569 HIDD_BM_SetColorMap(dstbm_obj
, NULL
);
577 /****************************************************************************************/
579 struct wp8_render_data
583 HIDDT_PixelLUT
*pixlut
;
586 static ULONG
wp8_render(APTR wp8r_data
, WORD srcx
, WORD srcy
, OOP_Object
*dstbm_obj
,
587 OOP_Object
*dst_gc
, struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
589 struct wp8_render_data
*wp8rd
= wp8r_data
;
590 WORD width
= rect
->MaxX
- rect
->MinX
+ 1;
591 WORD height
= rect
->MaxY
- rect
->MinY
+ 1;
593 HIDD_BM_PutImageLUT(dstbm_obj
, dst_gc
,
594 wp8rd
->array
+ CHUNKY8_COORD_TO_BYTEIDX(srcx
, srcy
, wp8rd
->modulo
), wp8rd
->modulo
,
595 rect
->MinX
, rect
->MinY
, width
, height
, wp8rd
->pixlut
);
597 return width
* height
;
600 /****************************************************************************************/
602 LONG
write_pixels_8(struct RastPort
*rp
, UBYTE
*array
, ULONG modulo
,
603 WORD xstart
, WORD ystart
, WORD xstop
, WORD ystop
,
604 HIDDT_PixelLUT
*pixlut
, BOOL do_update
, struct GfxBase
*GfxBase
)
606 struct wp8_render_data wp8rd
;
609 HIDDT_PixelLUT bm_lut
;
611 /* If we haven't got a LUT, we obtain it from the bitmap */
612 if ((!pixlut
) && IS_HIDD_BM(rp
->BitMap
))
614 bm_lut
.entries
= AROS_PALETTE_SIZE
;
615 bm_lut
.pixels
= HIDD_BM_PIXTAB(rp
->BitMap
);
618 #ifdef RTG_SANITY_CHECK
619 if ((!bm_lut
.pixels
) && (HIDD_BM_REALDEPTH(rp
->BitMap
) > 8))
621 D(bug("write_pixels_8: can't work on hicolor/truecolor screen without LUT"));
627 gc
= GetDriverData(rp
, GfxBase
);
628 GC_DRMD(gc
) = vHidd_GC_DrawMode_Copy
;
630 wp8rd
.modulo
= modulo
;
632 wp8rd
.pixlut
= pixlut
;
639 return do_render_with_gc(rp
, NULL
, &rr
, wp8_render
, &wp8rd
, gc
, do_update
, FALSE
, GfxBase
);
642 /****************************************************************************************/
644 struct wtp8_render_data
648 HIDDT_PixelLUT
*pixlut
;
652 static ULONG
wtp8_render(APTR wtp8r_data
, WORD srcx
, WORD srcy
, OOP_Object
*dstbm_obj
,
653 OOP_Object
*dst_gc
, struct Rectangle
*rect
, struct GfxBase
*GfxBase
)
655 struct wtp8_render_data
*wtp8rd
= wtp8r_data
;
656 WORD width
= rect
->MaxX
- rect
->MinX
+ 1;
657 WORD height
= rect
->MaxY
- rect
->MinY
+ 1;
659 HIDD_BM_PutTranspImageLUT(dstbm_obj
, dst_gc
,
660 wtp8rd
->array
+ CHUNKY8_COORD_TO_BYTEIDX(srcx
, srcy
, wtp8rd
->modulo
), wtp8rd
->modulo
,
661 rect
->MinX
, rect
->MinY
,width
, height
, wtp8rd
->pixlut
, wtp8rd
->transparent
);
663 return width
* height
;
665 /****************************************************************************************/
667 LONG
write_transp_pixels_8(struct RastPort
*rp
, UBYTE
*array
, ULONG modulo
,
668 WORD xstart
, WORD ystart
, WORD xstop
, WORD ystop
,
669 HIDDT_PixelLUT
*pixlut
, UBYTE transparent
,
670 BOOL do_update
, struct GfxBase
*GfxBase
)
672 struct wtp8_render_data wtp8rd
;
676 gc
= GetDriverData(rp
, GfxBase
);
677 GC_DRMD(gc
) = vHidd_GC_DrawMode_Copy
;
679 wtp8rd
.modulo
= modulo
;
680 wtp8rd
.array
= array
;
681 wtp8rd
.pixlut
= pixlut
;
682 wtp8rd
.transparent
= transparent
;
689 return do_render_with_gc(rp
, NULL
, &rr
, wtp8_render
, &wtp8rd
, gc
, do_update
, FALSE
, GfxBase
);
692 /****************************************************************************************/
695 ** General functions for moving blocks of data to or from HIDDs, be it pixelarrays
696 ** or bitmaps. They use a callback-function to get data from amiga/put data to amiga
697 ** bitmaps/pixelarrays
700 /****************************************************************************************/
702 /****************************************************************************************/
704 #define ENABLE_PROFILING 0
705 #define USE_OLD_MoveRaster 0
707 #define rdtscll(val) \
708 __asm__ __volatile__("rdtsc" : "=A" (val))
710 #if ENABLE_PROFILING && defined(__i386__)
713 #define AROS_BEGIN_PROFILING(context) \
715 unsigned long long _time1, _time2; \
716 char *_text = #context; \
720 #define AROS_END_PROFILING \
723 kprintf("%s: Ticks count: %u\n", _text, (unsigned long)(_time2 - _time1)); \
728 #define AROS_BEGIN_PROFILING(context)
729 #define AROS_END_PROFILING
733 BOOL
MoveRaster (struct RastPort
* rp
, WORD dx
, WORD dy
, WORD x1
, WORD y1
,
734 WORD x2
, WORD y2
, BOOL UpdateDamageList
, struct GfxBase
* GfxBase
)
736 struct Layer
*L
= rp
->Layer
;
737 struct Rectangle ScrollRect
;
738 struct Rectangle Rect
;
740 if (0 == dx
&& 0 == dy
)
743 ScrollRect
.MinX
= x1
;
744 ScrollRect
.MinY
= y1
;
745 ScrollRect
.MaxX
= x2
;
746 ScrollRect
.MaxY
= y2
;
751 TranslateRect(&Rect
, -dx
, -dy
);
752 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
754 BltBitMap(rp
->BitMap
,
760 Rect
.MaxX
- Rect
.MinX
+ 1,
761 Rect
.MaxY
- Rect
.MinY
+ 1,
769 struct ClipRect
*SrcCR
;
773 if (L
->Flags
& LAYERSIMPLE
&& UpdateDamageList
)
775 /* Scroll the old damagelist within the scroll area */
776 ScrollRegion(L
->DamageList
, &ScrollRect
, -dx
, -dy
);
779 /* The scrolling area is relative to the Layer, so make it relative to the screen */
780 TranslateRect(&ScrollRect
, MinX(L
), MinY(L
));
782 /* The damage list will be formed by the now hidden layer's parts that will become visible due
783 to the scrolling procedure, thus we procede this way:
785 1) Calculate the invisible region out of the visible one, subtracting it from the
788 2) Scroll the invisible region by (-dx, -dy) and then subtract from it the not scrolled equivalent
790 The regions that we obtain after (2) is the new damage list
793 if (L
->Flags
& LAYERSIMPLE
&& UpdateDamageList
)
797 TranslateRect(&Rect
, dx
, dy
);
799 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
801 struct Region
*Damage
= NewRegion();
806 BOOL res
= OrRectRegion(Damage
, &ScrollRect
);
808 BOOL res
= OrRectRegion(Damage
, &Rect
);
812 DisposeRegion(Damage
);
821 ClearRegionRegion(L
->VisibleRegion
, Damage
)
823 Damage
->RegionRectangle
828 We play sort of dirty here, by making assumptions about the internals of the
829 Region structure and the region handling functions, but we are allowed to do that,
835 TranslateRect(Bounds(Damage
), -dx
, -dy
);
839 ClearRegionRegion(&Tmp
, Damage
)
841 Damage
->RegionRectangle
845 AndRectRegion(Damage
, &ScrollRect
);
846 if (Damage
->RegionRectangle
)
850 /* Join the new damage list with the old one */
851 TranslateRect(Bounds(Damage
), -MinX(L
), -MinY(L
));
852 OrRegionRegion(Damage
, L
->DamageList
);
854 L
->Flags
|= LAYERREFRESH
;
859 DisposeRegion(Damage
);
864 AROS_BEGIN_PROFILING(SortLayerCR
)
867 SortLayerCR(L
, dx
, dy
);
871 AROS_BEGIN_PROFILING(Blitting loop
)
873 #if USE_OLDMoveRaster
876 struct ClipRect
*LastHiddenCR
;
878 for (LastHiddenCR
= NULL
, SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
880 SrcCR
->_p1
= LastHiddenCR
;
883 LastHiddenCR
= SrcCR
;
888 for (SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
892 if (SrcCR
->lobs
&& (L
->Flags
& LAYERSIMPLE
))
897 if (_AndRectRect(&ScrollRect
, Bounds(SrcCR
), &Rect
))
899 TranslateRect(&Rect
, -dx
, -dy
);
901 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
907 /* Rect.Min(X|Y) are the coordinates to wich the rectangle has to be moved
908 Rect.Max(X|Y) - Rect.Max(X|Y) - 1 are the dimensions of this rectangle */
909 if (!SrcCR
->_p1
&& !SrcCR
->lobs
)
911 /* there are no hidden/obscured rectangles this recrtangle has to deal with*/
920 Rect
.MaxX
- Rect
.MinX
+ 1,
921 Rect
.MaxY
- Rect
.MinY
+ 1,
929 struct BitMap
*srcbm
;
930 struct RegionRectangle
*rr
;
931 struct Region
*RectRegion
= NewRegion();
932 struct Rectangle Tmp
;
933 struct ClipRect
*HiddCR
;
934 WORD corrsrcx
, corrsrcy
;
940 if (!OrRectRegion(&Rect
, RectRegion
))
942 DisposeRegion(RectRegion
);
948 if (L
->Flags
& LAYERSUPER
)
950 corrsrcx
= - MinX(L
) - L
->Scroll_X
;
951 corrsrcy
= - MinY(L
) - L
->Scroll_Y
;
955 corrsrcx
= - MinX(SrcCR
) + ALIGN_OFFSET(MinX(SrcCR
));
956 corrsrcy
= - MinY(SrcCR
);
958 srcbm
= SrcCR
->BitMap
;
967 for (HiddCR
= SrcCR
->_p1
; HiddCR
; HiddCR
= HiddCR
->_p1
)
969 if (_AndRectRect(Bounds(RectRegion
), Bounds(HiddCR
), &Tmp
))
971 if (!(L
->Flags
& LAYERSIMPLE
))
973 WORD corrdstx
, corrdsty
;
975 if (L
->Flags
& LAYERSUPER
)
977 corrdstx
= - MinX(L
) - L
->Scroll_X
;
978 corrdsty
= - MinY(L
) - L
->Scroll_Y
;
983 corrdstx
= - MinX(HiddCR
) + ALIGN_OFFSET(MinX(HiddCR
));
984 corrdsty
= - MinY(HiddCR
);
991 Tmp
.MinX
+ corrsrcx
+ dx
,
992 Tmp
.MinY
+ corrsrcy
+ dy
,
996 Tmp
.MaxX
- Tmp
.MinX
+ 1,
997 Tmp
.MaxY
- Tmp
.MinY
+ 1,
1004 if (!ClearRectRegion(RectRegion
, &Tmp
))
1006 DisposeRegion(RectRegion
);
1012 if ((dosrcsrc
= _AndRectRect(Bounds(SrcCR
), &Rect
, &Tmp
)))
1014 if (!ClearRectRegion(RectRegion
, &Tmp
))
1016 DisposeRegion(RectRegion
);
1021 for (rr
= RectRegion
->RegionRectangle
; rr
; rr
= rr
->Next
)
1026 MinX(rr
) + MinX(RectRegion
) + corrsrcx
+ dx
,
1027 MinY(rr
) + MinY(RectRegion
) + corrsrcy
+ dy
,
1029 MinX(rr
) + MinX(RectRegion
),
1030 MinY(rr
) + MinY(RectRegion
),
1044 Tmp
.MinX
+ corrsrcx
+ dx
,
1045 Tmp
.MinY
+ corrsrcy
+ dy
,
1047 Tmp
.MinX
+ corrsrcx
,
1048 Tmp
.MinY
+ corrsrcy
,
1049 Tmp
.MaxX
- Tmp
.MinX
+ 1,
1050 Tmp
.MaxY
- Tmp
.MinY
+ 1,
1058 DisposeRegion(RectRegion
);
1065 for (SrcCR
= L
->ClipRect
; SrcCR
; SrcCR
= SrcCR
->Next
)
1067 if (_AndRectRect(&ScrollRect
, Bounds(SrcCR
), &Rect
))
1069 TranslateRect(&Rect
, -dx
, -dy
);
1071 if (_AndRectRect(&ScrollRect
, &Rect
, &Rect
))
1073 struct BitMap
*srcbm
;
1074 struct ClipRect
*DstCR
;
1075 WORD corrsrcx
, corrsrcy
;
1080 if (L
->Flags
& LAYERSIMPLE
) continue;
1082 if (L
->Flags
& LAYERSUPER
)
1084 corrsrcx
= - MinX(L
) - L
->Scroll_X
;
1085 corrsrcy
= - MinY(L
) - L
->Scroll_Y
;
1089 corrsrcx
= - MinX(SrcCR
) + ALIGN_OFFSET(MinX(SrcCR
));
1090 corrsrcy
= - MinY(SrcCR
);
1092 srcbm
= SrcCR
->BitMap
;
1101 area
= (Rect
.MaxX
- Rect
.MinX
+ 1) * (Rect
.MaxY
- Rect
.MinY
+ 1);
1103 for (DstCR
= L
->ClipRect
; area
&& DstCR
; DstCR
= DstCR
->Next
)
1105 struct Rectangle Rect2
;
1107 if (_AndRectRect(Bounds(DstCR
), &Rect
, &Rect2
))
1109 struct BitMap
*dstbm
;
1110 WORD corrdstx
, corrdsty
;
1112 area
-= (Rect2
.MaxX
- Rect2
.MinX
+ 1) * (Rect2
.MaxY
- Rect2
.MinY
+ 1);
1116 if (L
->Flags
& LAYERSIMPLE
) continue;
1118 if (L
->Flags
& LAYERSUPER
)
1120 corrdstx
= - MinX(L
) - L
->Scroll_X
;
1121 corrdsty
= - MinY(L
) - L
->Scroll_Y
;
1125 corrdstx
= - MinX(DstCR
) + ALIGN_OFFSET(MinX(DstCR
));
1126 corrdsty
= - MinY(DstCR
);
1128 dstbm
= DstCR
->BitMap
;
1140 Rect2
.MinX
+ corrsrcx
+ dx
,
1141 Rect2
.MinY
+ corrsrcy
+ dy
,
1143 Rect2
.MinX
+ corrdstx
,
1144 Rect2
.MinY
+ corrdsty
,
1145 Rect2
.MaxX
- Rect2
.MinX
+ 1,
1146 Rect2
.MaxY
- Rect2
.MinY
+ 1,
1165 /****************************************************************************************/
1167 BOOL
GetRPClipRectangleForRect(struct RastPort
*rp
, struct Rectangle
*rect
, struct Rectangle
*r
)
1169 struct gfx_driverdata
*dd
= ObtainDriverData(rp
);
1171 if (dd
&& dd
->dd_ClipRectangleFlags
& RPCRF_VALID
)
1173 *r
= dd
->dd_ClipRectangle
;
1175 if (dd
->dd_ClipRectangleFlags
& RPCRF_RELRIGHT
)
1177 r
->MaxX
+= rect
->MaxX
- rect
->MinX
;
1180 if (dd
->dd_ClipRectangleFlags
& RPCRF_RELBOTTOM
)
1182 r
->MaxY
+= rect
->MaxY
- rect
->MinY
;
1185 r
->MinX
+= rect
->MinX
;
1186 r
->MinY
+= rect
->MinY
;
1187 r
->MaxX
+= rect
->MinX
;
1188 r
->MaxY
+= rect
->MinY
;
1196 /****************************************************************************************/
1198 BOOL
GetRPClipRectangleForBitMap(struct RastPort
*rp
, struct BitMap
*bm
,
1199 struct Rectangle
*r
, struct GfxBase
*GfxBase
)
1201 struct Rectangle bm_rect
;
1206 bm_rect
.MaxX
= GetBitMapAttr(bm
, BMA_WIDTH
) - 1;
1207 bm_rect
.MaxY
= GetBitMapAttr(bm
, BMA_HEIGHT
) - 1;
1209 res
= GetRPClipRectangleForRect(rp
, &bm_rect
, r
);
1215 * Set the rectangle to total bitmap size. This prevents trashing memory
1216 * by hitting unallocated memory in HIDDs. They don't check bitmap bounds.