revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / monitors / Compositor / displaymode.c
blob00f6d5c4a5e91f5cb2e43fc6945e34dfb611a1fe
1 /*
2 Copyright © 2010-2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
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;
15 IPTR w, h, d;
16 ULONG dw, dh, delta;
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)
27 BOOL match;
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"));
33 continue;
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;
42 delta = dw * dh;
44 match = FALSE;
45 if (delta < found_delta)
47 /* If mode resolution is closer to the needed one, we've got a better match */
48 found_delta = delta;
49 found_width = w;
50 found_height = h;
52 match = TRUE;
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))
64 match = TRUE;
66 else if (found_depth < depth)
69 * We want better depth than current candidate.
70 * In this case anything deeper will do.
72 if (d > found_depth)
73 match = TRUE;
77 if (match)
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));
84 found_depth = d;
85 found_mode = mode;
87 D(bug("\n"));
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;
97 return found_mode;
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);
116 if (sync)
118 /* Get the needed size */
119 OOP_GetAttr(sync, aHidd_Sync_HDisp, &curwidth);
120 OOP_GetAttr(sync, aHidd_Sync_VDisp, &curheight);
122 else
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);
132 else
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)
137 curdepth = 24;
138 else
139 curdepth = 16;
142 else
144 OOP_GetAttr(n->bm, aHidd_BitMap_Width, &curwidth);
145 OOP_GetAttr(n->bm, aHidd_BitMap_Height, &curheight);
147 if (n->sbmflags & COMPF_ALPHA)
148 curdepth = 24;
149 else
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);
156 else
158 if (compdata->flags & COMPSTATEF_DEEPLUT)
159 curdepth = 24;
160 else
161 curdepth = 16;
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;
207 else
210 * If we have a LUT bitmap on stack, we request 24-bit screen
211 * for better color transfer.
213 *wanteddepth = 24;
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;
228 ULONG found_depth;
229 IPTR modeid;
231 D(bug("[Compositor] %s()\n", __PRETTY_FUNCTION__));
233 if (compdata->flags & COMPSTATEF_HASALPHA)
234 CalculateParametersAlpha(compdata, &wantedwidth, &wantedheight, &wanteddepth);
235 else
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 },
249 { TAG_DONE , 0 }
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);