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