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