9b751959590718d14527c9c96c9fb44703fed3ac
[mesa.git] / src / egl / drivers / demo / demo.c
1 /*
2 * Sample driver: Demo
3 */
4
5 #include <assert.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "eglconfig.h"
9 #include "eglcontext.h"
10 #include "egldisplay.h"
11 #include "egldriver.h"
12 #include "eglglobals.h"
13 #include "eglmode.h"
14 #include "eglscreen.h"
15 #include "eglsurface.h"
16
17
18 /**
19 * Demo driver-specific driver class derived from _EGLDriver
20 */
21 typedef struct demo_driver
22 {
23 _EGLDriver Base; /* base class/object */
24 GLuint DemoStuff;
25 } DemoDriver;
26
27 #define DEMO_DRIVER(D) ((DemoDriver *) (D))
28
29
30 /**
31 * Demo driver-specific surface class derived from _EGLSurface
32 */
33 typedef struct demo_surface
34 {
35 _EGLSurface Base; /* base class/object */
36 GLuint DemoStuff;
37 } DemoSurface;
38
39
40 /**
41 * Demo driver-specific context class derived from _EGLContext
42 */
43 typedef struct demo_context
44 {
45 _EGLContext Base; /* base class/object */
46 GLuint DemoStuff;
47 } DemoContext;
48
49
50
51 static EGLBoolean
52 demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
53 {
54 _EGLDisplay *disp = _eglLookupDisplay(dpy);
55 _EGLScreen *scrn;
56 EGLint i;
57
58 /* Create a screen */
59 scrn = calloc(1, sizeof(*scrn));
60 _eglAddScreen(disp, scrn);
61
62 /* Create the screen's modes - silly example */
63 _eglAddMode(scrn, 1600, 1200, 72 * 1000, "1600x1200-72");
64 _eglAddMode(scrn, 1280, 1024, 72 * 1000, "1280x1024-70");
65 _eglAddMode(scrn, 1280, 1024, 70 * 1000, "1280x1024-70");
66 _eglAddMode(scrn, 1024, 768, 72 * 1000, "1024x768-72");
67
68 /* Create the display's visual configs - silly example */
69 for (i = 0; i < 4; i++) {
70 _EGLConfig config;
71 _eglInitConfig(&config, i + 1);
72 _eglSetConfigAttrib(&config, EGL_RED_SIZE, 8);
73 _eglSetConfigAttrib(&config, EGL_GREEN_SIZE, 8);
74 _eglSetConfigAttrib(&config, EGL_BLUE_SIZE, 8);
75 _eglSetConfigAttrib(&config, EGL_ALPHA_SIZE, 8);
76 _eglSetConfigAttrib(&config, EGL_BUFFER_SIZE, 32);
77 if (i & 1) {
78 _eglSetConfigAttrib(&config, EGL_DEPTH_SIZE, 32);
79 }
80 if (i & 2) {
81 _eglSetConfigAttrib(&config, EGL_STENCIL_SIZE, 8);
82 }
83 _eglSetConfigAttrib(&config, EGL_SURFACE_TYPE,
84 (EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT));
85 _eglAddConfig(disp, &config);
86 }
87
88 drv->Initialized = EGL_TRUE;
89
90 *major = 1;
91 *minor = 0;
92
93 return EGL_TRUE;
94 }
95
96
97 static EGLBoolean
98 demoTerminate(_EGLDriver *drv, EGLDisplay dpy)
99 {
100 /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
101 free(drv);
102 return EGL_TRUE;
103 }
104
105
106 static DemoContext *
107 LookupDemoContext(EGLContext ctx)
108 {
109 _EGLContext *c = _eglLookupContext(ctx);
110 return (DemoContext *) c;
111 }
112
113
114 static DemoSurface *
115 LookupDemoSurface(EGLSurface surf)
116 {
117 _EGLSurface *s = _eglLookupSurface(surf);
118 return (DemoSurface *) s;
119 }
120
121
122
123 static EGLContext
124 demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
125 {
126 _EGLConfig *conf;
127 DemoContext *c;
128 _EGLDisplay *disp = _eglLookupDisplay(dpy);
129 int i;
130
131 conf = _eglLookupConfig(drv, dpy, config);
132 if (!conf) {
133 _eglError(EGL_BAD_CONFIG, "eglCreateContext");
134 return EGL_NO_CONTEXT;
135 }
136
137 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
138 switch (attrib_list[i]) {
139 /* no attribs defined for now */
140 default:
141 _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
142 return EGL_NO_CONTEXT;
143 }
144 }
145
146 c = (DemoContext *) calloc(1, sizeof(DemoContext));
147 if (!c)
148 return EGL_NO_CONTEXT;
149
150 _eglInitContext(&c->Base);
151 c->Base.Display = disp;
152 c->Base.Config = conf;
153 c->Base.DrawSurface = EGL_NO_SURFACE;
154 c->Base.ReadSurface = EGL_NO_SURFACE;
155 c->DemoStuff = 1;
156 printf("demoCreateContext\n");
157
158 /* generate handle and insert into hash table */
159 _eglSaveContext(&c->Base);
160 assert(c->Base.Handle);
161
162 return c->Base.Handle;
163 }
164
165
166 static EGLSurface
167 demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
168 {
169 int i;
170 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
171 switch (attrib_list[i]) {
172 /* no attribs at this time */
173 default:
174 _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface");
175 return EGL_NO_SURFACE;
176 }
177 }
178 printf("eglCreateWindowSurface()\n");
179 /* XXX unfinished */
180
181 return EGL_NO_SURFACE;
182 }
183
184
185 static EGLSurface
186 demoCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
187 {
188 _EGLConfig *conf;
189 EGLint i;
190
191 conf = _eglLookupConfig(drv, dpy, config);
192 if (!conf) {
193 _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
194 return EGL_NO_SURFACE;
195 }
196
197 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
198 switch (attrib_list[i]) {
199 /* no attribs at this time */
200 default:
201 _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
202 return EGL_NO_SURFACE;
203 }
204 }
205
206 if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) {
207 _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface");
208 return EGL_NO_SURFACE;
209 }
210
211 printf("eglCreatePixmapSurface()\n");
212 return EGL_NO_SURFACE;
213 }
214
215
216 static EGLSurface
217 demoCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
218 const EGLint *attrib_list)
219 {
220 DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
221 if (!surf)
222 return EGL_NO_SURFACE;
223
224 if (_eglInitPbufferSurface(&surf->Base, drv, dpy, config, attrib_list)
225 == EGL_NO_SURFACE) {
226 free(surf);
227 return EGL_NO_SURFACE;
228 }
229
230 /* a real driver would allocate the pbuffer memory here */
231
232 return surf->Base.Handle;
233 }
234
235
236 static EGLBoolean
237 demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
238 {
239 DemoSurface *fs = LookupDemoSurface(surface);
240 _eglRemoveSurface(&fs->Base);
241 if (fs->Base.IsBound) {
242 fs->Base.DeletePending = EGL_TRUE;
243 }
244 else {
245 free(fs);
246 }
247 return EGL_TRUE;
248 }
249
250
251 static EGLBoolean
252 demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
253 {
254 DemoContext *fc = LookupDemoContext(context);
255 _eglRemoveContext(&fc->Base);
256 if (fc->Base.IsBound) {
257 fc->Base.DeletePending = EGL_TRUE;
258 }
259 else {
260 free(fc);
261 }
262 return EGL_TRUE;
263 }
264
265
266 static EGLBoolean
267 demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
268 {
269 /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
270 DemoSurface *readSurf = LookupDemoSurface(read);
271 DemoSurface *drawSurf = LookupDemoSurface(draw);
272 DemoContext *ctx = LookupDemoContext(context);
273 EGLBoolean b;
274
275 b = _eglMakeCurrent(drv, dpy, draw, read, context);
276 if (!b)
277 return EGL_FALSE;
278
279 /* XXX this is where we'd do the hardware context switch */
280 (void) drawSurf;
281 (void) readSurf;
282 (void) ctx;
283
284 printf("eglMakeCurrent()\n");
285 return EGL_TRUE;
286 }
287
288
289 /*
290 * Just to silence warning
291 */
292 extern _EGLDriver *
293 _eglMain(NativeDisplayType dpy);
294
295
296 /**
297 * The bootstrap function. Return a new DemoDriver object and
298 * plug in API functions.
299 */
300 _EGLDriver *
301 _eglMain(NativeDisplayType dpy)
302 {
303 DemoDriver *demo;
304
305 demo = (DemoDriver *) calloc(1, sizeof(DemoDriver));
306 if (!demo) {
307 return NULL;
308 }
309
310 /* First fill in the dispatch table with defaults */
311 _eglInitDriverFallbacks(&demo->Base);
312 /* then plug in our Demo-specific functions */
313 demo->Base.Initialize = demoInitialize;
314 demo->Base.Terminate = demoTerminate;
315 demo->Base.CreateContext = demoCreateContext;
316 demo->Base.MakeCurrent = demoMakeCurrent;
317 demo->Base.CreateWindowSurface = demoCreateWindowSurface;
318 demo->Base.CreatePixmapSurface = demoCreatePixmapSurface;
319 demo->Base.CreatePbufferSurface = demoCreatePbufferSurface;
320 demo->Base.DestroySurface = demoDestroySurface;
321 demo->Base.DestroyContext = demoDestroyContext;
322
323 /* enable supported extensions */
324 demo->Base.MESA_screen_surface = EGL_TRUE;
325 demo->Base.MESA_copy_context = EGL_TRUE;
326
327 return &demo->Base;
328 }