2 Copyright © 2010-2013, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
8 #include <proto/utility.h>
9 #include "compositor_intern.h"
11 static HIDDT_ModeID
FindBestHiddMode(struct HIDDCompositorData
*compdata
, ULONG width
, ULONG height
, ULONG depth
, ULONG
*res_depth
)
13 HIDDT_ModeID mode
= vHidd_ModeID_Invalid
;
14 OOP_Object
*sync
, *pf
;
17 ULONG found_delta
= -1;
18 ULONG found_width
= 0;
19 ULONG found_height
= 0;
20 ULONG found_depth
= 0;
21 HIDDT_ModeID found_mode
= vHidd_ModeID_Invalid
;
23 D(bug("[%s] Finding best match for mode %ux%ux%u\n", __PRETTY_FUNCTION__
, width
, height
, depth
));
25 while ((mode
= HIDD_Gfx_NextModeID(compdata
->gfx
, mode
, &sync
, &pf
)) != vHidd_ModeID_Invalid
)
29 D(bug("[%s] Checking mode 0x%08X... ", __PRETTY_FUNCTION__
, mode
));
30 if (OOP_GET(pf
, aHidd_PixFmt_ColorModel
) != vHidd_ColorModel_TrueColor
)
32 D(bug("Skipped (not truecolor)\n"));
36 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &w
);
37 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &h
);
38 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &d
);
40 dw
= w
> width
? w
- width
: w
< width
? width
- w
: 1;
41 dh
= h
> height
? h
- height
: h
< height
? height
- h
: 1;
45 if (delta
< found_delta
)
47 /* If mode resolution is closer to the needed one, we've got a better match */
54 else if (delta
== found_delta
)
56 /* If resolution is the same as that of current candidate mode, we can look at depth. */
57 if (found_depth
> depth
)
60 * Candidate mode if deeper than requested. We can supersede it with another mode
61 * of smaller depth, but which still matches our request.
63 if ((d
< found_depth
) && (d
>= depth
))
66 else if (found_depth
< depth
)
69 * We want better depth than current candidate.
70 * In this case anything deeper will do.
80 * Mode with the same delta, but larger depth, may supersede
81 * previous mode, if we prefer deeper ones.
83 D(bug("Selected (%ldx%ldx%ld, delta = %u)", w
, h
, d
, delta
));
90 /* Store mode information */
91 compdata
->displayrect
.MinX
= 0;
92 compdata
->displayrect
.MinY
= 0;
93 compdata
->displayrect
.MaxX
= found_width
- 1;
94 compdata
->displayrect
.MaxY
= found_height
- 1;
95 *res_depth
= found_depth
;
100 /* Follows the resolution of biggest screen */
101 static void CalculateParametersAlpha(struct HIDDCompositorData
*compdata
, ULONG
*wantedwidth
,
102 ULONG
*wantedheight
, ULONG
*wanteddepth
)
104 struct StackBitMapNode
*n
;
105 OOP_Object
*sync
, *pf
;
106 IPTR curwidth
, curheight
, curdepth
, modeid
;
108 for (n
= (struct StackBitMapNode
*)compdata
->bitmapstack
.mlh_TailPred
;
109 n
->n
.mln_Pred
; n
= (struct StackBitMapNode
*)n
->n
.mln_Pred
)
111 if ((!(n
->sbmflags
& COMPF_ALPHA
)) && (n
->sbmflags
& STACKNODEF_DISPLAYABLE
))
113 OOP_GetAttr(n
->bm
, aHidd_BitMap_ModeID
, &modeid
);
114 HIDD_Gfx_GetMode(compdata
->gfx
, modeid
, &sync
, &pf
);
118 /* Get the needed size */
119 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &curwidth
);
120 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &curheight
);
124 OOP_GetAttr(n
->bm
, aHidd_BitMap_Width
, &curwidth
);
125 OOP_GetAttr(n
->bm
, aHidd_BitMap_Height
, &curheight
);
128 if (OOP_GET(pf
, aHidd_PixFmt_ColorModel
) == vHidd_ColorModel_TrueColor
)
130 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &curdepth
);
134 /* If we have a LUT bitmap on stack, we request atleast 16-bit screen.
135 if DEEPLUT is set be use 24bit instead (for better color matching) */
136 if (compdata
->flags
& COMPSTATEF_DEEPLUT
)
144 OOP_GetAttr(n
->bm
, aHidd_BitMap_Width
, &curwidth
);
145 OOP_GetAttr(n
->bm
, aHidd_BitMap_Height
, &curheight
);
147 if (n
->sbmflags
& COMPF_ALPHA
)
151 OOP_GetAttr(n
->bm
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
152 if (OOP_GET(pf
, aHidd_PixFmt_ColorModel
) == vHidd_ColorModel_TrueColor
)
154 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &curdepth
);
158 if (compdata
->flags
& COMPSTATEF_DEEPLUT
)
165 if ((ULONG
)curwidth
> *wantedwidth
)
166 *wantedwidth
= (ULONG
)curwidth
;
167 if ((ULONG
)curheight
> *wantedheight
)
168 *wantedheight
= (ULONG
)curheight
;
169 if ((ULONG
)curdepth
> *wanteddepth
)
170 *wanteddepth
= (ULONG
)curdepth
;
174 /* Follows the resolution of topmost screen */
175 static void CalculateParametersRegular(struct HIDDCompositorData
*compdata
, ULONG
*wantedwidth
,
176 ULONG
*wantedheight
, ULONG
*wanteddepth
)
178 struct StackBitMapNode
*n
;
179 OOP_Object
*sync
, *pf
;
180 IPTR width
, height
, depth
, modeid
;
183 * Examine all bitmaps in the stack to figure out the needed depth.
184 * We need a maximum depth of all depths in order to keep correct colors.
185 * But not less than 16 bits, because we can't compose on a LUT screen.
187 * If a LUT bitmap is present in the stack (depth < 9), we request truecolor
188 * screen for better color presentation.
190 * We examine bitmaps in reverse order, in this case 'sync' will hold
191 * information about the top bitmap when we exit the loop.
192 * Size of our composited mode needs to be as close as possible to that one.
195 for (n
= (struct StackBitMapNode
*)compdata
->bitmapstack
.mlh_TailPred
;
196 n
->n
.mln_Pred
; n
= (struct StackBitMapNode
*)n
->n
.mln_Pred
)
198 OOP_GetAttr(n
->bm
, aHidd_BitMap_ModeID
, &modeid
);
199 HIDD_Gfx_GetMode(compdata
->gfx
, modeid
, &sync
, &pf
);
201 if (OOP_GET(pf
, aHidd_PixFmt_ColorModel
) == vHidd_ColorModel_TrueColor
)
203 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
204 if ((ULONG
)depth
> *wanteddepth
)
205 *wanteddepth
= (ULONG
)depth
;
210 * If we have a LUT bitmap on stack, we request 24-bit screen
211 * for better color transfer.
217 /* Get the needed size */
218 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &width
);
219 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &height
);
221 *wantedwidth
= (ULONG
)width
;
222 *wantedheight
= (ULONG
)height
;
225 void UpdateDisplayMode(struct HIDDCompositorData
*compdata
)
227 ULONG wantedwidth
= 0, wantedheight
= 0, wanteddepth
= 16;
231 D(bug("[Compositor] %s()\n", __PRETTY_FUNCTION__
));
233 if (compdata
->flags
& COMPSTATEF_HASALPHA
)
234 CalculateParametersAlpha(compdata
, &wantedwidth
, &wantedheight
, &wanteddepth
);
236 CalculateParametersRegular(compdata
, &wantedwidth
, &wantedheight
, &wanteddepth
);
238 D(bug("[%s] Prefered mode %ldx%ldx%d\n", __PRETTY_FUNCTION__
, wantedwidth
, wantedheight
, wanteddepth
));
240 modeid
= FindBestHiddMode(compdata
, wantedwidth
, wantedheight
, wanteddepth
, &found_depth
);
241 D(bug("[%s] Composition Display ModeID 0x%08X [current 0x%08X]\n", __PRETTY_FUNCTION__
, modeid
, compdata
->displaymode
));
243 if (modeid
!= compdata
->displaymode
)
245 /* The mode is different. Need to prepare information needed for compositing */
246 struct TagItem gctags
[] =
248 { aHidd_GC_Foreground
, 0x99999999 },
252 /* Signal mode change */
253 compdata
->displaymode
= modeid
;
254 compdata
->displaydepth
= wanteddepth
;
255 compdata
->modeschanged
= TRUE
;
257 /* Get gray foregound */
258 if (found_depth
< 24)
259 gctags
[0].ti_Data
= 0x9492;
261 OOP_SetAttrs(compdata
->gc
, gctags
);