Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
  5.  * Copyright 2010 LunarG, Inc.
  6.  * All Rights Reserved.
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the
  10.  * "Software"), to deal in the Software without restriction, including
  11.  * without limitation the rights to use, copy, modify, merge, publish,
  12.  * distribute, sub license, and/or sell copies of the Software, and to
  13.  * permit persons to whom the Software is furnished to do so, subject to
  14.  * the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice (including the
  17.  * next paragraph) shall be included in all copies or substantial portions
  18.  * of the Software.
  19.  *
  20.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  23.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  25.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  26.  * DEALINGS IN THE SOFTWARE.
  27.  *
  28.  **************************************************************************/
  29.  
  30.  
  31. /*
  32.  * Ideas for screen management extension to EGL.
  33.  *
  34.  * Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc).
  35.  * The screens' handles can be obtained with eglGetScreensMESA().
  36.  *
  37.  * A new kind of EGLSurface is possible- one which can be directly scanned
  38.  * out on a screen.  Such a surface is created with eglCreateScreenSurface().
  39.  *
  40.  * To actually display a screen surface on a screen, the eglShowSurface()
  41.  * function is called.
  42.  */
  43.  
  44. #include <assert.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47.  
  48. #include "egldisplay.h"
  49. #include "eglcurrent.h"
  50. #include "eglmode.h"
  51. #include "eglsurface.h"
  52. #include "eglscreen.h"
  53. #include "eglmutex.h"
  54.  
  55.  
  56. #ifdef EGL_MESA_screen_surface
  57.  
  58.  
  59. /* ugh, no atomic op? */
  60. static _EGL_DECLARE_MUTEX(_eglNextScreenHandleMutex);
  61. static EGLScreenMESA _eglNextScreenHandle = 1;
  62.  
  63.  
  64. /**
  65.  * Return a new screen handle/ID.
  66.  * NOTE: we never reuse these!
  67.  */
  68. static EGLScreenMESA
  69. _eglAllocScreenHandle(void)
  70. {
  71.    EGLScreenMESA s;
  72.  
  73.    _eglLockMutex(&_eglNextScreenHandleMutex);
  74.    s = _eglNextScreenHandle;
  75.    _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES;
  76.    _eglUnlockMutex(&_eglNextScreenHandleMutex);
  77.  
  78.    return s;
  79. }
  80.  
  81.  
  82. /**
  83.  * Initialize an _EGLScreen object to default values.
  84.  */
  85. void
  86. _eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes)
  87. {
  88.    memset(screen, 0, sizeof(_EGLScreen));
  89.  
  90.    screen->Display = dpy;
  91.    screen->NumModes = num_modes;
  92.    screen->StepX = 1;
  93.    screen->StepY = 1;
  94.  
  95.    if (num_modes > _EGL_SCREEN_MAX_MODES)
  96.       num_modes = _EGL_SCREEN_MAX_MODES;
  97.    screen->Modes = calloc(num_modes, sizeof(*screen->Modes));
  98.    screen->NumModes = (screen->Modes) ? num_modes : 0;
  99. }
  100.  
  101.  
  102. /**
  103.  * Link a screen to its display and return the handle of the link.
  104.  * The handle can be passed to client directly.
  105.  */
  106. EGLScreenMESA
  107. _eglLinkScreen(_EGLScreen *screen)
  108. {
  109.    _EGLDisplay *display;
  110.    EGLint i;
  111.  
  112.    assert(screen && screen->Display);
  113.    display = screen->Display;
  114.  
  115.    if (!display->Screens) {
  116.       display->Screens = _eglCreateArray("Screen", 4);
  117.       if (!display->Screens)
  118.          return (EGLScreenMESA) 0;
  119.    }
  120.  
  121.    screen->Handle = _eglAllocScreenHandle();
  122.    for (i = 0; i < screen->NumModes; i++)
  123.       screen->Modes[i].Handle = screen->Handle + i;
  124.  
  125.    _eglAppendArray(display->Screens, (void *) screen);
  126.  
  127.    return screen->Handle;
  128. }
  129.  
  130.  
  131. /**
  132.  * Lookup a handle to find the linked config.
  133.  * Return NULL if the handle has no corresponding linked config.
  134.  */
  135. _EGLScreen *
  136. _eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
  137. {
  138.    EGLint i;
  139.  
  140.    if (!display || !display->Screens)
  141.       return NULL;
  142.  
  143.    for (i = 0; i < display->Screens->Size; i++) {
  144.       _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i];
  145.       if (scr->Handle == screen) {
  146.          assert(scr->Display == display);
  147.          return scr;
  148.       }
  149.    }
  150.    return NULL;
  151. }
  152.  
  153.  
  154. static EGLBoolean
  155. _eglFlattenScreen(void *elem, void *buffer)
  156. {
  157.    _EGLScreen *scr = (_EGLScreen *) elem;
  158.    EGLScreenMESA *handle = (EGLScreenMESA *) buffer;
  159.    *handle = _eglGetScreenHandle(scr);
  160.    return EGL_TRUE;
  161. }
  162.  
  163.  
  164. EGLBoolean
  165. _eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
  166.                    EGLint max_screens, EGLint *num_screens)
  167. {
  168.    *num_screens = _eglFlattenArray(display->Screens, (void *) screens,
  169.          sizeof(screens[0]), max_screens, _eglFlattenScreen);
  170.  
  171.    return EGL_TRUE;
  172. }
  173.  
  174.  
  175. /**
  176.  * Set a screen's surface origin.
  177.  */
  178. EGLBoolean
  179. _eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy,
  180.                        _EGLScreen *scrn, EGLint x, EGLint y)
  181. {
  182.    scrn->OriginX = x;
  183.    scrn->OriginY = y;
  184.  
  185.    return EGL_TRUE;
  186. }
  187.  
  188.  
  189. /**
  190.  * Query a screen's current surface.
  191.  */
  192. EGLBoolean
  193. _eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
  194.                            _EGLScreen *scrn, _EGLSurface **surf)
  195. {
  196.    *surf = scrn->CurrentSurface;
  197.    return EGL_TRUE;
  198. }
  199.  
  200.  
  201. /**
  202.  * Query a screen's current mode.
  203.  */
  204. EGLBoolean
  205. _eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
  206.                         _EGLMode **m)
  207. {
  208.    *m = scrn->CurrentMode;
  209.    return EGL_TRUE;
  210. }
  211.  
  212.  
  213. EGLBoolean
  214. _eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
  215.                     EGLint attribute, EGLint *value)
  216. {
  217.    switch (attribute) {
  218.    case EGL_SCREEN_POSITION_MESA:
  219.       value[0] = scrn->OriginX;
  220.       value[1] = scrn->OriginY;
  221.       break;
  222.    case EGL_SCREEN_POSITION_GRANULARITY_MESA:
  223.       value[0] = scrn->StepX;
  224.       value[1] = scrn->StepY;
  225.       break;
  226.    default:
  227.       _eglError(EGL_BAD_ATTRIBUTE, "eglQueryScreenMESA");
  228.       return EGL_FALSE;
  229.    }
  230.  
  231.    return EGL_TRUE;
  232. }
  233.  
  234.  
  235. #endif /* EGL_MESA_screen_surface */
  236.