egl_dri2: Look up _glapi_get_proc_address dynamically.
[mesa.git] / src / egl / main / eglscreen.c
1 /*
2 * Ideas for screen management extension to EGL.
3 *
4 * Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc).
5 * The screens' handles can be obtained with eglGetScreensMESA().
6 *
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().
9 *
10 * To actually display a screen surface on a screen, the eglShowSurface()
11 * function is called.
12 */
13
14 #include <assert.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include "egldisplay.h"
19 #include "eglcurrent.h"
20 #include "eglmode.h"
21 #include "eglsurface.h"
22 #include "eglscreen.h"
23 #include "eglmutex.h"
24
25
26 #ifdef EGL_MESA_screen_surface
27
28
29 /* ugh, no atomic op? */
30 static _EGL_DECLARE_MUTEX(_eglNextScreenHandleMutex);
31 static EGLScreenMESA _eglNextScreenHandle = 1;
32
33
34 /**
35 * Return a new screen handle/ID.
36 * NOTE: we never reuse these!
37 */
38 static EGLScreenMESA
39 _eglAllocScreenHandle(void)
40 {
41 EGLScreenMESA s;
42
43 _eglLockMutex(&_eglNextScreenHandleMutex);
44 s = _eglNextScreenHandle;
45 _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES;
46 _eglUnlockMutex(&_eglNextScreenHandleMutex);
47
48 return s;
49 }
50
51
52 /**
53 * Initialize an _EGLScreen object to default values.
54 */
55 void
56 _eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes)
57 {
58 memset(screen, 0, sizeof(_EGLScreen));
59
60 screen->Display = dpy;
61 screen->NumModes = num_modes;
62 screen->StepX = 1;
63 screen->StepY = 1;
64
65 if (num_modes > _EGL_SCREEN_MAX_MODES)
66 num_modes = _EGL_SCREEN_MAX_MODES;
67 screen->Modes = (_EGLMode *) calloc(num_modes, sizeof(*screen->Modes));
68 screen->NumModes = (screen->Modes) ? num_modes : 0;
69 }
70
71
72 /**
73 * Link a screen to its display and return the handle of the link.
74 * The handle can be passed to client directly.
75 */
76 EGLScreenMESA
77 _eglLinkScreen(_EGLScreen *screen)
78 {
79 _EGLDisplay *display;
80 EGLint i;
81
82 assert(screen && screen->Display);
83 display = screen->Display;
84
85 if (!display->Screens) {
86 display->Screens = _eglCreateArray("Screen", 4);
87 if (!display->Screens)
88 return (EGLScreenMESA) 0;
89 }
90
91 screen->Handle = _eglAllocScreenHandle();
92 for (i = 0; i < screen->NumModes; i++)
93 screen->Modes[i].Handle = screen->Handle + i;
94
95 _eglAppendArray(display->Screens, (void *) screen);
96
97 return screen->Handle;
98 }
99
100
101 /**
102 * Lookup a handle to find the linked config.
103 * Return NULL if the handle has no corresponding linked config.
104 */
105 _EGLScreen *
106 _eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
107 {
108 EGLint i;
109
110 if (!display || !display->Screens)
111 return NULL;
112
113 for (i = 0; i < display->Screens->Size; i++) {
114 _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i];
115 if (scr->Handle == screen) {
116 assert(scr->Display == display);
117 return scr;
118 }
119 }
120 return NULL;
121 }
122
123
124 static EGLBoolean
125 _eglFlattenScreen(void *elem, void *buffer)
126 {
127 _EGLScreen *scr = (_EGLScreen *) elem;
128 EGLScreenMESA *handle = (EGLScreenMESA *) buffer;
129 *handle = _eglGetScreenHandle(scr);
130 return EGL_TRUE;
131 }
132
133
134 EGLBoolean
135 _eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
136 EGLint max_screens, EGLint *num_screens)
137 {
138 *num_screens = _eglFlattenArray(display->Screens, (void *) screens,
139 sizeof(screens[0]), max_screens, _eglFlattenScreen);
140
141 return EGL_TRUE;
142 }
143
144
145 /**
146 * Set a screen's surface origin.
147 */
148 EGLBoolean
149 _eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy,
150 _EGLScreen *scrn, EGLint x, EGLint y)
151 {
152 scrn->OriginX = x;
153 scrn->OriginY = y;
154
155 return EGL_TRUE;
156 }
157
158
159 /**
160 * Query a screen's current surface.
161 */
162 EGLBoolean
163 _eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
164 _EGLScreen *scrn, _EGLSurface **surf)
165 {
166 *surf = scrn->CurrentSurface;
167 return EGL_TRUE;
168 }
169
170
171 /**
172 * Query a screen's current mode.
173 */
174 EGLBoolean
175 _eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
176 _EGLMode **m)
177 {
178 *m = scrn->CurrentMode;
179 return EGL_TRUE;
180 }
181
182
183 EGLBoolean
184 _eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
185 EGLint attribute, EGLint *value)
186 {
187 switch (attribute) {
188 case EGL_SCREEN_POSITION_MESA:
189 value[0] = scrn->OriginX;
190 value[1] = scrn->OriginY;
191 break;
192 case EGL_SCREEN_POSITION_GRANULARITY_MESA:
193 value[0] = scrn->StepX;
194 value[1] = scrn->StepY;
195 break;
196 default:
197 _eglError(EGL_BAD_ATTRIBUTE, "eglQueryScreenMESA");
198 return EGL_FALSE;
199 }
200
201 return EGL_TRUE;
202 }
203
204
205 #endif /* EGL_MESA_screen_surface */