egl: Some per-driver data should be per-display.
[platform/upstream/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 *disp, EGLint *major, EGLint *minor)
53 {
54    _EGLScreen *scrn;
55    EGLint i;
56
57    /* Create a screen */
58    scrn = calloc(1, sizeof(*scrn));
59    _eglAddScreen(disp, scrn);
60
61    /* Create the screen's modes - silly example */
62    _eglAddNewMode(scrn, 1600, 1200, 72 * 1000, "1600x1200-72");
63    _eglAddNewMode(scrn, 1280, 1024, 72 * 1000, "1280x1024-70");
64    _eglAddNewMode(scrn, 1280, 1024, 70 * 1000, "1280x1024-70");
65    _eglAddNewMode(scrn, 1024,  768, 72 * 1000, "1024x768-72");
66
67    /* Create the display's visual configs - silly example */
68    for (i = 0; i < 4; i++) {
69       _EGLConfig *config = calloc(1, sizeof(_EGLConfig));
70       _eglInitConfig(config, i + 1);
71       _eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
72       _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
73       _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
74       _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
75       _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
76       if (i & 1) {
77          _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 32);
78       }
79       if (i & 2) {
80          _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
81       }
82       _eglSetConfigAttrib(config, EGL_SURFACE_TYPE,
83                           (EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT));
84       _eglAddConfig(disp, config);
85    }
86
87    /* enable supported extensions */
88    disp->Extensions.MESA_screen_surface = EGL_TRUE;
89    disp->Extensions.MESA_copy_context = EGL_TRUE;
90
91    *major = 1;
92    *minor = 0;
93
94    return EGL_TRUE;
95 }
96
97
98 static EGLBoolean
99 demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
100 {
101    /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
102    return EGL_TRUE;
103 }
104
105
106 static DemoContext *
107 LookupDemoContext(_EGLContext *c)
108 {
109    return (DemoContext *) c;
110 }
111
112
113 static DemoSurface *
114 LookupDemoSurface(_EGLSurface *s)
115 {
116    return (DemoSurface *) s;
117 }
118
119
120 static _EGLContext *
121 demoCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list)
122 {
123    DemoContext *c;
124    int i;
125
126    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
127       switch (attrib_list[i]) {
128          /* no attribs defined for now */
129       default:
130          _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
131          return NULL;
132       }
133    }
134
135    c = (DemoContext *) calloc(1, sizeof(DemoContext));
136    if (!c)
137       return NULL;
138
139    _eglInitContext(drv, &c->Base, conf, attrib_list);
140    c->DemoStuff = 1;
141    printf("demoCreateContext\n");
142
143    return &c->Base;
144 }
145
146
147 static _EGLSurface *
148 demoCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list)
149 {
150    int i;
151    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
152       switch (attrib_list[i]) {
153          /* no attribs at this time */
154       default:
155          _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface");
156          return NULL;
157       }
158    }
159    printf("eglCreateWindowSurface()\n");
160    /* XXX unfinished */
161
162    return NULL;
163 }
164
165
166 static _EGLSurface *
167 demoCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list)
168 {
169    EGLint i;
170
171    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
172       switch (attrib_list[i]) {
173          /* no attribs at this time */
174       default:
175          _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
176          return NULL;
177       }
178    }
179
180    if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) {
181       _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface");
182       return NULL;
183    }
184
185    printf("eglCreatePixmapSurface()\n");
186    return NULL;
187 }
188
189
190 static _EGLSurface *
191 demoCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
192                          const EGLint *attrib_list)
193 {
194    DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
195
196    if (!surf)
197       return NULL;
198
199    if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
200                         conf, attrib_list)) {
201       free(surf);
202       return NULL;
203    }
204
205    /* a real driver would allocate the pbuffer memory here */
206
207    return &surf->Base;
208 }
209
210
211 static EGLBoolean
212 demoDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
213 {
214    DemoSurface *fs = LookupDemoSurface(surface);
215    if (!_eglIsSurfaceBound(&fs->Base))
216       free(fs);
217    return EGL_TRUE;
218 }
219
220
221 static EGLBoolean
222 demoDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context)
223 {
224    DemoContext *fc = LookupDemoContext(context);
225    if (!_eglIsContextBound(&fc->Base))
226       free(fc);
227    return EGL_TRUE;
228 }
229
230
231 static EGLBoolean
232 demoMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *drawSurf, _EGLSurface *readSurf, _EGLContext *ctx)
233 {
234    /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
235    EGLBoolean b;
236
237    b = _eglMakeCurrent(drv, dpy, drawSurf, readSurf, ctx);
238    if (!b)
239       return EGL_FALSE;
240
241    /* XXX this is where we'd do the hardware context switch */
242    (void) drawSurf;
243    (void) readSurf;
244    (void) ctx;
245
246    printf("eglMakeCurrent()\n");
247    return EGL_TRUE;
248 }
249
250
251 static void
252 demoUnload(_EGLDriver *drv)
253 {
254    free(drv);
255 }
256
257
258 /**
259  * The bootstrap function.  Return a new DemoDriver object and
260  * plug in API functions.
261  */
262 _EGLDriver *
263 _eglMain(const char *args)
264 {
265    DemoDriver *demo;
266
267    demo = (DemoDriver *) calloc(1, sizeof(DemoDriver));
268    if (!demo) {
269       return NULL;
270    }
271
272    /* First fill in the dispatch table with defaults */
273    _eglInitDriverFallbacks(&demo->Base);
274    /* then plug in our Demo-specific functions */
275    demo->Base.API.Initialize = demoInitialize;
276    demo->Base.API.Terminate = demoTerminate;
277    demo->Base.API.CreateContext = demoCreateContext;
278    demo->Base.API.MakeCurrent = demoMakeCurrent;
279    demo->Base.API.CreateWindowSurface = demoCreateWindowSurface;
280    demo->Base.API.CreatePixmapSurface = demoCreatePixmapSurface;
281    demo->Base.API.CreatePbufferSurface = demoCreatePbufferSurface;
282    demo->Base.API.DestroySurface = demoDestroySurface;
283    demo->Base.API.DestroyContext = demoDestroyContext;
284
285    demo->Base.Name = "egl/demo";
286    demo->Base.Unload = demoUnload;
287
288    return &demo->Base;
289 }