1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2010 LunarG, Inc.
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE.
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <assert.h>
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdlib.h>
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <string.h>
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "egldisplay.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "eglmode.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "eglcurrent.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "eglscreen.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_MESA_screen_surface
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MIN2(A, B)  (((A) < (B)) ? (A) : (B))
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Given an EGLModeMESA handle, return the corresponding _EGLMode object
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or null if non-existant.
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_EGLMode *
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp)
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint scrnum;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!disp || !disp->Screens)
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* loop over all screens on the display */
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (scrnum = 0; scrnum < disp->Screens->Size; scrnum++) {
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const _EGLScreen *scrn = disp->Screens->Elements[scrnum];
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      EGLint idx;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the mode ids of a screen ranges from scrn->Handle to scrn->Handle +
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * scrn->NumModes
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mode >= scrn->Handle &&
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          mode < scrn->Handle + _EGL_SCREEN_MAX_MODES) {
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         idx = mode - scrn->Handle;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(idx < scrn->NumModes && scrn->Modes[idx].Handle == mode);
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return &scrn->Modes[idx];
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Parse the attrib_list to fill in the fields of the given _eglMode
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return EGL_FALSE if any errors, EGL_TRUE otherwise.
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglParseModeAttribs(_EGLMode *mode, const EGLint *attrib_list)
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint i;
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* init all attribs to EGL_DONT_CARE */
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mode->Handle = EGL_DONT_CARE;
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mode->Width = EGL_DONT_CARE;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mode->Height = EGL_DONT_CARE;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mode->RefreshRate = EGL_DONT_CARE;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mode->Optimal = EGL_DONT_CARE;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mode->Interlaced = EGL_DONT_CARE;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mode->Name = NULL;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (attrib_list[i]) {
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_MODE_ID_MESA:
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mode->Handle = attrib_list[++i];
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (mode->Handle <= 0) {
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(handle)");
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return EGL_FALSE;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_WIDTH:
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mode->Width = attrib_list[++i];
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (mode->Width <= 0) {
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(width)");
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return EGL_FALSE;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_HEIGHT:
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mode->Height = attrib_list[++i];
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (mode->Height <= 0) {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(height)");
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return EGL_FALSE;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_REFRESH_RATE_MESA:
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mode->RefreshRate = attrib_list[++i];
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (mode->RefreshRate <= 0) {
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(refresh rate)");
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return EGL_FALSE;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_INTERLACED_MESA:
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mode->Interlaced = attrib_list[++i];
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (mode->Interlaced != EGL_TRUE && mode->Interlaced != EGL_FALSE) {
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(interlaced)");
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return EGL_FALSE;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_OPTIMAL_MESA:
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mode->Optimal = attrib_list[++i];
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (mode->Optimal != EGL_TRUE && mode->Optimal != EGL_FALSE) {
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            _eglError(EGL_BAD_PARAMETER, "eglChooseModeMESA(optimal)");
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return EGL_FALSE;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _eglError(EGL_BAD_ATTRIBUTE, "eglChooseModeMESA");
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return EGL_FALSE;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Determine if the candidate mode's attributes are at least as good
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as the minimal mode's.
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return EGL_TRUE if qualifies, EGL_FALSE otherwise
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglModeQualifies(const _EGLMode *c, const _EGLMode *min)
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (min->Handle != EGL_DONT_CARE && c->Handle != min->Handle)
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (min->Width != EGL_DONT_CARE && c->Width < min->Width)
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (min->Height != EGL_DONT_CARE && c->Height < min->Height)
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (min->RefreshRate != EGL_DONT_CARE && c->RefreshRate < min->RefreshRate)
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (min->Optimal != EGL_DONT_CARE && c->Optimal != min->Optimal)
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (min->Interlaced != EGL_DONT_CARE && c->Interlaced != min->Interlaced)
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return value of given mode attribute, or -1 if bad attrib.
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLint
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggetModeAttrib(const _EGLMode *m, EGLint attrib)
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (attrib) {
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_MODE_ID_MESA:
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return m->Handle;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_WIDTH:
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return m->Width;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_HEIGHT:
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return m->Height;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_REFRESH_RATE_MESA:
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return m->RefreshRate;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_OPTIMAL_MESA:
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return m->Optimal;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_INTERLACED_MESA:
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return m->Interlaced;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return -1;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SMALLER 1
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LARGER  2
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sort_info {
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint Attrib;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint Order; /* SMALLER or LARGER */
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* the order of these entries is the priority */
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct sort_info SortInfo[] = {
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { EGL_OPTIMAL_MESA, LARGER },
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { EGL_INTERLACED_MESA, SMALLER },
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { EGL_WIDTH, LARGER },
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { EGL_HEIGHT, LARGER },
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { EGL_REFRESH_RATE_MESA, LARGER },
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { EGL_MODE_ID_MESA, SMALLER },
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { 0, 0 }
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compare modes 'a' and 'b' and return -1 if a belongs before b, or 1 if a
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * belongs after b, or 0 if they're equal.
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used by qsort().
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglCompareModes(const void *a, const void *b)
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const _EGLMode *aMode = *((const _EGLMode **) a);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const _EGLMode *bMode = *((const _EGLMode **) b);
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint i;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; SortInfo[i].Attrib; i++) {
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const EGLint aVal = getModeAttrib(aMode, SortInfo[i].Attrib);
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const EGLint bVal = getModeAttrib(bMode, SortInfo[i].Attrib);
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (aVal == bVal) {
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* a tie */
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (SortInfo[i].Order == SMALLER) {
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return (aVal < bVal) ? -1 : 1;
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (SortInfo[i].Order == LARGER) {
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return (aVal > bVal) ? -1 : 1;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* all attributes identical */
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return 0;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Search for EGLModes which match the given attribute list.
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via eglChooseModeMESA API function.
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgEGLBoolean
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const EGLint *attrib_list, EGLModeMESA *modes,
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   EGLint modes_size, EGLint *num_modes)
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLMode **modeList, min;
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint i, count;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_eglParseModeAttribs(&min, attrib_list)) {
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* error code will have been recorded */
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* allocate array of mode pointers */
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   modeList = (_EGLMode **) malloc(modes_size * sizeof(_EGLMode *));
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!modeList) {
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglError(EGL_BAD_MODE_MESA, "eglChooseModeMESA(out of memory)");
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* make array of pointers to qualifying modes */
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = count = 0; i < scrn->NumModes && count < modes_size; i++) {
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (_eglModeQualifies(scrn->Modes + i, &min)) {
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         modeList[count++] = scrn->Modes + i;
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* sort array of pointers */
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   qsort(modeList, count, sizeof(_EGLMode *), _eglCompareModes);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* copy mode handles to output array */
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      modes[i] = modeList[i]->Handle;
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(modeList);
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *num_modes = count;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return all possible modes for the given screen.  No sorting of results.
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via eglGetModesMESA() API function.
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgEGLBoolean
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes)
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (modes) {
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      EGLint i;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *num_modes = MIN2(scrn->NumModes, modes_size);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < *num_modes; i++) {
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         modes[i] = scrn->Modes[i].Handle;
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* just return total number of supported modes */
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *num_modes = scrn->NumModes;
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Query an attribute of a mode.
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgEGLBoolean
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy,
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      _EGLMode *m, EGLint attribute, EGLint *value)
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint v;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v = getModeAttrib(m, attribute);
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (v < 0) {
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglError(EGL_BAD_ATTRIBUTE, "eglGetModeAttribMESA");
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *value = v;
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return human-readable string for given mode.
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is the default function called by eglQueryModeStringMESA().
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst char *
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m)
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return m->Name;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* EGL_MESA_screen_surface */
358