2 Copyright © 2010-2014, The AROS Development Team. All rights reserved.
11 #define DREDRAWBM(x) x
12 #define DREDRAWSCR(x) x
25 #include <aros/debug.h>
27 #include <clib/alib_protos.h>
28 #include <proto/exec.h>
29 #include <proto/dos.h>
30 #include <proto/graphics.h>
31 #include <proto/intuition.h>
32 #include <proto/oop.h>
33 #include <proto/utility.h>
35 #include <graphics/view.h>
36 #include <hidd/graphics.h>
38 #include "compositor_intern.h"
40 #define COMPOSITOR_PREFS "SYS/compositor.prefs"
41 #define COMPOSITOR_PEFSTEMPLATE "ABOVE/S,BELOW/S,LEFT/S,RIGHT/S,ALPHA/S"
43 #define CAPABILITY_FLAGS (COMPF_ABOVE|COMPF_BELOW|COMPF_LEFT|COMPF_RIGHT|COMPF_ALPHA)
59 #define GfxBase compdata->GraphicsBase
63 #define IntuitionBase compdata->IntuitionBase
65 #define _RECT(x) x.MinX, x.MinY, x.MaxX, x.MaxY
67 #define MAX(a,b) a > b ? a : b
68 #define MIN(a,b) a < b ? a : b
70 BOOL
isRectInRegion(struct Region
*region
, struct Rectangle
*rect
)
72 struct RegionRectangle
*rrect
= region
->RegionRectangle
;
76 if (AndRectRect(&rrect
->bounds
, rect
, NULL
))
84 static struct StackBitMapNode
* HIDDCompositorFindBitMapStackNode(struct HIDDCompositorData
* compdata
, OOP_Object
* bm
)
86 struct StackBitMapNode
* n
= NULL
;
88 ForeachNode(&compdata
->bitmapstack
, n
)
97 struct Screen
*HIDDCompositorFindBitMapScreen(struct HIDDCompositorData
*compdata
, OOP_Object
*bm
)
99 struct Screen
*curScreen
= NULL
;
101 for (curScreen
= IntuitionBase
->FirstScreen
; curScreen
!= NULL
; curScreen
= curScreen
->NextScreen
)
103 if (bm
== HIDD_BM_OBJ(curScreen
->RastPort
.BitMap
))
107 return (struct Screen
*)NULL
;
110 static VOID
HIDDCompositorValidateBitMapPositionChange(OOP_Object
* bm
, SIPTR
*newxoffset
, SIPTR
*newyoffset
, LONG displayedwidth
, LONG displayedheight
)
113 LONG neglimit
, poslimit
;
115 OOP_GetAttr(bm
, aHidd_BitMap_Width
, &width
);
116 OOP_GetAttr(bm
, aHidd_BitMap_Height
, &height
);
118 /* Check x position */
119 if (width
> displayedwidth
)
121 neglimit
= displayedwidth
- width
;
127 poslimit
= displayedwidth
- width
;
130 if (*(newxoffset
) > poslimit
)
131 *(newxoffset
) = poslimit
;
132 if (*(newxoffset
) < neglimit
)
133 *(newxoffset
) = neglimit
;
135 /* Check y position */
136 if (height
> displayedheight
)
137 neglimit
= displayedheight
- height
; /* Limit for scroll */
140 poslimit
= displayedheight
- 15; /* Limit for drag */
142 if (*(newyoffset
) > poslimit
)
143 *(newyoffset
) = poslimit
;
144 if (*(newyoffset
) < neglimit
)
145 *(newyoffset
) = neglimit
;
148 static VOID
HIDDCompositorRecalculateVisibleRegions(struct HIDDCompositorData
*compdata
)
150 struct StackBitMapNode
*n
= NULL
, *tmpn
;
151 struct Region
*dispvisregion
= NULL
;
152 ULONG oldflags
= compdata
->flags
;
154 DRECALC(bug("[Compositor:%s] Display rect [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__
, _RECT(compdata
->displayrect
)));
157 * This function assumes bitmapstack is in correct Z order:
158 * from topmost to bottom most
160 if ((dispvisregion
= NewRegion()) != NULL
)
162 OrRectRegion(dispvisregion
, &compdata
->displayrect
);
164 compdata
->flags
&= ~COMPSTATEF_HASALPHA
;
165 if (compdata
->alpharegion
)
167 DisposeRegion(compdata
->alpharegion
);
168 compdata
->alpharegion
= NULL
;
170 DRECALC(bug("[Compositor:%s] DisplayRegion @ 0x%p\n", __PRETTY_FUNCTION__
, dispvisregion
));
172 ForeachNodeSafe(&compdata
->bitmapstack
, n
, tmpn
)
174 /* Get bitmap bounding box in screen coordinates */
175 struct Rectangle tmprect
;
177 n
->sbmflags
&= ~STACKNODEF_VISIBLE
;
180 ClearRegion(n
->screenregion
);
182 n
->screenregion
= NewRegion();
186 struct RegionRectangle
*srrect
;
188 tmprect
.MinX
= n
->leftedge
;
189 tmprect
.MaxX
= n
->leftedge
+ OOP_GET(n
->bm
, aHidd_BitMap_Width
) - 1;
190 tmprect
.MinY
= n
->topedge
;
191 tmprect
.MaxY
= n
->topedge
+ OOP_GET(n
->bm
, aHidd_BitMap_Height
) - 1;
193 DRECALC(bug("[Compositor:%s] Screen Rect [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__
, _RECT(tmprect
)));
195 OrRectRegion(n
->screenregion
, &tmprect
); // Start with the Screen's dimensions ..
196 AndRegionRegion(dispvisregion
, n
->screenregion
); // And adjust for the "Display"
198 if ((srrect
= n
->screenregion
->RegionRectangle
) != NULL
)
202 tmprect
.MinX
= srrect
->bounds
.MinX
+ n
->screenregion
->bounds
.MinX
;
203 tmprect
.MinY
= srrect
->bounds
.MinY
+ n
->screenregion
->bounds
.MinY
;
204 tmprect
.MaxX
= srrect
->bounds
.MaxX
+ n
->screenregion
->bounds
.MinX
;
205 tmprect
.MaxY
= srrect
->bounds
.MaxY
+ n
->screenregion
->bounds
.MinY
;
207 if (!(n
->sbmflags
& COMPF_ALPHA
))
208 ClearRectRegion(dispvisregion
, &tmprect
);
211 compdata
->flags
|= COMPSTATEF_HASALPHA
;
212 if (!(compdata
->alpharegion
))
213 compdata
->alpharegion
= NewRegion();
215 OrRectRegion(compdata
->alpharegion
, &tmprect
);
217 srrect
= srrect
->Next
;
220 if (!(compdata
->capabilities
& COMPF_ABOVE
) && !(n
->sbmflags
& COMPF_ABOVE
))
222 tmprect
.MinX
= compdata
->displayrect
.MinX
;
223 tmprect
.MaxX
= compdata
->displayrect
.MaxX
;
224 tmprect
.MinY
= compdata
->displayrect
.MinY
;
225 tmprect
.MaxY
= n
->topedge
- 1;
226 ClearRectRegion(dispvisregion
, &tmprect
);
228 if (!(compdata
->capabilities
& COMPF_BELOW
) && !(n
->sbmflags
& COMPF_BELOW
))
230 tmprect
.MinX
= compdata
->displayrect
.MinX
;
231 tmprect
.MaxX
= compdata
->displayrect
.MaxX
;
232 tmprect
.MinY
= n
->topedge
+ OOP_GET(n
->bm
, aHidd_BitMap_Height
);
233 tmprect
.MaxY
= compdata
->displayrect
.MaxY
;
234 ClearRectRegion(dispvisregion
, &tmprect
);
236 if (!(compdata
->capabilities
& COMPF_LEFT
) && !(n
->sbmflags
& COMPF_LEFT
))
238 tmprect
.MinX
= compdata
->displayrect
.MinX
;
239 tmprect
.MaxX
= n
->leftedge
- 1;
240 tmprect
.MinY
= n
->topedge
;
241 tmprect
.MaxY
= n
->topedge
+ OOP_GET(n
->bm
, aHidd_BitMap_Height
) - 1;
242 ClearRectRegion(dispvisregion
, &tmprect
);
244 if (!(compdata
->capabilities
& COMPF_RIGHT
) && !(n
->sbmflags
& COMPF_RIGHT
))
246 tmprect
.MinX
= n
->leftedge
+ OOP_GET(n
->bm
, aHidd_BitMap_Width
);
247 tmprect
.MaxX
= compdata
->displayrect
.MaxX
;
248 tmprect
.MinY
= n
->topedge
;
249 tmprect
.MaxY
= n
->topedge
+ OOP_GET(n
->bm
, aHidd_BitMap_Height
) - 1;
250 ClearRectRegion(dispvisregion
, &tmprect
);
252 n
->sbmflags
|= STACKNODEF_VISIBLE
;
255 DRECALC(bug("[Compositor:%s] HiddBitmap 0x%p, topedge %d, visible %d\n", __PRETTY_FUNCTION__
,
256 n
->bm
, n
->topedge
, (n
->sbmflags
& STACKNODEF_VISIBLE
)));
260 DRECALC(bug("[Compositor:%s] Failed to create Screen Region\n", __PRETTY_FUNCTION__
));
263 DisposeRegion(dispvisregion
);
264 if (compdata
->flags
!= oldflags
)
266 ULONG newflags
= (~oldflags
) & compdata
->flags
;
267 DRECALC(bug("[Compositor:%s] Newly set flags %08x\n", __PRETTY_FUNCTION__
, newflags
));
268 if ((!(newflags
& COMPSTATEF_HASALPHA
)) && (oldflags
& COMPSTATEF_HASALPHA
))
270 DRECALC(bug("[Compositor:%s] Alpha removed\n", __PRETTY_FUNCTION__
));
271 if (compdata
->alpharegion
)
272 DisposeRegion(compdata
->alpharegion
);
274 compdata
->alpharegion
= NULL
;
280 DRECALC(bug("[Compositor:%s] Failed to create Display Region\n", __PRETTY_FUNCTION__
));
284 static inline void HIDDCompositorRedrawBitmap(struct HIDDCompositorData
*compdata
, OOP_Object
*renderTarget
, struct StackBitMapNode
*n
, struct Rectangle
*rect
)
286 /* The given rectangle is already in screen coordinate system here */
287 ULONG blitwidth
= rect
->MaxX
- rect
->MinX
+ 1;
288 ULONG blitheight
= rect
->MaxY
- rect
->MinY
+ 1;
290 DREDRAWBM(bug("[Compositor:%s] Redraw HiddBitMap 0x%p, Rect[%d, %d - %d, %d]\n", __PRETTY_FUNCTION__
, n
->bm
,
291 rect
->MinX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
));
293 if (!(n
->sbmflags
& COMPF_ALPHA
))
295 DREDRAWBM(bug("[Compositor:%s] Blitting %dx%d [from %d, %d]\n", __PRETTY_FUNCTION__
, blitwidth
, blitheight
,
296 rect
->MinX
- n
->leftedge
, rect
->MinY
- n
->topedge
));
298 HIDD_Gfx_CopyBox(compdata
->gfx
, n
->bm
,
299 /* Transform to source bitmap coord system */
300 rect
->MinX
- n
->leftedge
, rect
->MinY
- n
->topedge
,
302 rect
->MinX
, rect
->MinY
, blitwidth
, blitheight
,
308 ULONG width
, height
, banksize
, memsize
;
311 DREDRAWBM(bug("[Compositor:%s] AlphaBlending %dx%d @ %d,%d to %d,%d\n", __PRETTY_FUNCTION__
,
312 blitwidth
, blitheight
,
313 rect
->MinX
- n
->leftedge
, rect
->MinY
- n
->topedge
, rect
->MinX
, rect
->MinY
));
315 if (HIDD_BM_ObtainDirectAccess(n
->bm
, &baseaddress
, &width
, &height
, &banksize
, &memsize
))
317 DREDRAWBM(bug("[Compositor:%s] Alpha baseaddress @ 0x%p\n", __PRETTY_FUNCTION__
, baseaddress
));
318 OOP_GetAttr(n
->bm
, aHidd_BitMap_BytesPerRow
, &modulo
);
319 HIDD_BM_PutAlphaImage(renderTarget
, compdata
->gfx
, baseaddress
+ ((rect
->MinY
- n
->topedge
) * modulo
) + ((rect
->MinX
- n
->leftedge
) << 2), modulo
,
320 rect
->MinX
, rect
->MinY
, blitwidth
, blitheight
);
321 HIDD_BM_ReleaseDirectAccess(n
->bm
);
326 static inline void HIDDCompositorFillRect(struct HIDDCompositorData
*compdata
, OOP_Object
*renderTarget
, ULONG MinX
, ULONG MinY
, ULONG MaxX
, ULONG MaxY
)
328 DREDRAWSCR(bug("[Compositor:%s] Filling [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__
,
329 MinX
, MinY
, MaxX
, MaxY
));
331 HIDD_BM_FillRect(renderTarget
, compdata
->gc
,
332 MinX
, MinY
, MaxX
, MaxY
);
336 static VOID
HIDDCompositorRedrawAlphaRegions(struct HIDDCompositorData
*compdata
, struct Rectangle
*drawrect
)
338 OOP_Object
*renderTarget
= compdata
->displaybitmap
;
339 struct Rectangle alpharect
;
340 struct StackBitMapNode
*n
;
341 struct BitMap
*backbm
;
343 if (compdata
->intermedbitmap
)
344 renderTarget
= compdata
->intermedbitmap
;
346 DREDRAWSCR(if (drawrect
){ bug("[Compositor:%s] Rect [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__
, _RECT((*drawrect
))); })
348 OOP_GetAttr(renderTarget
, aHidd_BitMap_BMStruct
, (IPTR
*)&backbm
);
350 // Alpha Regions are drawn in reverse order incase they overlap..
351 for (n
= (struct StackBitMapNode
*)compdata
->bitmapstack
.mlh_TailPred
;
352 n
->n
.mln_Pred
; n
= (struct StackBitMapNode
*)n
->n
.mln_Pred
)
354 if ((n
->sbmflags
& STACKNODEF_VISIBLE
) &&
355 (n
->sbmflags
& COMPF_ALPHA
) &&
358 struct RegionRectangle
*srrect
;
360 DREDRAWSCR(bug("[Compositor:%s] Alpha Screen Region @ 0x%p HiddBitMap @ 0x%p\n", __PRETTY_FUNCTION__
,
361 n
->screenregion
, n
->bm
));
363 if ((srrect
= n
->screenregion
->RegionRectangle
) != NULL
)
365 DREDRAWSCR(bug("[Compositor:%s] Compositing Visible Alpha Regions..\n", __PRETTY_FUNCTION__
));
368 alpharect
.MinX
= srrect
->bounds
.MinX
+ n
->screenregion
->bounds
.MinX
;
369 alpharect
.MinY
= srrect
->bounds
.MinY
+ n
->screenregion
->bounds
.MinY
;
370 alpharect
.MaxX
= srrect
->bounds
.MaxX
+ n
->screenregion
->bounds
.MinX
;
371 alpharect
.MaxY
= srrect
->bounds
.MaxY
+ n
->screenregion
->bounds
.MinY
;
373 if (!(drawrect
) || AndRectRect(drawrect
, &alpharect
, &alpharect
))
375 DREDRAWSCR(bug("[Compositor:%s] Alpha-Region [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__
, _RECT(alpharect
)));
377 if ((n
->prealphacomphook
) && (backbm
!= NULL
))
379 struct HIDD_BackFillHookMsg preprocessmsg
;
380 preprocessmsg
.bounds
= &alpharect
;
381 preprocessmsg
.offsetx
= 0;
382 preprocessmsg
.offsety
= 0;
383 CallHookPkt(n
->prealphacomphook
, backbm
, &preprocessmsg
);
386 HIDDCompositorRedrawBitmap(compdata
, renderTarget
, n
, &alpharect
);
387 if (renderTarget
== compdata
->displaybitmap
)
388 HIDD_BM_UpdateRect(compdata
->displaybitmap
,
389 alpharect
.MinX
, alpharect
.MinY
,
390 alpharect
.MaxX
- alpharect
.MinX
+ 1,
391 alpharect
.MaxY
- alpharect
.MinY
+ 1);
393 srrect
= srrect
->Next
;
400 static VOID
HIDDCompositorRedrawVisibleRegions(struct HIDDCompositorData
*compdata
, struct Rectangle
*drawrect
)
402 OOP_Object
*renderTarget
= compdata
->displaybitmap
;
403 struct Region
*dispvisregion
= NULL
;
404 struct Rectangle tmprect
;
405 struct BitMap
*clearbm
;
406 struct StackBitMapNode
*n
;
408 DREDRAWSCR(bug("[Compositor:%s] Redrawing Display (GfxBase @ 0x%p)\n", __PRETTY_FUNCTION__
, GfxBase
));
412 /* Recalculate visible regions */
413 HIDDCompositorRecalculateVisibleRegions(compdata
);
416 if ((compdata
->flags
& COMPSTATEF_HASALPHA
) && (compdata
->intermedbitmap
))
417 renderTarget
= compdata
->intermedbitmap
;
419 if ((dispvisregion
= NewRegion()) != NULL
)
422 OrRectRegion(dispvisregion
, drawrect
);
424 OrRectRegion(dispvisregion
, &compdata
->displayrect
);
426 DRECALC(bug("[Compositor:%s] Display rect [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__
, _RECT(compdata
->displayrect
)));
428 ForeachNode(&compdata
->bitmapstack
, n
)
430 if ((n
->sbmflags
& STACKNODEF_VISIBLE
) &&
431 (!(n
->sbmflags
& COMPF_ALPHA
)) &&
434 struct RegionRectangle
* srrect
;
435 DREDRAWSCR(bug("[Compositor:%s] Screen Region @ 0x%p HiddBitMap @ 0x%p\n", __PRETTY_FUNCTION__
,
436 n
->screenregion
, n
->bm
));
438 // Render the visable regions ..
439 if ((srrect
= n
->screenregion
->RegionRectangle
) != NULL
)
441 DREDRAWSCR(bug("[Compositor:%s] Redrawing Visible Screen Regions..\n", __PRETTY_FUNCTION__
));
444 tmprect
.MinX
= srrect
->bounds
.MinX
+ n
->screenregion
->bounds
.MinX
;
445 tmprect
.MinY
= srrect
->bounds
.MinY
+ n
->screenregion
->bounds
.MinY
;
446 tmprect
.MaxX
= srrect
->bounds
.MaxX
+ n
->screenregion
->bounds
.MinX
;
447 tmprect
.MaxY
= srrect
->bounds
.MaxY
+ n
->screenregion
->bounds
.MinY
;
449 if (!(drawrect
) || AndRectRect(drawrect
, &tmprect
, &tmprect
))
451 DREDRAWSCR(bug("[Compositor:%s] Region [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__
, _RECT(tmprect
)));
453 HIDDCompositorRedrawBitmap(compdata
, renderTarget
, n
, &tmprect
);
454 if (renderTarget
== compdata
->displaybitmap
)
455 HIDD_BM_UpdateRect(compdata
->displaybitmap
,
456 tmprect
.MinX
, tmprect
.MinY
,
457 tmprect
.MaxX
- tmprect
.MinX
+ 1,
458 tmprect
.MaxY
- tmprect
.MinY
+ 1);
460 srrect
= srrect
->Next
;
462 ClearRegionRegion(n
->screenregion
, dispvisregion
);
466 OOP_GetAttr(renderTarget
, aHidd_BitMap_BMStruct
, (IPTR
*)&clearbm
);
468 struct RegionRectangle
* dispclrrect
= dispvisregion
->RegionRectangle
;
471 struct HIDD_BackFillHookMsg clearmsg
;
473 tmprect
.MinX
= dispclrrect
->bounds
.MinX
+ dispvisregion
->bounds
.MinX
;
474 tmprect
.MinY
= dispclrrect
->bounds
.MinY
+ dispvisregion
->bounds
.MinY
;
475 tmprect
.MaxX
= dispclrrect
->bounds
.MaxX
+ dispvisregion
->bounds
.MinX
;
476 tmprect
.MaxY
= dispclrrect
->bounds
.MaxY
+ dispvisregion
->bounds
.MinY
;
478 if (!(drawrect
) || AndRectRect(drawrect
, &tmprect
, &tmprect
))
480 DREDRAWSCR(bug("[Compositor:%s] Render Display Void Region [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__
, _RECT(tmprect
)));
484 clearmsg
.bounds
= &tmprect
;
485 clearmsg
.offsetx
= 0;
486 clearmsg
.offsety
= 0;
487 CallHookPkt(compdata
->backfillhook
, clearbm
, &clearmsg
);
490 HIDDCompositorFillRect(compdata
, renderTarget
, tmprect
.MinX
, tmprect
.MinY
, tmprect
.MaxX
, tmprect
.MaxY
);
492 if (renderTarget
== compdata
->displaybitmap
)
493 HIDD_BM_UpdateRect(compdata
->displaybitmap
,
494 tmprect
.MinX
, tmprect
.MinY
,
495 tmprect
.MaxX
- tmprect
.MinX
+ 1,
496 tmprect
.MaxY
- tmprect
.MinY
+ 1);
498 dispclrrect
= dispclrrect
->Next
;
500 if (compdata
->flags
& COMPSTATEF_HASALPHA
)
502 HIDDCompositorRedrawAlphaRegions(compdata
, drawrect
);
504 DisposeRegion(dispvisregion
);
506 if (renderTarget
!= compdata
->displaybitmap
)
508 DREDRAWSCR(bug("[Compositor:%s] Copying Alpha Intermediary BitMap\n", __PRETTY_FUNCTION__
, _RECT(tmprect
)));
511 HIDD_Gfx_CopyBox(compdata
->gfx
, renderTarget
,
512 compdata
->displayrect
.MinX
, compdata
->displayrect
.MinY
,
513 compdata
->displaybitmap
,
514 compdata
->displayrect
.MinX
, compdata
->displayrect
.MinY
,
515 compdata
->displayrect
.MaxX
- compdata
->displayrect
.MinX
+ 1,
516 compdata
->displayrect
.MaxY
- compdata
->displayrect
.MinY
+ 1,
518 HIDD_BM_UpdateRect(compdata
->displaybitmap
,
519 compdata
->displayrect
.MinX
, compdata
->displayrect
.MinY
,
520 compdata
->displayrect
.MaxX
- compdata
->displayrect
.MinX
+ 1,
521 compdata
->displayrect
.MaxY
- compdata
->displayrect
.MinY
+ 1);
525 HIDD_Gfx_CopyBox(compdata
->gfx
, renderTarget
,
526 drawrect
->MinX
, drawrect
->MinY
,
527 compdata
->displaybitmap
,
528 drawrect
->MinX
, drawrect
->MinY
,
529 drawrect
->MaxX
- drawrect
->MinX
+ 1,
530 drawrect
->MaxY
- drawrect
->MinY
+ 1,
532 HIDD_BM_UpdateRect(compdata
->displaybitmap
,
533 drawrect
->MinX
, drawrect
->MinY
,
534 drawrect
->MaxX
- drawrect
->MinX
+ 1,
535 drawrect
->MaxY
- drawrect
->MinY
+ 1);
542 There are several cases that needs to be handled in this code. They are documented
543 below. Please read it before making changes.
544 etb = existing topbitmap
547 cb = composited bitmap
548 fs = covers full screen
549 nfs = not covers full screen
555 The resulting mode is always that of screen bitmap as set in "effect" column.
556 The composited bitmap always matches the resulting screen mode or is NULL.
558 | exiting screen situation | change | effect |
559 | USE CASE: SWITCHING BETWEEN FULL SCREEN SCREENS - SAME MODE |
560 | etb->fs, mA, sb==etb, cb==NULL | ntb->fs, mA | sb==ntb, cb==NULL |
561 | etb->fs, mA, sb==etb, cb!=NULL | ntb->fs, mA | sb==ntb, cb!=NULL |
562 | USE CASE: SWITCHING BETWEEN FULL SCREEN AND NOT FULL SCREEN SCREENS - SAME MODE |
563 | etb->fs, mA, sb==etb, cb==NULL | ntb->nfs, mA | new(cb), sb==cb, cb!=NULL |
564 | etb->fs, mA, sb==etb, cb!=NULL | ntb->nfs, mA | sb==cb, cb!=NULL |
565 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND FULL SCREEN SCREENS - SAME MODE |
566 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
567 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->fs, mA | sb==ntb, cb!=NULL |
568 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND NOT FULL SCREEN SCREENS - SAME MODE |
569 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
570 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->nfs, mA | sb==cb, cb!=NULL |
573 | USE CASE: SWITCHING BETWEEN FULL SCREEN SCREENS - DIFFERENT MODES |
574 | etb->fs, mA, sb==etb, cb==NULL | ntb->fs, mB | sb==ntb, cb==NULL |
575 | etb->fs, mA, sb==etb, cb!=NULL | ntb->fs, mB | disp(cb), sb==ntb, cb==NULL |
576 | USE CASE: SWITCHING BETWEEN FULL SCREEN AND NOT FULL SCREEN SCREENS - DIFFERENT MODES |
577 | etb->fs, mA, sb==etb, cb==NULL | ntb->nfs, mB | new(cb), sb==cb, cb!=NULL |
578 | etb->fs, mA, sb==etb, cb!=NULL | ntb->nfs, mB | disp(cb), new(cb), sb==cb, cb!=NULL |
579 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND FULL SCREEN SCREENS - DIFFERENT MODES |
580 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
581 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->fs, mB | disp(cb), sb==ntb, cb==NULL |
582 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND NOT FULL SCREEN SCREENS - DIFFERENT MODES |
583 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
584 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->nfs, mB | disp(cb), new(cb), sb==cb, cb!=NULL |
587 | USE CASE: DRAGGING SCREEN DOWN |
588 | etb->fs, mA, sb==etb, cb==NULL | ntb->nfs, mA | new(cb), sb==cb |
589 | etb->fs, mA, sb==etb, cb!=NULL | ntb->nfs, mA | sb==cb |
590 | USE CASE: DRAGGING SCREEN UP |
591 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->fs, mA | sb==etb |
592 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
594 Resulting rules (order matters):
596 (a) if ((cb!=NULL) && (etb->mode!=ntb->mode)) {dispose(cb), cb=NULL}
597 (b) if ((ntb->nfs) && (cb==NULL)) new(cb)
598 (c) if (ntb->nfs) sb=cb
599 (d) if (ntb->fs) sb=ntb
602 (e) if (oldsb!=sb) modeswitch(sb)
604 02.09.2011: we don't remember sb any more because we don't handle it in any way. Instead
605 we either have or don't have displaybitmap. If we have it, composition
606 is on (sb = cb). If we don't have it, composition is off (sb = ntb).
608 static BOOL
HIDDCompositorToggleCompositing(struct HIDDCompositorData
*compdata
, BOOL newtop
)
611 * If the topbitmap covers the complete screen, show it instead of
612 * displaybitmap. Remember that screen bitmap -> composited bitmap
613 * mirroring has a negative impact on performance.
615 OOP_Object
*olddisplaybitmap
= compdata
->displaybitmap
;
616 OOP_Object
*oldintermedbitmap
= compdata
->intermedbitmap
;
617 struct StackBitMapNode
*topnode
= (struct StackBitMapNode
*)compdata
->bitmapstack
.mlh_Head
;
618 OOP_Object
*newsdispbitmap
= NULL
;
619 struct BitMap
*tmpBM
;
620 struct TagItem bmtags
[2];
622 BOOL ok
= TRUE
, composit
= FALSE
;
624 /* (a) If mode change is needed, enforce opening a new screen */
625 if (compdata
->modeschanged
)
627 DTOGGLE(bug("[Compositor:%s] Display Mode changed\n", __PRETTY_FUNCTION__
));
628 compdata
->displaybitmap
= NULL
;
631 bmtags
[0].ti_Tag
= BMATags_DisplayID
; bmtags
[0].ti_Data
= (compdata
->displayid
| compdata
->displaymode
);
632 bmtags
[1].ti_Tag
= TAG_DONE
; bmtags
[1].ti_Data
= TAG_DONE
;
634 if ((topnode
->topedge
> 0) || ((compdata
->displayrect
.MaxY
- compdata
->displayrect
.MinY
+ 1) > OOP_GET(topnode
->bm
, aHidd_BitMap_Height
)))
636 else if ((topnode
->leftedge
> 0) || ((compdata
->displayrect
.MaxX
- compdata
->displayrect
.MinX
+ 1) > OOP_GET(topnode
->bm
, aHidd_BitMap_Width
)))
638 else if (topnode
->sbmflags
& COMPF_ALPHA
)
644 if (compdata
->displaybitmap
== NULL
)
647 * displaybitmap == NULL means we were in passthrough mode before,
648 * or have just changed display mode - set up screen for composition.
650 DTOGGLE(bug("[Compositor:%s] Initialising Display-Compositor..\n", __PRETTY_FUNCTION__
));
655 * If our display driver uses a framebuffer, we can reuse it.
656 * Copy its original contents back into the bitmap which it replaced,
657 * then change framebuffer's video mode.
658 * Framebuffer is the only bitmap which can change its ModeID on the fly.
660 DTOGGLE(bug("[Compositor:%s] Using Display Famebuffer HiddBitMap @ 0x%p\n", __PRETTY_FUNCTION__
, compdata
->fb
));
662 /* Do this comparison in order not to show the framebuffer twice */
663 if (olddisplaybitmap
!= compdata
->fb
)
666 * 1. It's legal to show the framebuffer itself. This causes copying
667 * back old bitmap contents and detaching from it.
668 * 2. The result of this will always match compdata->fb.
669 * 3. Internally this is a simple blit operation, it can't fail.
671 DTOGGLE(bug("[Compositor:%s] Copying old Famebuffer BitMap\n", __PRETTY_FUNCTION__
));
672 compdata
->screenbitmap
= HIDD_Gfx_Show(compdata
->gfx
, compdata
->fb
, fHidd_Gfx_Show_CopyBack
);
675 /* Switch display mode on the framebuffer. */
676 OOP_SetAttrsTags(compdata
->fb
, aHidd_BitMap_ModeID
, compdata
->displaymode
, TAG_DONE
);
677 /* We are now compositing on the framebuffer */
678 compdata
->displaybitmap
= compdata
->fb
;
683 * There's no framebuffer.
684 * Create a new bitmap that will be used for compositing.
687 tmpBM
= AllocBitMap(compdata
->displayrect
.MaxX
- compdata
->displayrect
.MinX
+ 1,
688 compdata
->displayrect
.MaxY
- compdata
->displayrect
.MinY
+ 1,
689 compdata
->displaydepth
,
690 BMF_DISPLAYABLE
|BMF_CHECKVALUE
, (struct BitMap
*)bmtags
);
693 compdata
->displaybitmap
= HIDD_BM_OBJ(tmpBM
);
694 DTOGGLE(bug("[Compositor:%s] Created Compositor Display BitMap @ 0x%p [HiddBitMap @ 0x%p]\n", __PRETTY_FUNCTION__
, tmpBM
, compdata
->displaybitmap
));
696 /* Mode changed, this bitmap will be shown later */
697 newsdispbitmap
= compdata
->displaybitmap
;
699 /* NewBitMap can fail, handle this */
705 else /* if (compdata->displaybitmap == NULL) */
708 * We are already in compositing mode and will stay in it.
709 * Do not destroy our working bitmap.
711 olddisplaybitmap
= NULL
;
714 if ((compdata
->flags
& COMPSTATEF_HASALPHA
) && !(compdata
->intermedbitmap
))
716 tmpBM
= AllocBitMap(compdata
->displayrect
.MaxX
- compdata
->displayrect
.MinX
+ 1,
717 compdata
->displayrect
.MaxY
- compdata
->displayrect
.MinY
+ 1,
718 compdata
->displaydepth
,
719 BMF_CHECKVALUE
, (struct BitMap
*)bmtags
);
722 compdata
->intermedbitmap
= HIDD_BM_OBJ(tmpBM
);
723 DTOGGLE(bug("[Compositor:%s] Allocated Alpha Intermediary BitMap @ 0x%p [HiddBitMap @ 0x%p]\n", __PRETTY_FUNCTION__
, tmpBM
, compdata
->intermedbitmap
));
726 else if (!(compdata
->flags
& COMPSTATEF_HASALPHA
) && (compdata
->intermedbitmap
))
727 compdata
->intermedbitmap
= NULL
;
730 * (c) Here composition is turned on (displaybitmap != NULL).
731 * Redraw bitmap stack - compensate possible changes
734 HIDDCompositorRedrawVisibleRegions(compdata
, NULL
);
736 else if (olddisplaybitmap
|| newtop
)
739 * (d) Set passthrough mode and display the frontmost bitmap.
740 * This is also triggered by 'newtop' parameter, which tells us
741 * that frontmost bitmap has been changed, and we need to display a new one.
742 * Old displaybitmap has been remembered in the beginning. If it's not
743 * NULL, it will be destroyed in the end.
745 newsdispbitmap
= compdata
->topbitmap
;
746 compdata
->displaybitmap
= NULL
;
749 DTOGGLE(bug("[Compositor:%s] oldcompbm 0x%p, topbm 0x%p, dispbm 0x%p, newdispbm 0x%p\n", __PRETTY_FUNCTION__
,
750 olddisplaybitmap
, compdata
->topbitmap
, compdata
->displaybitmap
, newsdispbitmap
));
753 * (e) If the screenbitmap changed, show the new screenbitmap.
754 * We do it after refreshing, for better visual appearance.
760 compdata
->screenbitmap
= HIDD_Gfx_Show(compdata
->gfx
, newsdispbitmap
, fHidd_Gfx_Show_CopyBack
);
761 DTOGGLE(bug("[Compositor:%s] Displayed HiddBitMap 0x%p, Show returned 0x%p\n", __PRETTY_FUNCTION__
, newsdispbitmap
, compdata
->screenbitmap
));
763 /* After Show we need Update for mirroring drivers */
764 if (compdata
->screenbitmap
)
766 OOP_GetAttr(compdata
->screenbitmap
, aHidd_BitMap_Width
, &w
);
767 OOP_GetAttr(compdata
->screenbitmap
, aHidd_BitMap_Height
, &h
);
768 HIDD_BM_UpdateRect(compdata
->screenbitmap
, 0, 0, w
, h
);
773 * (a) - disposing of previous compositing buffers needs to happen after mode switch
774 * since it could have been the current screenbitmap
776 if (!(compdata
->flags
& COMPSTATEF_HASALPHA
) && (oldintermedbitmap
))
778 struct BitMap
*freebm
;
780 DTOGGLE(bug("[Compositor:%s] Disposing old alpha-intermediate bitmap 0x%p\n", __PRETTY_FUNCTION__
, oldintermedbitmap
));
782 OOP_GetAttr(oldintermedbitmap
, aHidd_BitMap_BMStruct
, (IPTR
*)&freebm
);
786 HIDD_Gfx_DisposeBitMap(compdata
->gfx
, oldintermedbitmap
);
788 compdata
->intermedbitmap
= NULL
;
791 if (olddisplaybitmap
&& (olddisplaybitmap
!= compdata
->fb
))
793 struct BitMap
*freebm
;
795 DTOGGLE(bug("[Compositor:%s] Disposing old display bitmap 0x%p\n", __PRETTY_FUNCTION__
, olddisplaybitmap
));
797 OOP_GetAttr(olddisplaybitmap
, aHidd_BitMap_BMStruct
, (IPTR
*)&freebm
);
801 HIDD_Gfx_DisposeBitMap(compdata
->gfx
, olddisplaybitmap
);
805 compdata
->modeschanged
= FALSE
;
810 static VOID
HIDDCompositorPurgeBitMapStack(struct HIDDCompositorData
* compdata
)
812 struct StackBitMapNode
* curr
, * next
;
814 ForeachNodeSafe(&compdata
->bitmapstack
, curr
, next
)
816 if (curr
->screenregion
)
817 DisposeRegion(curr
->screenregion
);
819 FreeMem(curr
, sizeof(struct StackBitMapNode
));
822 NEWLIST(&compdata
->bitmapstack
);
825 static void HIDDCompositorShowSingle(struct HIDDCompositorData
*compdata
, OOP_Object
*bm
)
827 /* Show the single top bitmap */
828 compdata
->topbitmap
= bm
;
829 compdata
->screenbitmap
= HIDD_Gfx_Show(compdata
->gfx
, bm
, fHidd_Gfx_Show_CopyBack
);
831 /* Dispose working bitmap (if any) */
832 if (compdata
->displaybitmap
)
834 /* Be careful with the framebuffer */
835 if (compdata
->displaybitmap
!= compdata
->fb
)
836 HIDD_Gfx_DisposeBitMap(compdata
->gfx
, compdata
->displaybitmap
);
838 /* This will deactivate us */
839 compdata
->displaybitmap
= NULL
;
843 /* Emergency error recovery function */
844 static void HIDDCompositorReset(struct HIDDCompositorData
*compdata
)
846 /* Purge bitmap stack */
847 HIDDCompositorPurgeBitMapStack(compdata
);
850 * Reset our internal state so that next BitMapStackChanged
851 * causes complete reinitialization.
853 compdata
->displaymode
= vHidd_ModeID_Invalid
;
854 compdata
->screenbitmap
= NULL
;
856 compdata
->flags
&= ~COMPSTATEF_HASALPHA
;
859 VOID
CompositorParseConfig(struct HIDDCompositorData
*compdata
)
861 struct RDArgs
*rdargs
;
862 IPTR CompArgs
[NOOFARGS
] = { 0 };
863 TEXT CompConfig
[1024];
865 /* use default amiga-like capabailities */
866 compdata
->capabilities
= COMPF_ABOVE
;
868 rdargs
= AllocDosObjectTags(DOS_RDARGS
, TAG_END
);
871 if (GetVar(COMPOSITOR_PREFS
, CompConfig
, 1024, GVF_GLOBAL_ONLY
) != -1)
873 rdargs
->RDA_Source
.CS_Buffer
= CompConfig
;
874 rdargs
->RDA_Source
.CS_Length
= strlen(rdargs
->RDA_Source
.CS_Buffer
);
875 rdargs
->RDA_DAList
= (IPTR
)NULL
;
876 rdargs
->RDA_Buffer
= NULL
;
877 rdargs
->RDA_BufSiz
= 0;
878 rdargs
->RDA_ExtHelp
= NULL
;
879 rdargs
->RDA_Flags
= 0;
881 if (ReadArgs(COMPOSITOR_PEFSTEMPLATE
, CompArgs
, rdargs
) != NULL
)
883 if (CompArgs
[ARG_ABOVE
])
884 compdata
->capabilities
|= COMPF_ABOVE
;
886 compdata
->capabilities
&= ~COMPF_ABOVE
;
888 if (CompArgs
[ARG_BELOW
])
889 compdata
->capabilities
|= COMPF_BELOW
;
891 compdata
->capabilities
&= ~COMPF_BELOW
;
893 if (CompArgs
[ARG_LEFT
])
894 compdata
->capabilities
|= COMPF_LEFT
;
896 compdata
->capabilities
&= ~COMPF_LEFT
;
898 if (CompArgs
[ARG_RIGHT
])
899 compdata
->capabilities
|= COMPF_RIGHT
;
901 compdata
->capabilities
&= ~COMPF_RIGHT
;
903 if (CompArgs
[ARG_ALPHA
])
904 compdata
->capabilities
|= COMPF_ALPHA
;
906 compdata
->capabilities
&= ~COMPF_ALPHA
;
911 FreeDosObject(DOS_RDARGS
, rdargs
);
915 AROS_UFH3(void, CompositorDefaultBackFillFunc
,
916 AROS_UFHA(struct Hook
* , h
, A0
),
917 AROS_UFHA(struct BitMap
* , bm
, A2
),
918 AROS_UFHA(struct HIDD_BackFillHookMsg
* , msg
, A1
))
922 struct HIDDCompositorData
*compdata
= h
->h_Data
;
924 D(bug("[%s] HIDDCompositorData @ 0x%p\n", __PRETTY_FUNCTION__
, compdata
));
926 HIDDCompositorFillRect(compdata
, HIDD_BM_OBJ(bm
), msg
->bounds
->MinX
, msg
->bounds
->MinY
, msg
->bounds
->MaxX
, msg
->bounds
->MaxY
);
932 OOP_Object
*METHOD(Compositor
, Root
, New
)
934 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
938 OOP_MethodID disposemid
;
939 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
941 D(bug("[%s] Compositor @ 0x%p, data @ 0x%p\n", __PRETTY_FUNCTION__
, o
, compdata
));
943 CompositorParseConfig(compdata
);
945 compdata
->capabilities
= (ULONG
)GetTagData(aHidd_Compositor_State
, compdata
->capabilities
, msg
->attrList
);
946 compdata
->flags
|= COMPSTATEF_DEEPLUT
;
948 D(bug("[%s] Compositor Capabilities: %08lx\n", __PRETTY_FUNCTION__
, compdata
->capabilities
));
950 compdata
->displaymode
= vHidd_ModeID_Invalid
;
952 NEWLIST(&compdata
->bitmapstack
);
954 compdata
->defaultbackfill
.h_Entry
= (HOOKFUNC
)AROS_ASMSYMNAME(CompositorDefaultBackFillFunc
);
955 compdata
->defaultbackfill
.h_Data
= compdata
;
956 compdata
->backfillhook
= &compdata
->defaultbackfill
;
958 InitSemaphore(&compdata
->semaphore
);
960 compdata
->displayid
= (ULONG
)GetTagData(aHidd_Compositor_DisplayID
, 0, msg
->attrList
);
961 compdata
->gfx
= (OOP_Object
*)GetTagData(aHidd_Compositor_GfxHidd
, 0, msg
->attrList
);
962 compdata
->fb
= (OOP_Object
*)GetTagData(aHidd_Compositor_FrameBuffer
, 0, msg
->attrList
);
964 D(bug("[%s] DisplayID %08lx for Gfx Driver @ 0x%p\n", __PRETTY_FUNCTION__
, compdata
->displayid
, compdata
->gfx
));
966 GfxBase
= (APTR
)OpenLibrary("graphics.library", 41);
967 IntuitionBase
= (APTR
)OpenLibrary("intuition.library", 50);
969 /* GfxHidd is mandatory */
970 if ((compdata
->GraphicsBase
) && (compdata
->gfx
!= NULL
))
972 /* Create GC object that will be used for drawing operations */
973 compdata
->gc
= HIDD_Gfx_NewGC(compdata
->gfx
, NULL
);
975 D(bug("[%s] Compositor GC @ %p\n", __PRETTY_FUNCTION__
, compdata
->gc
));
977 if ((compdata
->gfx
) && (compdata
->gc
))
981 /* Creation failed */
982 disposemid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
983 OOP_CoerceMethod(cl
, o
, &disposemid
);
989 void METHOD(Compositor
, Root
, Dispose
)
993 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
994 bug("[%s] HIDDCompositorData @ 0x%p\n", __PRETTY_FUNCTION__
, compdata
);
997 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
1000 VOID
METHOD(Compositor
, Root
, Get
)
1004 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1006 if (IS_COMPOSITOR_ATTR(msg
->attrID
, idx
))
1010 case aoHidd_Compositor_Capabilities
:
1012 *msg
->storage
= (IPTR
)CAPABILITY_FLAGS
;
1013 D(bug("[%s] Compositor Capabilities: %lx\n", __PRETTY_FUNCTION__
, *msg
->storage
));
1016 case aoHidd_Compositor_State
:
1018 *msg
->storage
= (IPTR
)(compdata
->capabilities
& CAPABILITY_FLAGS
);
1019 D(bug("[%s] Compositor State: %lx\n", __PRETTY_FUNCTION__
, compdata
->capabilities
));
1022 case aoHidd_Compositor_BackFillHook
:
1024 D(bug("[%s] BackFillHook: 0x%p\n", __PRETTY_FUNCTION__
, compdata
->backfillhook
));
1025 *msg
->storage
= (IPTR
)compdata
->backfillhook
;
1030 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
1033 VOID
METHOD(Compositor
, Root
, Set
)
1037 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1038 struct TagItem
*tag
, *tstate
= msg
->attrList
;
1040 while ((tag
= NextTagItem(&tstate
)))
1042 if (IS_COMPOSITOR_ATTR(tag
->ti_Tag
, idx
))
1046 case aoHidd_Compositor_State
:
1048 D(bug("[%s] Compositor Capabilities State: %lx -> ", __PRETTY_FUNCTION__
, compdata
->capabilities
));
1049 compdata
->capabilities
= (ULONG
)(tag
->ti_Data
& CAPABILITY_FLAGS
);
1050 D(bug("%lx\n", compdata
->capabilities
));
1053 case aoHidd_Compositor_BackFillHook
:
1057 D(bug("[%s] BackFillHook: 0x%p -> 0x%p\n", __PRETTY_FUNCTION__
, compdata
->backfillhook
, tag
->ti_Data
));
1058 compdata
->backfillhook
= (struct Hook
*)tag
->ti_Data
;
1062 D(bug("[%s] Default BackFillHook\n", __PRETTY_FUNCTION__
));
1063 compdata
->backfillhook
= &compdata
->defaultbackfill
;
1071 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
1074 OOP_Object
*METHOD(Compositor
, Hidd_Compositor
, BitMapStackChanged
)
1076 struct HIDD_ViewPortData
*vpdata
;
1077 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1078 struct StackBitMapNode
*n
;
1079 struct Screen
*bmScreen
;
1080 OOP_Object
*bmpxfmt
;
1082 BOOL newtop
= FALSE
;
1085 DSTACK(bug("[Compositor] %s: Top bitmap: 0x%lx\n", __PRETTY_FUNCTION__
, msg
->data
->Bitmap
));
1087 LOCK_COMPOSITOR_WRITE
1089 /* Free all items which are already on the list */
1090 HIDDCompositorPurgeBitMapStack(compdata
);
1096 DSTACK(bug("[Compositor] %s: No ViewPort specified\n", __PRETTY_FUNCTION__
));
1099 HIDDCompositorShowSingle(compdata
, NULL
);
1101 /* We know we are inactive after this */
1102 *msg
->active
= FALSE
;
1103 /* This can return NULL, it's okay */
1104 return compdata
->screenbitmap
;
1107 /* Copy bitmaps pointers to our stack */
1108 for (vpdata
= msg
->data
; vpdata
; vpdata
= vpdata
->Next
)
1110 n
= AllocMem(sizeof(struct StackBitMapNode
), MEMF_ANY
| MEMF_CLEAR
);
1115 * We need to reset own state and return NULL. graphics.library
1116 * falls back to no composition in this case.
1118 DSTACK(bug("[Compositor] %s: Error allocating StackBitMapNode!!!\n", __PRETTY_FUNCTION__
));
1124 DSTACK(bug("[Compositor] %s: ViewPort 0x%p, offset (%d, %d)\n", __PRETTY_FUNCTION__
, vpdata
->vpe
->ViewPort
, vpdata
->vpe
->ViewPort
->DxOffset
, vpdata
->vpe
->ViewPort
->DyOffset
));
1126 n
->bm
= vpdata
->Bitmap
;
1127 n
->sbmflags
= STACKNODEF_DISPLAYABLE
;
1128 n
->leftedge
= vpdata
->vpe
->ViewPort
->DxOffset
;
1129 n
->topedge
= vpdata
->vpe
->ViewPort
->DyOffset
;
1131 n
->screenregion
= NewRegion();
1133 if ((bmScreen
= HIDDCompositorFindBitMapScreen(compdata
, n
->bm
)) != NULL
)
1135 DSTACK(bug("[Compositor] %s: Screen @ 0x%p\n", __PRETTY_FUNCTION__
, bmScreen
));
1136 GetAttr(SA_CompositingFlags
, (Object
*)bmScreen
, &n
->sbmflags
);
1137 DSTACK(bug("[Compositor] %s: CompositingFlags %08x\n", __PRETTY_FUNCTION__
, n
->sbmflags
));
1138 n
->sbmflags
|= STACKNODEF_DISPLAYABLE
;
1139 if (n
->sbmflags
& COMPF_ALPHA
)
1141 GetAttr(SA_AlphaPreCompositingHook
, (Object
*)bmScreen
, (IPTR
*)&n
->prealphacomphook
);
1142 DSTACK(bug("[Compositor] %s: Pre-AlphaCompositing Hook @ 0x%p\n", __PRETTY_FUNCTION__
, n
->prealphacomphook
));
1146 if (n
->sbmflags
& COMPF_ALPHA
)
1148 bmpxfmt
= (OOP_Object
*)OOP_GET(n
->bm
, aHidd_BitMap_PixFmt
);
1149 bmstdfmt
= (int)OOP_GET(bmpxfmt
, aHidd_PixFmt_StdPixFmt
);
1150 DSTACK(bug("[Compositor] %s: Screen BitMap PixFmt %lx @ 0x%p\n", __PRETTY_FUNCTION__
, bmstdfmt
, bmpxfmt
));
1154 case vHidd_StdPixFmt_ARGB32
:
1155 case vHidd_StdPixFmt_BGRA32
:
1156 case vHidd_StdPixFmt_RGBA32
:
1157 case vHidd_StdPixFmt_ABGR32
:
1159 DSTACK(bug("[Compositor] %s: Screen BitMap has Alpha\n", __PRETTY_FUNCTION__
));
1161 compdata
->flags
|= COMPSTATEF_HASALPHA
;
1166 n
->sbmflags
&= ~COMPF_ALPHA
;
1172 if (!(n
->sbmflags
& COMPF_ALPHA
))
1174 if ((((BOOL
)OOP_GET(n
->bm
, aHidd_BitMap_Displayable
)) != TRUE
))
1175 n
->sbmflags
&= ~STACKNODEF_DISPLAYABLE
;
1177 AddTail((struct List
*)&compdata
->bitmapstack
, (struct Node
*)n
);
1180 /* Switch mode if needed */
1181 UpdateDisplayMode(compdata
);
1183 if (msg
->data
->Bitmap
!= compdata
->topbitmap
)
1185 /* Set the new pointer to top bitmap */
1186 compdata
->topbitmap
= msg
->data
->Bitmap
;
1193 * Validate bitmap offsets - they might not match the compositing rules taking
1194 * new displayedwidth/displayedheight values
1196 ForeachNode(&compdata
->bitmapstack
, n
)
1198 HIDDCompositorValidateBitMapPositionChange(n
->bm
, &n
->leftedge
, &n
->topedge
,
1199 compdata
->displayrect
.MaxX
- compdata
->displayrect
.MinX
+ 1,
1200 compdata
->displayrect
.MaxY
- compdata
->displayrect
.MinY
+ 1);
1201 DSTACK(bug("[Compositor] %s: Bitmap 0x%p, display size %d x %d, validated position (%ld, %ld)\n", __PRETTY_FUNCTION__
,
1202 n
->bm
, compdata
->displayrect
.MaxX
- compdata
->displayrect
.MinX
+ 1, compdata
->displayrect
.MaxY
- compdata
->displayrect
.MinY
+ 1,
1203 n
->leftedge
, n
->topedge
));
1206 /* Toogle compositing based on screen positions */
1207 ok
= HIDDCompositorToggleCompositing(compdata
, newtop
);
1213 HIDDCompositorReset(compdata
);
1214 HIDDCompositorShowSingle(compdata
, msg
->data
->Bitmap
);
1219 DSTACK(bug("[%s] Done, composited bitmap 0x%p\n", __PRETTY_FUNCTION__
, compdata
->displaybitmap
));
1221 /* Tell if the composition is active */
1222 *msg
->active
= compdata
->displaybitmap
? TRUE
: FALSE
;
1223 /* Return actually displayed bitmap */
1224 return compdata
->screenbitmap
;
1227 VOID
METHOD(Compositor
, Hidd_Compositor
, BitMapRectChanged
)
1229 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1230 OOP_Object
*renderTarget
= compdata
->displaybitmap
;
1232 if (compdata
->displaybitmap
)
1234 /* Composition is active, handle redraw if the bitmap is on screen */
1235 struct StackBitMapNode
*n
;
1237 DUPDATE(bug("[%s] Bitmap 0x%p\n", __PRETTY_FUNCTION__
, msg
->bm
));
1239 LOCK_COMPOSITOR_READ
1241 if (compdata
->intermedbitmap
)
1242 renderTarget
= compdata
->intermedbitmap
;
1244 n
= HIDDCompositorFindBitMapStackNode(compdata
, msg
->bm
);
1245 if (n
&& (n
->sbmflags
& STACKNODEF_VISIBLE
))
1247 struct Rectangle dstandvisrect
;
1248 struct Rectangle srcrect
;
1250 srcrect
.MinX
= n
->leftedge
+ msg
->x
;
1251 srcrect
.MinY
= n
->topedge
+ msg
->y
;
1252 srcrect
.MaxX
= srcrect
.MinX
+ msg
->width
- 1;
1253 srcrect
.MaxY
= srcrect
.MinY
+ msg
->height
- 1;
1254 DUPDATE(bug("[%s] Bitmap rect [%d, %d -> %d, %d]\n", __PRETTY_FUNCTION__
, msg
->x
, msg
->y
, msg
->x
+ msg
->width
- 1, msg
->y
+ msg
->height
- 1));
1256 DUPDATE(bug("[%s] Screen-relative rect [%d, %d -> %d, %d]\n", __PRETTY_FUNCTION__
, _RECT(srcrect
)));
1258 struct RegionRectangle
* srrect
= n
->screenregion
->RegionRectangle
;
1261 BOOL updateAlphaBmps
= FALSE
;
1263 dstandvisrect
.MinX
= srrect
->bounds
.MinX
+ n
->screenregion
->bounds
.MinX
;
1264 dstandvisrect
.MinY
= srrect
->bounds
.MinY
+ n
->screenregion
->bounds
.MinY
;
1265 dstandvisrect
.MaxX
= srrect
->bounds
.MaxX
+ n
->screenregion
->bounds
.MinX
;
1266 dstandvisrect
.MaxY
= srrect
->bounds
.MaxY
+ n
->screenregion
->bounds
.MinY
;
1268 if (AndRectRect(&srcrect
, &dstandvisrect
, &dstandvisrect
))
1270 /* Intersection is valid. Blit. */
1271 DUPDATE(bug("[%s] Clipped rect (%d, %d) - (%d, %d)\n", __PRETTY_FUNCTION__
, _RECT(dstandvisrect
)));
1273 if (!(n
->sbmflags
& COMPF_ALPHA
))
1275 if ((compdata
->alpharegion
) && (isRectInRegion(compdata
->alpharegion
, &dstandvisrect
)))
1277 DUPDATE(bug("[%s] ** BitMap in Alpha Region!\n", __PRETTY_FUNCTION__
));
1278 updateAlphaBmps
= TRUE
;
1280 HIDDCompositorRedrawBitmap(compdata
, renderTarget
, n
, &dstandvisrect
);
1284 HIDDCompositorRedrawVisibleRegions(compdata
, &dstandvisrect
);
1287 if (updateAlphaBmps
)
1288 HIDDCompositorRedrawAlphaRegions(compdata
, &dstandvisrect
);
1290 if (renderTarget
!= compdata
->displaybitmap
)
1292 HIDD_Gfx_CopyBox(compdata
->gfx
, renderTarget
,
1293 dstandvisrect
.MinX
, dstandvisrect
.MinY
,
1294 compdata
->displaybitmap
,
1295 dstandvisrect
.MinX
, dstandvisrect
.MinY
,
1296 dstandvisrect
.MaxX
- dstandvisrect
.MinX
+ 1,
1297 dstandvisrect
.MaxY
- dstandvisrect
.MinY
+ 1,
1301 srrect
= srrect
->Next
;
1303 HIDD_BM_UpdateRect(compdata
->displaybitmap
,
1304 srcrect
.MinX
, srcrect
.MinY
,
1305 srcrect
.MaxX
- srcrect
.MinX
+ 1,
1306 srcrect
.MaxY
- srcrect
.MinY
+ 1);
1311 DUPDATE(bug("[%s] Done\n", __PRETTY_FUNCTION__
));
1315 /* In order to speed things up, we handle passthrough ourselves here. */
1316 HIDD_BM_UpdateRect(msg
->bm
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);
1320 IPTR
METHOD(Compositor
, Hidd_Compositor
, BitMapPositionChange
)
1322 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1323 struct StackBitMapNode
*n
;
1324 IPTR disp_width
, disp_height
;
1326 LOCK_COMPOSITOR_READ
1328 n
= HIDDCompositorFindBitMapStackNode(compdata
, msg
->bm
);
1331 /* The bitmap is on display. Validate against screen size */
1332 disp_width
= compdata
->displayrect
.MaxX
+ 1;
1333 disp_height
= compdata
->displayrect
.MaxY
+ 1;
1337 /* The bitmap is not displayed yet. Validate against its own ModeID size. */
1338 HIDDT_ModeID modeid
= vHidd_ModeID_Invalid
;
1339 OOP_Object
*bmfriend
, *sync
, *pf
;
1341 OOP_GetAttr(msg
->bm
, aHidd_BitMap_ModeID
, &modeid
);
1343 if ((modeid
== vHidd_ModeID_Invalid
) && (OOP_GET(msg
->bm
, aHidd_BitMap_Compositable
)))
1345 OOP_GetAttr(msg
->bm
, aHidd_BitMap_Friend
, (IPTR
*)&bmfriend
);
1347 OOP_GetAttr(bmfriend
, aHidd_BitMap_ModeID
, &modeid
);
1350 if (modeid
== vHidd_ModeID_Invalid
)
1353 * Nondisplayable bitmaps don't scroll.
1354 * In fact they simply can't get in here because MakeVPort() performs the validation.
1355 * But who knows what bug can slip into someone's software...
1361 HIDD_Gfx_GetMode(compdata
->gfx
, modeid
, &sync
, &pf
);
1362 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &disp_width
);
1363 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &disp_height
);
1366 DMOVE(bug("[%s] Validating bitmap 0x%p, position (%ld, %ld), limits %ld x %ld\n", __PRETTY_FUNCTION__
,
1367 msg
->bm
, *msg
->newxoffset
, *msg
->newyoffset
, disp_width
, disp_height
));
1369 HIDDCompositorValidateBitMapPositionChange(msg
->bm
, msg
->newxoffset
, msg
->newyoffset
,
1370 disp_width
, disp_height
);
1372 DMOVE(bug("[%s] Validated position (%ld, %ld)\n", __PRETTY_FUNCTION__
, *msg
->newxoffset
, *msg
->newyoffset
));
1374 if (n
&& ((*msg
->newxoffset
!= n
->leftedge
) || (*msg
->newyoffset
!= n
->topedge
)))
1376 DMOVE(bug("[%s] Old position (%ld, %ld)\n", __PRETTY_FUNCTION__
, n
->leftedge
, n
->topedge
));
1378 /* Reflect the change if it happened */
1379 n
->leftedge
= *msg
->newxoffset
;
1380 n
->topedge
= *msg
->newyoffset
;
1382 if (compdata
->topbitmap
== msg
->bm
)
1385 * If this is the frontmost bitmap, we may want to toggle compositing,
1386 * if it starts/stops covering the whole screen at one point.
1387 * We don't need to call HIDDCompositorRedrawVisibleRegions() here because
1388 * HIDDCompositorToggleCompositing() does this itself, for improved
1389 * visual appearance.
1391 HIDDCompositorToggleCompositing(compdata
, FALSE
);
1394 HIDDCompositorRedrawVisibleRegions(compdata
, NULL
);
1399 /* Return active state */
1400 return compdata
->displaybitmap
? TRUE
: FALSE
;
1403 IPTR
METHOD(Compositor
, Hidd_Compositor
, BitMapValidate
)
1405 if (IS_HIDD_BM(msg
->bm
))
1411 IPTR
METHOD(Compositor
, Hidd_Compositor
, BitMapEnable
)
1413 if (IS_HIDD_BM(msg
->bm
))
1415 if (!(OOP_GET(HIDD_BM_OBJ(msg
->bm
), aHidd_BitMap_Displayable
)))
1417 struct TagItem composittags
[] = {
1418 {aHidd_BitMap_Compositable
, TRUE
},
1422 D(bug("[%s] Marking BitMap 0x%lx as Compositable\n", __PRETTY_FUNCTION__
, msg
->bm
));
1423 OOP_SetAttrs(HIDD_BM_OBJ(msg
->bm
), composittags
);
1431 #define NUM_Compositor_Root_METHODS 4
1433 static const struct OOP_MethodDescr Compositor_Root_descr
[] =
1435 {(OOP_MethodFunc
)Compositor__Root__New
, moRoot_New
},
1436 {(OOP_MethodFunc
)Compositor__Root__Dispose
, moRoot_Dispose
},
1437 {(OOP_MethodFunc
)Compositor__Root__Get
, moRoot_Get
},
1438 {(OOP_MethodFunc
)Compositor__Root__Set
, moRoot_Set
},
1442 #define NUM_Compositor_Hidd_Compositor_METHODS 5
1444 static const struct OOP_MethodDescr Compositor_Hidd_Compositor_descr
[] =
1446 {(OOP_MethodFunc
)Compositor__Hidd_Compositor__BitMapStackChanged
, moHidd_Compositor_BitMapStackChanged
},
1447 {(OOP_MethodFunc
)Compositor__Hidd_Compositor__BitMapRectChanged
, moHidd_Compositor_BitMapRectChanged
},
1448 {(OOP_MethodFunc
)Compositor__Hidd_Compositor__BitMapPositionChange
, moHidd_Compositor_BitMapPositionChange
},
1449 {(OOP_MethodFunc
)Compositor__Hidd_Compositor__BitMapValidate
, moHidd_Compositor_BitMapValidate
},
1450 {(OOP_MethodFunc
)Compositor__Hidd_Compositor__BitMapEnable
, moHidd_Compositor_BitMapEnable
},
1454 const struct OOP_InterfaceDescr Compositor_ifdescr
[] =
1456 {Compositor_Root_descr
, IID_Root
, NUM_Compositor_Root_METHODS
},
1457 {Compositor_Hidd_Compositor_descr
, IID_Hidd_Compositor
, NUM_Compositor_Hidd_Compositor_METHODS
},