1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5 * Copyright 2010 LunarG, Inc.
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:
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
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.
28 **************************************************************************/
32 * Ideas for screen management extension to EGL.
34 * Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc).
35 * The screens' handles can be obtained with eglGetScreensMESA().
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().
40 * To actually display a screen surface on a screen, the eglShowSurface()
48 #include "egldisplay.h"
49 #include "eglcurrent.h"
51 #include "eglsurface.h"
52 #include "eglscreen.h"
56 #ifdef EGL_MESA_screen_surface
59 /* ugh, no atomic op? */
60 static _EGL_DECLARE_MUTEX(_eglNextScreenHandleMutex
);
61 static EGLScreenMESA _eglNextScreenHandle
= 1;
65 * Return a new screen handle/ID.
66 * NOTE: we never reuse these!
69 _eglAllocScreenHandle(void)
73 _eglLockMutex(&_eglNextScreenHandleMutex
);
74 s
= _eglNextScreenHandle
;
75 _eglNextScreenHandle
+= _EGL_SCREEN_MAX_MODES
;
76 _eglUnlockMutex(&_eglNextScreenHandleMutex
);
83 * Initialize an _EGLScreen object to default values.
86 _eglInitScreen(_EGLScreen
*screen
, _EGLDisplay
*dpy
, EGLint num_modes
)
88 memset(screen
, 0, sizeof(_EGLScreen
));
90 screen
->Display
= dpy
;
91 screen
->NumModes
= num_modes
;
95 if (num_modes
> _EGL_SCREEN_MAX_MODES
)
96 num_modes
= _EGL_SCREEN_MAX_MODES
;
97 screen
->Modes
= (_EGLMode
*) calloc(num_modes
, sizeof(*screen
->Modes
));
98 screen
->NumModes
= (screen
->Modes
) ? num_modes
: 0;
103 * Link a screen to its display and return the handle of the link.
104 * The handle can be passed to client directly.
107 _eglLinkScreen(_EGLScreen
*screen
)
109 _EGLDisplay
*display
;
112 assert(screen
&& screen
->Display
);
113 display
= screen
->Display
;
115 if (!display
->Screens
) {
116 display
->Screens
= _eglCreateArray("Screen", 4);
117 if (!display
->Screens
)
118 return (EGLScreenMESA
) 0;
121 screen
->Handle
= _eglAllocScreenHandle();
122 for (i
= 0; i
< screen
->NumModes
; i
++)
123 screen
->Modes
[i
].Handle
= screen
->Handle
+ i
;
125 _eglAppendArray(display
->Screens
, (void *) screen
);
127 return screen
->Handle
;
132 * Lookup a handle to find the linked config.
133 * Return NULL if the handle has no corresponding linked config.
136 _eglLookupScreen(EGLScreenMESA screen
, _EGLDisplay
*display
)
140 if (!display
|| !display
->Screens
)
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
);
155 _eglFlattenScreen(void *elem
, void *buffer
)
157 _EGLScreen
*scr
= (_EGLScreen
*) elem
;
158 EGLScreenMESA
*handle
= (EGLScreenMESA
*) buffer
;
159 *handle
= _eglGetScreenHandle(scr
);
165 _eglGetScreensMESA(_EGLDriver
*drv
, _EGLDisplay
*display
, EGLScreenMESA
*screens
,
166 EGLint max_screens
, EGLint
*num_screens
)
168 *num_screens
= _eglFlattenArray(display
->Screens
, (void *) screens
,
169 sizeof(screens
[0]), max_screens
, _eglFlattenScreen
);
176 * Set a screen's surface origin.
179 _eglScreenPositionMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
180 _EGLScreen
*scrn
, EGLint x
, EGLint y
)
190 * Query a screen's current surface.
193 _eglQueryScreenSurfaceMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
194 _EGLScreen
*scrn
, _EGLSurface
**surf
)
196 *surf
= scrn
->CurrentSurface
;
202 * Query a screen's current mode.
205 _eglQueryScreenModeMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLScreen
*scrn
,
208 *m
= scrn
->CurrentMode
;
214 _eglQueryScreenMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLScreen
*scrn
,
215 EGLint attribute
, EGLint
*value
)
218 case EGL_SCREEN_POSITION_MESA
:
219 value
[0] = scrn
->OriginX
;
220 value
[1] = scrn
->OriginY
;
222 case EGL_SCREEN_POSITION_GRANULARITY_MESA
:
223 value
[0] = scrn
->StepX
;
224 value
[1] = scrn
->StepY
;
227 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryScreenMESA");
235 #endif /* EGL_MESA_screen_surface */