2 Copyright © 2010-2017, 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>
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 OOP_DisposeObject(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 OOP_DisposeObject(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 OOP_DisposeObject(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
;
863 IPTR CompArgs
[NOOFARGS
] = { 0 };
864 TEXT CompConfig
[1024];
868 D(bug("[Composit] %s(0x%p)\n", __PRETTY_FUNCTION__
, compdata
));
870 /* Disable DOS Requesters (GetVar() -> "Please insert volume ENV:"),
871 because this can hang boot process if WB screen is not open
872 yet. Opening of WB screen (when requester tries to open) would
873 hang because display database semaphore is locked in AddDisplayDriverA(). */
875 me
= (struct Process
*)FindTask(NULL
);
876 old_windowptr
= me
->pr_WindowPtr
;
877 me
->pr_WindowPtr
= (APTR
)-1;
879 /* use default amiga-like capabailities */
880 compdata
->capabilities
= COMPF_ABOVE
;
882 rdargs
= AllocDosObjectTags(DOS_RDARGS
, TAG_END
);
885 D(bug("[Composit] %s: RDArgs @ 0x%p\n", __PRETTY_FUNCTION__
, rdargs
));
887 if ((len
= GetVar(COMPOSITOR_PREFS
, CompConfig
, 1024, GVF_GLOBAL_ONLY
)) != -1)
889 rdargs
->RDA_Source
.CS_Buffer
= CompConfig
;
890 rdargs
->RDA_Source
.CS_Length
= len
;
891 rdargs
->RDA_DAList
= (IPTR
)NULL
;
892 rdargs
->RDA_Buffer
= NULL
;
893 rdargs
->RDA_BufSiz
= 0;
894 rdargs
->RDA_ExtHelp
= NULL
;
895 rdargs
->RDA_Flags
= 0;
897 if (ReadArgs(COMPOSITOR_PEFSTEMPLATE
, CompArgs
, rdargs
) != NULL
)
899 if (CompArgs
[ARG_ABOVE
])
900 compdata
->capabilities
|= COMPF_ABOVE
;
902 compdata
->capabilities
&= ~COMPF_ABOVE
;
904 if (CompArgs
[ARG_BELOW
])
905 compdata
->capabilities
|= COMPF_BELOW
;
907 compdata
->capabilities
&= ~COMPF_BELOW
;
909 if (CompArgs
[ARG_LEFT
])
910 compdata
->capabilities
|= COMPF_LEFT
;
912 compdata
->capabilities
&= ~COMPF_LEFT
;
914 if (CompArgs
[ARG_RIGHT
])
915 compdata
->capabilities
|= COMPF_RIGHT
;
917 compdata
->capabilities
&= ~COMPF_RIGHT
;
919 if (CompArgs
[ARG_ALPHA
])
920 compdata
->capabilities
|= COMPF_ALPHA
;
922 compdata
->capabilities
&= ~COMPF_ALPHA
;
927 FreeDosObject(DOS_RDARGS
, rdargs
);
930 me
->pr_WindowPtr
= old_windowptr
;
933 AROS_UFH3(void, CompositorDefaultBackFillFunc
,
934 AROS_UFHA(struct Hook
* , h
, A0
),
935 AROS_UFHA(struct BitMap
* , bm
, A2
),
936 AROS_UFHA(struct HIDD_BackFillHookMsg
* , msg
, A1
))
940 struct HIDDCompositorData
*compdata
= h
->h_Data
;
942 D(bug("[Composit] %s: HIDDCompositorData @ 0x%p\n", __PRETTY_FUNCTION__
, compdata
));
944 HIDDCompositorFillRect(compdata
, HIDD_BM_OBJ(bm
), msg
->bounds
->MinX
, msg
->bounds
->MinY
, msg
->bounds
->MaxX
, msg
->bounds
->MaxY
);
950 OOP_Object
*METHOD(Compositor
, Root
, New
)
952 D(bug("[Composit] %s()\n", __PRETTY_FUNCTION__
));
954 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
958 OOP_MethodID disposemid
;
959 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
961 D(bug("[Composit] %s: Compositor @ 0x%p, data @ 0x%p\n", __PRETTY_FUNCTION__
, o
, compdata
));
963 CompositorParseConfig(compdata
);
965 compdata
->capabilities
= (ULONG
)GetTagData(aHidd_Compositor_State
, compdata
->capabilities
, msg
->attrList
);
966 compdata
->flags
|= COMPSTATEF_DEEPLUT
;
968 D(bug("[Composit] %s: Compositor Capabilities: %08lx\n", __PRETTY_FUNCTION__
, compdata
->capabilities
));
970 compdata
->displaymode
= vHidd_ModeID_Invalid
;
972 NEWLIST(&compdata
->bitmapstack
);
974 compdata
->defaultbackfill
.h_Entry
= (HOOKFUNC
)AROS_ASMSYMNAME(CompositorDefaultBackFillFunc
);
975 compdata
->defaultbackfill
.h_Data
= compdata
;
976 compdata
->backfillhook
= &compdata
->defaultbackfill
;
978 InitSemaphore(&compdata
->semaphore
);
980 compdata
->displayid
= (ULONG
)GetTagData(aHidd_Compositor_DisplayID
, 0, msg
->attrList
);
981 compdata
->gfx
= (OOP_Object
*)GetTagData(aHidd_Compositor_GfxHidd
, 0, msg
->attrList
);
982 compdata
->fb
= (OOP_Object
*)GetTagData(aHidd_Compositor_FrameBuffer
, 0, msg
->attrList
);
984 D(bug("[Composit] %s: DisplayID %08lx for Gfx Driver @ 0x%p\n", __PRETTY_FUNCTION__
, compdata
->displayid
, compdata
->gfx
));
986 GfxBase
= (APTR
)OpenLibrary("graphics.library", 41);
987 IntuitionBase
= (APTR
)OpenLibrary("intuition.library", 50);
989 /* GfxHidd is mandatory */
990 if ((compdata
->GraphicsBase
) && (compdata
->gfx
!= NULL
))
992 /* Create GC object that will be used for drawing operations */
993 compdata
->gc
= HIDD_Gfx_CreateObject(compdata
->gfx
, OOP_FindClass(CLID_Hidd_GC
), NULL
);
995 D(bug("[Composit] %s: Compositor GC @ %p\n", __PRETTY_FUNCTION__
, compdata
->gc
));
997 if ((compdata
->gfx
) && (compdata
->gc
))
1001 /* Creation failed */
1002 disposemid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
1003 OOP_CoerceMethod(cl
, o
, &disposemid
);
1009 void METHOD(Compositor
, Root
, Dispose
)
1013 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1014 bug("[Composit] %s: HIDDCompositorData @ 0x%p\n", __PRETTY_FUNCTION__
, compdata
);
1017 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
1020 VOID
METHOD(Compositor
, Root
, Get
)
1024 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1026 if (IS_COMPOSITOR_ATTR(msg
->attrID
, idx
))
1030 case aoHidd_Compositor_Capabilities
:
1032 *msg
->storage
= (IPTR
)CAPABILITY_FLAGS
;
1033 D(bug("[Composit] %s: Compositor Capabilities: %lx\n", __PRETTY_FUNCTION__
, *msg
->storage
));
1036 case aoHidd_Compositor_State
:
1038 *msg
->storage
= (IPTR
)(compdata
->capabilities
& CAPABILITY_FLAGS
);
1039 D(bug("[Composit] %s: Compositor State: %lx\n", __PRETTY_FUNCTION__
, compdata
->capabilities
));
1042 case aoHidd_Compositor_BackFillHook
:
1044 D(bug("[Composit] %s: BackFillHook: 0x%p\n", __PRETTY_FUNCTION__
, compdata
->backfillhook
));
1045 *msg
->storage
= (IPTR
)compdata
->backfillhook
;
1050 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
1053 VOID
METHOD(Compositor
, Root
, Set
)
1057 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1058 struct TagItem
*tag
, *tstate
= msg
->attrList
;
1060 while ((tag
= NextTagItem(&tstate
)))
1062 if (IS_COMPOSITOR_ATTR(tag
->ti_Tag
, idx
))
1066 case aoHidd_Compositor_State
:
1068 D(bug("[Composit] %s: Compositor Capabilities State: %lx -> ", __PRETTY_FUNCTION__
, compdata
->capabilities
));
1069 compdata
->capabilities
= (ULONG
)(tag
->ti_Data
& CAPABILITY_FLAGS
);
1070 D(bug("%lx\n", compdata
->capabilities
));
1073 case aoHidd_Compositor_BackFillHook
:
1077 D(bug("[Composit] %s: BackFillHook: 0x%p -> 0x%p\n", __PRETTY_FUNCTION__
, compdata
->backfillhook
, tag
->ti_Data
));
1078 compdata
->backfillhook
= (struct Hook
*)tag
->ti_Data
;
1082 D(bug("[Composit] %s: Default BackFillHook\n", __PRETTY_FUNCTION__
));
1083 compdata
->backfillhook
= &compdata
->defaultbackfill
;
1091 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
1094 OOP_Object
*METHOD(Compositor
, Hidd_Compositor
, BitMapStackChanged
)
1096 struct HIDD_ViewPortData
*vpdata
;
1097 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1098 struct StackBitMapNode
*n
;
1099 struct Screen
*bmScreen
;
1100 OOP_Object
*bmpxfmt
;
1102 BOOL newtop
= FALSE
;
1105 DSTACK(bug("[Compositor] %s: Top bitmap: 0x%lx\n", __PRETTY_FUNCTION__
, msg
->data
->Bitmap
));
1107 LOCK_COMPOSITOR_WRITE
1109 /* Free all items which are already on the list */
1110 HIDDCompositorPurgeBitMapStack(compdata
);
1116 DSTACK(bug("[Compositor] %s: No ViewPort specified\n", __PRETTY_FUNCTION__
));
1119 HIDDCompositorShowSingle(compdata
, NULL
);
1121 /* We know we are inactive after this */
1122 *msg
->active
= FALSE
;
1123 /* This can return NULL, it's okay */
1124 return compdata
->screenbitmap
;
1127 /* Copy bitmaps pointers to our stack */
1128 for (vpdata
= msg
->data
; vpdata
; vpdata
= vpdata
->Next
)
1130 n
= AllocMem(sizeof(struct StackBitMapNode
), MEMF_ANY
| MEMF_CLEAR
);
1135 * We need to reset own state and return NULL. graphics.library
1136 * falls back to no composition in this case.
1138 DSTACK(bug("[Compositor] %s: Error allocating StackBitMapNode!!!\n", __PRETTY_FUNCTION__
));
1144 DSTACK(bug("[Compositor] %s: ViewPort 0x%p, offset (%d, %d)\n", __PRETTY_FUNCTION__
, vpdata
->vpe
->ViewPort
, vpdata
->vpe
->ViewPort
->DxOffset
, vpdata
->vpe
->ViewPort
->DyOffset
));
1146 n
->bm
= vpdata
->Bitmap
;
1147 n
->sbmflags
= STACKNODEF_DISPLAYABLE
;
1148 n
->leftedge
= vpdata
->vpe
->ViewPort
->DxOffset
;
1149 n
->topedge
= vpdata
->vpe
->ViewPort
->DyOffset
;
1151 n
->screenregion
= NewRegion();
1153 if ((bmScreen
= HIDDCompositorFindBitMapScreen(compdata
, n
->bm
)) != NULL
)
1155 DSTACK(bug("[Compositor] %s: Screen @ 0x%p\n", __PRETTY_FUNCTION__
, bmScreen
));
1156 GetAttr(SA_CompositingFlags
, (Object
*)bmScreen
, &n
->sbmflags
);
1157 DSTACK(bug("[Compositor] %s: CompositingFlags %08x\n", __PRETTY_FUNCTION__
, n
->sbmflags
));
1158 n
->sbmflags
|= STACKNODEF_DISPLAYABLE
;
1159 if (n
->sbmflags
& COMPF_ALPHA
)
1161 GetAttr(SA_AlphaPreCompositingHook
, (Object
*)bmScreen
, (IPTR
*)&n
->prealphacomphook
);
1162 DSTACK(bug("[Compositor] %s: Pre-AlphaCompositing Hook @ 0x%p\n", __PRETTY_FUNCTION__
, n
->prealphacomphook
));
1166 if (n
->sbmflags
& COMPF_ALPHA
)
1168 bmpxfmt
= (OOP_Object
*)OOP_GET(n
->bm
, aHidd_BitMap_PixFmt
);
1169 bmstdfmt
= (int)OOP_GET(bmpxfmt
, aHidd_PixFmt_StdPixFmt
);
1170 DSTACK(bug("[Compositor] %s: Screen BitMap PixFmt %lx @ 0x%p\n", __PRETTY_FUNCTION__
, bmstdfmt
, bmpxfmt
));
1174 case vHidd_StdPixFmt_ARGB32
:
1175 case vHidd_StdPixFmt_BGRA32
:
1176 case vHidd_StdPixFmt_RGBA32
:
1177 case vHidd_StdPixFmt_ABGR32
:
1179 DSTACK(bug("[Compositor] %s: Screen BitMap has Alpha\n", __PRETTY_FUNCTION__
));
1181 compdata
->flags
|= COMPSTATEF_HASALPHA
;
1186 n
->sbmflags
&= ~COMPF_ALPHA
;
1192 if (!(n
->sbmflags
& COMPF_ALPHA
))
1194 if ((((BOOL
)OOP_GET(n
->bm
, aHidd_BitMap_Displayable
)) != TRUE
))
1195 n
->sbmflags
&= ~STACKNODEF_DISPLAYABLE
;
1197 AddTail((struct List
*)&compdata
->bitmapstack
, (struct Node
*)n
);
1200 /* Switch mode if needed */
1201 UpdateDisplayMode(compdata
);
1203 if (msg
->data
->Bitmap
!= compdata
->topbitmap
)
1205 /* Set the new pointer to top bitmap */
1206 compdata
->topbitmap
= msg
->data
->Bitmap
;
1213 * Validate bitmap offsets - they might not match the compositing rules taking
1214 * new displayedwidth/displayedheight values
1216 ForeachNode(&compdata
->bitmapstack
, n
)
1218 HIDDCompositorValidateBitMapPositionChange(n
->bm
, &n
->leftedge
, &n
->topedge
,
1219 compdata
->displayrect
.MaxX
- compdata
->displayrect
.MinX
+ 1,
1220 compdata
->displayrect
.MaxY
- compdata
->displayrect
.MinY
+ 1);
1221 DSTACK(bug("[Compositor] %s: Bitmap 0x%p, display size %d x %d, validated position (%ld, %ld)\n", __PRETTY_FUNCTION__
,
1222 n
->bm
, compdata
->displayrect
.MaxX
- compdata
->displayrect
.MinX
+ 1, compdata
->displayrect
.MaxY
- compdata
->displayrect
.MinY
+ 1,
1223 n
->leftedge
, n
->topedge
));
1226 /* Toogle compositing based on screen positions */
1227 ok
= HIDDCompositorToggleCompositing(compdata
, newtop
);
1233 HIDDCompositorReset(compdata
);
1234 HIDDCompositorShowSingle(compdata
, msg
->data
->Bitmap
);
1239 DSTACK(bug("[Composit] %s: Done, composited bitmap 0x%p\n", __PRETTY_FUNCTION__
, compdata
->displaybitmap
));
1241 /* Tell if the composition is active */
1242 *msg
->active
= compdata
->displaybitmap
? TRUE
: FALSE
;
1243 /* Return actually displayed bitmap */
1244 return compdata
->screenbitmap
;
1247 VOID
METHOD(Compositor
, Hidd_Compositor
, BitMapRectChanged
)
1249 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1250 OOP_Object
*renderTarget
= compdata
->displaybitmap
;
1252 if (compdata
->displaybitmap
)
1254 /* Composition is active, handle redraw if the bitmap is on screen */
1255 struct StackBitMapNode
*n
;
1257 DUPDATE(bug("[Composit] %s: Bitmap 0x%p\n", __PRETTY_FUNCTION__
, msg
->bm
));
1259 LOCK_COMPOSITOR_READ
1261 if (compdata
->intermedbitmap
)
1262 renderTarget
= compdata
->intermedbitmap
;
1264 n
= HIDDCompositorFindBitMapStackNode(compdata
, msg
->bm
);
1265 if (n
&& (n
->sbmflags
& STACKNODEF_VISIBLE
))
1267 struct Rectangle dstandvisrect
;
1268 struct Rectangle srcrect
;
1270 srcrect
.MinX
= n
->leftedge
+ msg
->x
;
1271 srcrect
.MinY
= n
->topedge
+ msg
->y
;
1272 srcrect
.MaxX
= srcrect
.MinX
+ msg
->width
- 1;
1273 srcrect
.MaxY
= srcrect
.MinY
+ msg
->height
- 1;
1274 DUPDATE(bug("[Composit] %s: Bitmap rect [%d, %d -> %d, %d]\n", __PRETTY_FUNCTION__
, msg
->x
, msg
->y
, msg
->x
+ msg
->width
- 1, msg
->y
+ msg
->height
- 1));
1276 DUPDATE(bug("[Composit] %s: Screen-relative rect [%d, %d -> %d, %d]\n", __PRETTY_FUNCTION__
, _RECT(srcrect
)));
1278 struct RegionRectangle
* srrect
= n
->screenregion
->RegionRectangle
;
1281 BOOL updateAlphaBmps
= FALSE
;
1283 dstandvisrect
.MinX
= srrect
->bounds
.MinX
+ n
->screenregion
->bounds
.MinX
;
1284 dstandvisrect
.MinY
= srrect
->bounds
.MinY
+ n
->screenregion
->bounds
.MinY
;
1285 dstandvisrect
.MaxX
= srrect
->bounds
.MaxX
+ n
->screenregion
->bounds
.MinX
;
1286 dstandvisrect
.MaxY
= srrect
->bounds
.MaxY
+ n
->screenregion
->bounds
.MinY
;
1288 if (AndRectRect(&srcrect
, &dstandvisrect
, &dstandvisrect
))
1290 /* Intersection is valid. Blit. */
1291 DUPDATE(bug("[Composit] %s: Clipped rect (%d, %d) - (%d, %d)\n", __PRETTY_FUNCTION__
, _RECT(dstandvisrect
)));
1293 if (!(n
->sbmflags
& COMPF_ALPHA
))
1295 if ((compdata
->alpharegion
) && (isRectInRegion(compdata
->alpharegion
, &dstandvisrect
)))
1297 DUPDATE(bug("[Composit] %s: ** BitMap in Alpha Region!\n", __PRETTY_FUNCTION__
));
1298 updateAlphaBmps
= TRUE
;
1300 HIDDCompositorRedrawBitmap(compdata
, renderTarget
, n
, &dstandvisrect
);
1304 HIDDCompositorRedrawVisibleRegions(compdata
, &dstandvisrect
);
1307 if (updateAlphaBmps
)
1308 HIDDCompositorRedrawAlphaRegions(compdata
, &dstandvisrect
);
1310 if (renderTarget
!= compdata
->displaybitmap
)
1312 HIDD_Gfx_CopyBox(compdata
->gfx
, renderTarget
,
1313 dstandvisrect
.MinX
, dstandvisrect
.MinY
,
1314 compdata
->displaybitmap
,
1315 dstandvisrect
.MinX
, dstandvisrect
.MinY
,
1316 dstandvisrect
.MaxX
- dstandvisrect
.MinX
+ 1,
1317 dstandvisrect
.MaxY
- dstandvisrect
.MinY
+ 1,
1321 srrect
= srrect
->Next
;
1323 HIDD_BM_UpdateRect(compdata
->displaybitmap
,
1324 srcrect
.MinX
, srcrect
.MinY
,
1325 srcrect
.MaxX
- srcrect
.MinX
+ 1,
1326 srcrect
.MaxY
- srcrect
.MinY
+ 1);
1331 DUPDATE(bug("[Composit] %s: Done\n", __PRETTY_FUNCTION__
));
1335 /* In order to speed things up, we handle passthrough ourselves here. */
1336 HIDD_BM_UpdateRect(msg
->bm
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);
1340 IPTR
METHOD(Compositor
, Hidd_Compositor
, BitMapPositionChange
)
1342 struct HIDDCompositorData
*compdata
= OOP_INST_DATA(cl
, o
);
1343 struct StackBitMapNode
*n
;
1344 IPTR disp_width
, disp_height
;
1346 LOCK_COMPOSITOR_READ
1348 n
= HIDDCompositorFindBitMapStackNode(compdata
, msg
->bm
);
1351 /* The bitmap is on display. Validate against screen size */
1352 disp_width
= compdata
->displayrect
.MaxX
+ 1;
1353 disp_height
= compdata
->displayrect
.MaxY
+ 1;
1357 /* The bitmap is not displayed yet. Validate against its own ModeID size. */
1358 HIDDT_ModeID modeid
= vHidd_ModeID_Invalid
;
1359 OOP_Object
*bmfriend
, *sync
, *pf
;
1361 OOP_GetAttr(msg
->bm
, aHidd_BitMap_ModeID
, &modeid
);
1363 if ((modeid
== vHidd_ModeID_Invalid
) && (OOP_GET(msg
->bm
, aHidd_BitMap_Compositable
)))
1365 OOP_GetAttr(msg
->bm
, aHidd_BitMap_Friend
, (IPTR
*)&bmfriend
);
1367 OOP_GetAttr(bmfriend
, aHidd_BitMap_ModeID
, &modeid
);
1370 if (modeid
== vHidd_ModeID_Invalid
)
1373 * Nondisplayable bitmaps don't scroll.
1374 * In fact they simply can't get in here because MakeVPort() performs the validation.
1375 * But who knows what bug can slip into someone's software...
1381 HIDD_Gfx_GetMode(compdata
->gfx
, modeid
, &sync
, &pf
);
1382 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &disp_width
);
1383 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &disp_height
);
1386 DMOVE(bug("[Composit] %s: Validating bitmap 0x%p, position (%ld, %ld), limits %ld x %ld\n", __PRETTY_FUNCTION__
,
1387 msg
->bm
, *msg
->newxoffset
, *msg
->newyoffset
, disp_width
, disp_height
));
1389 HIDDCompositorValidateBitMapPositionChange(msg
->bm
, msg
->newxoffset
, msg
->newyoffset
,
1390 disp_width
, disp_height
);
1392 DMOVE(bug("[Composit] %s: Validated position (%ld, %ld)\n", __PRETTY_FUNCTION__
, *msg
->newxoffset
, *msg
->newyoffset
));
1394 if (n
&& ((*msg
->newxoffset
!= n
->leftedge
) || (*msg
->newyoffset
!= n
->topedge
)))
1396 DMOVE(bug("[Composit] %s: Old position (%ld, %ld)\n", __PRETTY_FUNCTION__
, n
->leftedge
, n
->topedge
));
1398 /* Reflect the change if it happened */
1399 n
->leftedge
= *msg
->newxoffset
;
1400 n
->topedge
= *msg
->newyoffset
;
1402 if (compdata
->topbitmap
== msg
->bm
)
1405 * If this is the frontmost bitmap, we may want to toggle compositing,
1406 * if it starts/stops covering the whole screen at one point.
1407 * We don't need to call HIDDCompositorRedrawVisibleRegions() here because
1408 * HIDDCompositorToggleCompositing() does this itself, for improved
1409 * visual appearance.
1411 HIDDCompositorToggleCompositing(compdata
, FALSE
);
1414 HIDDCompositorRedrawVisibleRegions(compdata
, NULL
);
1419 /* Return active state */
1420 return compdata
->displaybitmap
? TRUE
: FALSE
;
1423 IPTR
METHOD(Compositor
, Hidd_Compositor
, BitMapValidate
)
1425 if (IS_HIDD_BM(msg
->bm
))
1431 IPTR
METHOD(Compositor
, Hidd_Compositor
, BitMapEnable
)
1433 if (IS_HIDD_BM(msg
->bm
))
1435 if (!(OOP_GET(HIDD_BM_OBJ(msg
->bm
), aHidd_BitMap_Displayable
)))
1437 struct TagItem composittags
[] = {
1438 {aHidd_BitMap_Compositable
, TRUE
},
1442 D(bug("[Composit] %s: Marking BitMap 0x%lx as Compositable\n", __PRETTY_FUNCTION__
, msg
->bm
));
1443 OOP_SetAttrs(HIDD_BM_OBJ(msg
->bm
), composittags
);
1451 #define NUM_Compositor_Root_METHODS 4
1453 static const struct OOP_MethodDescr Compositor_Root_descr
[] =
1455 {(OOP_MethodFunc
)Compositor__Root__New
, moRoot_New
},
1456 {(OOP_MethodFunc
)Compositor__Root__Dispose
, moRoot_Dispose
},
1457 {(OOP_MethodFunc
)Compositor__Root__Get
, moRoot_Get
},
1458 {(OOP_MethodFunc
)Compositor__Root__Set
, moRoot_Set
},
1462 #define NUM_Compositor_Hidd_Compositor_METHODS 5
1464 static const struct OOP_MethodDescr Compositor_Hidd_Compositor_descr
[] =
1466 {(OOP_MethodFunc
)Compositor__Hidd_Compositor__BitMapStackChanged
, moHidd_Compositor_BitMapStackChanged
},
1467 {(OOP_MethodFunc
)Compositor__Hidd_Compositor__BitMapRectChanged
, moHidd_Compositor_BitMapRectChanged
},
1468 {(OOP_MethodFunc
)Compositor__Hidd_Compositor__BitMapPositionChange
, moHidd_Compositor_BitMapPositionChange
},
1469 {(OOP_MethodFunc
)Compositor__Hidd_Compositor__BitMapValidate
, moHidd_Compositor_BitMapValidate
},
1470 {(OOP_MethodFunc
)Compositor__Hidd_Compositor__BitMapEnable
, moHidd_Compositor_BitMapEnable
},
1474 const struct OOP_InterfaceDescr Compositor_ifdescr
[] =
1476 {Compositor_Root_descr
, IID_Root
, NUM_Compositor_Root_METHODS
},
1477 {Compositor_Hidd_Compositor_descr
, IID_Hidd_Compositor
, NUM_Compositor_Hidd_Compositor_METHODS
},