e8c0c1df5ee4301b58be7c381ac26baf1617a757
[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 unsigned 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 unsigned 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 unsigned 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 _eglAddNewMode(scrn, 1600, 1200, 72 * 1000, "1600x1200-72");
64 _eglAddNewMode(scrn, 1280, 1024, 72 * 1000, "1280x1024-70");
65 _eglAddNewMode(scrn, 1280, 1024, 70 * 1000, "1280x1024-70");
66 _eglAddNewMode(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 = calloc(1, sizeof(_EGLConfig));
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 int i;
129
130 conf = _eglLookupConfig(drv, dpy, config);
131 if (!conf) {
132 _eglError(EGL_BAD_CONFIG, "eglCreateContext");
133 return EGL_NO_CONTEXT;
134 }
135
136 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
137 switch (attrib_list[i]) {
138 /* no attribs defined for now */
139 default:
140 _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
141 return EGL_NO_CONTEXT;
142 }
143 }
144
145 c = (DemoContext *) calloc(1, sizeof(DemoContext));
146 if (!c)
147 return EGL_NO_CONTEXT;
148
149 _eglInitContext(drv, &c->Base, conf, attrib_list);
150 c->DemoStuff = 1;
151 printf("demoCreateContext\n");
152
153 /* link to display */
154 _eglLinkContext(&c->Base, _eglLookupDisplay(dpy));
155 assert(_eglGetContextHandle(&c->Base));
156
157 return _eglGetContextHandle(&c->Base);
158 }
159
160
161 static EGLSurface
162 demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
163 {
164 int i;
165 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
166 switch (attrib_list[i]) {
167 /* no attribs at this time */
168 default:
169 _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface");
170 return EGL_NO_SURFACE;
171 }
172 }
173 printf("eglCreateWindowSurface()\n");
174 /* XXX unfinished */
175
176 return EGL_NO_SURFACE;
177 }
178
179
180 static EGLSurface
181 demoCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
182 {
183 _EGLConfig *conf;
184 EGLint i;
185
186 conf = _eglLookupConfig(drv, dpy, config);
187 if (!conf) {
188 _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
189 return EGL_NO_SURFACE;
190 }
191
192 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
193 switch (attrib_list[i]) {
194 /* no attribs at this time */
195 default:
196 _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
197 return EGL_NO_SURFACE;
198 }
199 }
200
201 if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) {
202 _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface");
203 return EGL_NO_SURFACE;
204 }
205
206 printf("eglCreatePixmapSurface()\n");
207 return EGL_NO_SURFACE;
208 }
209
210
211 static EGLSurface
212 demoCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
213 const EGLint *attrib_list)
214 {
215 DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
216 _EGLConfig *conf;
217
218 if (!surf)
219 return EGL_NO_SURFACE;
220
221 conf = _eglLookupConfig(drv, dpy, config);
222 if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
223 conf, attrib_list)) {
224 free(surf);
225 return EGL_NO_SURFACE;
226 }
227
228 /* a real driver would allocate the pbuffer memory here */
229
230 return surf->Base.Handle;
231 }
232
233
234 static EGLBoolean
235 demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
236 {
237 DemoSurface *fs = LookupDemoSurface(surface);
238 _eglUnlinkSurface(&fs->Base);
239 if (!_eglIsSurfaceBound(&fs->Base))
240 free(fs);
241 return EGL_TRUE;
242 }
243
244
245 static EGLBoolean
246 demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
247 {
248 DemoContext *fc = LookupDemoContext(context);
249 _eglUnlinkContext(&fc->Base);
250 if (!_eglIsContextBound(&fc->Base))
251 free(fc);
252 return EGL_TRUE;
253 }
254
255
256 static EGLBoolean
257 demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
258 {
259 /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
260 DemoSurface *readSurf = LookupDemoSurface(read);
261 DemoSurface *drawSurf = LookupDemoSurface(draw);
262 DemoContext *ctx = LookupDemoContext(context);
263 EGLBoolean b;
264
265 b = _eglMakeCurrent(drv, dpy, draw, read, context);
266 if (!b)
267 return EGL_FALSE;
268
269 /* XXX this is where we'd do the hardware context switch */
270 (void) drawSurf;
271 (void) readSurf;
272 (void) ctx;
273
274 printf("eglMakeCurrent()\n");
275 return EGL_TRUE;
276 }
277
278
279 /**
280 * The bootstrap function. Return a new DemoDriver object and
281 * plug in API functions.
282 */
283 _EGLDriver *
284 _eglMain(_EGLDisplay *dpy, const char *args)
285 {
286 DemoDriver *demo;
287
288 demo = (DemoDriver *) calloc(1, sizeof(DemoDriver));
289 if (!demo) {
290 return NULL;
291 }
292
293 /* First fill in the dispatch table with defaults */
294 _eglInitDriverFallbacks(&demo->Base);
295 /* then plug in our Demo-specific functions */
296 demo->Base.API.Initialize = demoInitialize;
297 demo->Base.API.Terminate = demoTerminate;
298 demo->Base.API.CreateContext = demoCreateContext;
299 demo->Base.API.MakeCurrent = demoMakeCurrent;
300 demo->Base.API.CreateWindowSurface = demoCreateWindowSurface;
301 demo->Base.API.CreatePixmapSurface = demoCreatePixmapSurface;
302 demo->Base.API.CreatePbufferSurface = demoCreatePbufferSurface;
303 demo->Base.API.DestroySurface = demoDestroySurface;
304 demo->Base.API.DestroyContext = demoDestroyContext;
305
306 /* enable supported extensions */
307 demo->Base.Extensions.MESA_screen_surface = EGL_TRUE;
308 demo->Base.Extensions.MESA_copy_context = EGL_TRUE;
309
310 return &demo->Base;
311 }