Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /************************************************************************** |
2 | * |
||
3 | * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
||
4 | * Copyright 2009-2010 Chia-I Wu |
||
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 |
||
45 | #include |
||
46 | #include |
||
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 */>> |