Merge commit 'origin/gallium-draw-retval'
[mesa.git] / src / gallium / state_trackers / egl / egl_context.c
1
2 #include "utils.h"
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include "egl_tracker.h"
7
8 #include "egllog.h"
9
10
11 #include "pipe/p_context.h"
12 #include "pipe/p_screen.h"
13
14 #include "state_tracker/st_public.h"
15 #include "state_tracker/drm_api.h"
16
17 #include "GL/internal/glcore.h"
18
19 _EGLContext *
20 drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list)
21 {
22 struct drm_device *dev = lookup_drm_device(dpy);
23 struct drm_context *ctx;
24 struct drm_context *share = NULL;
25 struct st_context *st_share = NULL;
26 int i;
27 __GLcontextModes *visual;
28
29 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
30 switch (attrib_list[i]) {
31 /* no attribs defined for now */
32 default:
33 _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
34 return EGL_NO_CONTEXT;
35 }
36 }
37
38 ctx = (struct drm_context *) calloc(1, sizeof(struct drm_context));
39 if (!ctx)
40 goto err_c;
41
42 _eglInitContext(drv, &ctx->base, conf, attrib_list);
43
44 ctx->pipe = dev->api->create_context(dev->api, dev->screen);
45 if (!ctx->pipe)
46 goto err_pipe;
47
48 if (share)
49 st_share = share->st;
50
51 visual = drm_visual_from_config(conf);
52 ctx->st = st_create_context(ctx->pipe, visual, st_share);
53 drm_visual_modes_destroy(visual);
54
55 if (!ctx->st)
56 goto err_gl;
57
58 return &ctx->base;
59
60 err_gl:
61 ctx->pipe->destroy(ctx->pipe);
62 err_pipe:
63 free(ctx);
64 err_c:
65 return NULL;
66 }
67
68 EGLBoolean
69 drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context)
70 {
71 struct drm_context *c = lookup_drm_context(context);
72 if (!_eglIsContextBound(&c->base)) {
73 st_destroy_context(c->st);
74 free(c);
75 }
76 return EGL_TRUE;
77 }
78
79 EGLBoolean
80 drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context)
81 {
82 struct drm_surface *readSurf = lookup_drm_surface(read);
83 struct drm_surface *drawSurf = lookup_drm_surface(draw);
84 struct drm_context *ctx = lookup_drm_context(context);
85 EGLBoolean b;
86
87 b = _eglMakeCurrent(drv, dpy, draw, read, context);
88 if (!b)
89 return EGL_FALSE;
90
91 if (ctx) {
92 if (!drawSurf || !readSurf)
93 return EGL_FALSE;
94
95 st_make_current(ctx->st, drawSurf->stfb, readSurf->stfb);
96
97 /* st_resize_framebuffer needs a bound context to work */
98 st_resize_framebuffer(drawSurf->stfb, drawSurf->w, drawSurf->h);
99 st_resize_framebuffer(readSurf->stfb, readSurf->w, readSurf->h);
100 } else {
101 st_make_current(NULL, NULL, NULL);
102 }
103
104 return EGL_TRUE;
105 }