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. #define EGL_EGLEXT_PROTOTYPES
  49. #include <EGL/egl.h>
  50. #include <EGL/eglext.h>
  51.  
  52. #include "egldisplay.h"
  53. #include "eglcurrent.h"
  54. #include "eglmode.h"
  55. #include "eglsurface.h"
  56. #include "eglscreen.h"
  57. #include "eglmutex.h"
  58.  
  59. //#define EGL_MESA_screen_surface
  60.  
  61. #ifdef EGL_MESA_screen_surface
  62.  
  63.  
  64. /* ugh, no atomic op? */
  65. static _EGL_DECLARE_MUTEX(_eglNextScreenHandleMutex);
  66. static EGLScreenMESA _eglNextScreenHandle = 1;
  67.  
  68.  
  69. /**
  70.  * Return a new screen handle/ID.
  71.  * NOTE: we never reuse these!
  72.  */
  73. static EGLScreenMESA
  74. _eglAllocScreenHandle(void)
  75. {
  76.    EGLScreenMESA s;
  77.  
  78.    _eglLockMutex(&_eglNextScreenHandleMutex);
  79.    s = _eglNextScreenHandle;
  80.    _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES;
  81.    _eglUnlockMutex(&_eglNextScreenHandleMutex);
  82.  
  83.    return s;
  84. }
  85.  
  86.  
  87. /**
  88.  * Initialize an _EGLScreen object to default values.
  89.  */
  90. void
  91. _eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes)
  92. {
  93.    memset(screen, 0, sizeof(_EGLScreen));
  94.  
  95.    screen->Display = dpy;
  96.    screen->NumModes = num_modes;
  97.    screen->StepX = 1;
  98.    screen->StepY = 1;
  99.  
  100.    if (num_modes > _EGL_SCREEN_MAX_MODES)
  101.       num_modes = _EGL_SCREEN_MAX_MODES;
  102.    screen->Modes = calloc(num_modes, sizeof(*screen->Modes));
  103.    screen->NumModes = (screen->Modes) ? num_modes : 0;
  104. }
  105.  
  106.  
  107. /**
  108.  * Link a screen to its display and return the handle of the link.
  109.  * The handle can be passed to client directly.
  110.  */
  111. EGLScreenMESA
  112. _eglLinkScreen(_EGLScreen *screen)
  113. {
  114.    _EGLDisplay *display;
  115.    EGLint i;
  116.  
  117.    assert(screen && screen->Display);
  118.    display = screen->Display;
  119.  
  120.    if (!display->Screens) {
  121.       display->Screens = _eglCreateArray("Screen", 4);
  122.       if (!display->Screens)
  123.          return (EGLScreenMESA) 0;
  124.    }
  125.  
  126.    screen->Handle = _eglAllocScreenHandle();
  127.    for (i = 0; i < screen->NumModes; i++)
  128.       screen->Modes[i].Handle = screen->Handle + i;
  129.  
  130.    _eglAppendArray(display->Screens, (void *) screen);
  131.  
  132.    return screen->Handle;
  133. }
  134.  
  135.  
  136. /**
  137.  * Lookup a handle to find the linked config.
  138.  * Return NULL if the handle has no corresponding linked config.
  139.  */
  140. _EGLScreen *
  141. _eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
  142. {
  143.    EGLint i;
  144.  
  145.    if (!display || !display->Screens)
  146.       return NULL;
  147.  
  148.    for (i = 0; i < display->Screens->Size; i++) {
  149.       _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i];
  150.       if (scr->Handle == screen) {
  151.          assert(scr->Display == display);
  152.          return scr;
  153.       }
  154.    }
  155.    return NULL;
  156. }
  157.  
  158.  
  159. static EGLBoolean
  160. _eglFlattenScreen(void *elem, void *buffer)
  161. {
  162.    _EGLScreen *scr = (_EGLScreen *) elem;
  163.    EGLScreenMESA *handle = (EGLScreenMESA *) buffer;
  164.    *handle = _eglGetScreenHandle(scr);
  165.    return EGL_TRUE;
  166. }
  167.  
  168.  
  169. EGLBoolean
  170. _eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
  171.                    EGLint max_screens, EGLint *num_screens)
  172. {
  173.    *num_screens = _eglFlattenArray(display->Screens, (void *) screens,
  174.          sizeof(screens[0]), max_screens, _eglFlattenScreen);
  175.  
  176.    return EGL_TRUE;
  177. }
  178.  
  179.  
  180. /**
  181.  * Set a screen's surface origin.
  182.  */
  183. EGLBoolean
  184. _eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy,
  185.                        _EGLScreen *scrn, EGLint x, EGLint y)
  186. {
  187.    scrn->OriginX = x;
  188.    scrn->OriginY = y;
  189.  
  190.    return EGL_TRUE;
  191. }
  192.  
  193.  
  194. /**
  195.  * Query a screen's current surface.
  196.  */
  197. EGLBoolean
  198. _eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
  199.                            _EGLScreen *scrn, _EGLSurface **surf)
  200. {
  201.    *surf = scrn->CurrentSurface;
  202.    return EGL_TRUE;
  203. }
  204.  
  205.  
  206. /**
  207.  * Query a screen's current mode.
  208.  */
  209. EGLBoolean
  210. _eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
  211.                         _EGLMode **m)
  212. {
  213.    *m = scrn->CurrentMode;
  214.    return EGL_TRUE;
  215. }
  216.  
  217.  
  218. EGLBoolean
  219. _eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
  220.                     EGLint attribute, EGLint *value)
  221. {
  222.    switch (attribute) {
  223.    case EGL_SCREEN_POSITION_MESA:
  224.       value[0] = scrn->OriginX;
  225.       value[1] = scrn->OriginY;
  226.       break;
  227.    case EGL_SCREEN_POSITION_GRANULARITY_MESA:
  228.       value[0] = scrn->StepX;
  229.       value[1] = scrn->StepY;
  230.       break;
  231.    default:
  232.       _eglError(EGL_BAD_ATTRIBUTE, "eglQueryScreenMESA");
  233.       return EGL_FALSE;
  234.    }
  235.  
  236.    return EGL_TRUE;
  237. }
  238.  
  239.  
  240. #endif /* EGL_MESA_screen_surface */
  241.