2 * Ideas for screen management extension to EGL.
4 * Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc).
5 * The screens' handles can be obtained with eglGetScreensMESA().
7 * A new kind of EGLSurface is possible- one which can be directly scanned
8 * out on a screen. Such a surface is created with eglCreateScreenSurface().
10 * To actually display a screen surface on a screen, the eglShowSurface()
18 #include "egldisplay.h"
19 #include "eglcurrent.h"
21 #include "eglconfig.h"
22 #include "eglsurface.h"
23 #include "eglscreen.h"
27 #ifdef EGL_MESA_screen_surface
30 /* ugh, no atomic op? */
31 static _EGL_DECLARE_MUTEX(_eglNextScreenHandleMutex
);
32 static EGLScreenMESA _eglNextScreenHandle
= 1;
36 * Return a new screen handle/ID.
37 * NOTE: we never reuse these!
40 _eglAllocScreenHandle(void)
44 _eglLockMutex(&_eglNextScreenHandleMutex
);
45 s
= _eglNextScreenHandle
++;
46 _eglUnlockMutex(&_eglNextScreenHandleMutex
);
53 * Initialize an _EGLScreen object to default values.
56 _eglInitScreen(_EGLScreen
*screen
)
58 memset(screen
, 0, sizeof(_EGLScreen
));
65 * Given a public screen handle, return the internal _EGLScreen object.
68 _eglLookupScreen(EGLScreenMESA screen
, _EGLDisplay
*display
)
72 if (!display
->Screens
)
75 for (i
= 0; i
< display
->Screens
->Size
; i
++) {
76 _EGLScreen
*scr
= (_EGLScreen
*) display
->Screens
->Elements
[i
];
77 if (scr
->Handle
== screen
)
85 * Add the given _EGLScreen to the display's list of screens.
88 _eglAddScreen(_EGLDisplay
*display
, _EGLScreen
*screen
)
93 if (!display
->Screens
) {
94 display
->Screens
= _eglCreateArray("Screen", 4);
95 if (!display
->Screens
)
98 screen
->Handle
= _eglAllocScreenHandle();
99 _eglAppendArray(display
->Screens
, (void *) screen
);
105 _eglFlattenScreen(void *elem
, void *buffer
)
107 _EGLScreen
*scr
= (_EGLScreen
*) elem
;
108 EGLScreenMESA
*handle
= (EGLScreenMESA
*) buffer
;
109 *handle
= scr
->Handle
;
115 _eglGetScreensMESA(_EGLDriver
*drv
, _EGLDisplay
*display
, EGLScreenMESA
*screens
,
116 EGLint max_screens
, EGLint
*num_screens
)
118 *num_screens
= _eglFlattenArray(display
->Screens
, (void *) screens
,
119 sizeof(screens
[0]), max_screens
, _eglFlattenScreen
);
126 * Drivers should do a proper implementation.
129 _eglCreateScreenSurfaceMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
130 const EGLint
*attrib_list
)
137 * Show the given surface on the named screen.
138 * If surface is EGL_NO_SURFACE, disable the screen's output.
140 * This is just a placeholder function; drivers will always override
141 * this with code that _really_ shows the surface.
144 _eglShowScreenSurfaceMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
145 _EGLScreen
*scrn
, _EGLSurface
*surf
,
149 scrn
->CurrentSurface
= NULL
;
152 if (surf
->Type
!= EGL_SCREEN_BIT_MESA
) {
153 _eglError(EGL_BAD_SURFACE
, "eglShowSurfaceMESA");
156 if (surf
->Width
< mode
->Width
|| surf
->Height
< mode
->Height
) {
157 _eglError(EGL_BAD_SURFACE
,
158 "eglShowSurfaceMESA(surface smaller than screen size)");
162 scrn
->CurrentSurface
= surf
;
163 scrn
->CurrentMode
= mode
;
170 * Set a screen's current display mode.
171 * Note: mode = EGL_NO_MODE is valid (turns off the screen)
173 * This is just a placeholder function; drivers will always override
174 * this with code that _really_ sets the mode.
177 _eglScreenModeMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLScreen
*scrn
,
180 scrn
->CurrentMode
= m
;
186 * Set a screen's surface origin.
189 _eglScreenPositionMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
190 _EGLScreen
*scrn
, EGLint x
, EGLint y
)
200 * Query a screen's current surface.
203 _eglQueryScreenSurfaceMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
204 _EGLScreen
*scrn
, _EGLSurface
**surf
)
206 *surf
= scrn
->CurrentSurface
;
212 * Query a screen's current mode.
215 _eglQueryScreenModeMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLScreen
*scrn
,
218 *m
= scrn
->CurrentMode
;
224 _eglQueryScreenMESA(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLScreen
*scrn
,
225 EGLint attribute
, EGLint
*value
)
228 case EGL_SCREEN_POSITION_MESA
:
229 value
[0] = scrn
->OriginX
;
230 value
[1] = scrn
->OriginY
;
232 case EGL_SCREEN_POSITION_GRANULARITY_MESA
:
233 value
[0] = scrn
->StepX
;
234 value
[1] = scrn
->StepY
;
237 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryScreenMESA");
246 * Delete the modes associated with given screen.
249 _eglDestroyScreenModes(_EGLScreen
*scrn
)
252 for (i
= 0; i
< scrn
->NumModes
; i
++) {
253 if (scrn
->Modes
[i
].Name
)
254 free((char *) scrn
->Modes
[i
].Name
); /* cast away const */
264 * Default fallback routine - drivers should usually override this.
267 _eglDestroyScreen(_EGLScreen
*scrn
)
269 _eglDestroyScreenModes(scrn
);
274 #endif /* EGL_MESA_screen_surface */