summaryrefslogtreecommitdiff
path: root/src/modules/evas/engines/gl_drm/evas_outbuf.c
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2015-06-03 12:56:35 -0400
committerChris Michael <cp.michael@samsung.com>2015-06-05 10:00:44 -0400
commitee593050f1674f29a99156f135c92f43cb5897e2 (patch)
tree2b9640cee9900f7700f789887f28df679cb00f32 /src/modules/evas/engines/gl_drm/evas_outbuf.c
parent58dbb63ba4bbc235477793b016ba31d2bf17d1fb (diff)
evas-gl-drm: Rework gl_drm engine to function again
Summary: Previous gl_drm evas engine code did not work properly (or at all really). This reworks/refactors the gl_drm engine code to work again with the changes made to ecore_drm. @fix Signed-off-by: Chris Michael <cp.michael@samsung.com>
Diffstat (limited to '')
-rw-r--r--src/modules/evas/engines/gl_drm/evas_outbuf.c656
1 files changed, 656 insertions, 0 deletions
diff --git a/src/modules/evas/engines/gl_drm/evas_outbuf.c b/src/modules/evas/engines/gl_drm/evas_outbuf.c
new file mode 100644
index 0000000000..124a3563a3
--- /dev/null
+++ b/src/modules/evas/engines/gl_drm/evas_outbuf.c
@@ -0,0 +1,656 @@
1#include "evas_engine.h"
2
3/* local variables */
4static Outbuf *_evas_gl_drm_window = NULL;
5static EGLContext context = EGL_NO_CONTEXT;
6static int win_count = 0;
7
8static void
9_evas_outbuf_cb_pageflip(void *data)
10{
11 Outbuf *ob;
12 Ecore_Drm_Fb *fb;
13
14 if (!(ob = data)) return;
15
16 if ((fb = ob->priv.buffer[ob->priv.curr]))
17 {
18 fb->pending_flip = EINA_FALSE;
19 gbm_surface_release_buffer(ob->surface, ob->priv.bo[ob->priv.curr]);
20 }
21
22 ob->priv.last = ob->priv.curr;
23 ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num;
24}
25
26static void
27_evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count)
28{
29 Ecore_Drm_Fb *buff;
30
31 buff = ob->priv.buffer[ob->priv.curr];
32
33 ob->priv.bo[ob->priv.curr] = gbm_surface_lock_front_buffer(ob->surface);
34
35 ecore_drm_fb_dirty(buff, rects, count);
36 ecore_drm_fb_set(ob->info->info.dev, buff);
37 ecore_drm_fb_send(ob->info->info.dev, buff, _evas_outbuf_cb_pageflip, ob);
38}
39
40static Eina_Bool
41_evas_outbuf_make_current(void *data, void *doit)
42{
43 Outbuf *ob;
44
45 if (!(ob = data)) return EINA_FALSE;
46
47 if (doit)
48 {
49 if (!eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
50 ob->egl.surface[0], ob->egl.context[0]))
51 return EINA_FALSE;
52 }
53 else
54 {
55 if (!eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE,
56 EGL_NO_SURFACE, EGL_NO_CONTEXT))
57 return EINA_FALSE;
58 }
59
60 return EINA_TRUE;
61}
62
63static Eina_Bool
64_evas_outbuf_egl_setup(Outbuf *ob)
65{
66 int ctx_attr[3];
67 int cfg_attr[40];
68 int maj = 0, min = 0;
69 int ncfg = 0, n = 0;
70 const GLubyte *vendor, *renderer, *version, *glslversion;
71 Eina_Bool blacklist = EINA_FALSE;
72
73 /* setup gbm egl surface */
74 ctx_attr[0] = EGL_CONTEXT_CLIENT_VERSION;
75 ctx_attr[1] = 2;
76 ctx_attr[2] = EGL_NONE;
77
78 cfg_attr[n++] = EGL_SURFACE_TYPE;
79 cfg_attr[n++] = EGL_WINDOW_BIT;
80 cfg_attr[n++] = EGL_RED_SIZE;
81 cfg_attr[n++] = 1;
82 cfg_attr[n++] = EGL_GREEN_SIZE;
83 cfg_attr[n++] = 1;
84 cfg_attr[n++] = EGL_BLUE_SIZE;
85 cfg_attr[n++] = 1;
86 cfg_attr[n++] = EGL_ALPHA_SIZE;
87 if (ob->destination_alpha) cfg_attr[n++] = 1;
88 else cfg_attr[n++] = 0;
89 cfg_attr[n++] = EGL_RENDERABLE_TYPE;
90 cfg_attr[n++] = EGL_OPENGL_ES2_BIT;
91 cfg_attr[n++] = EGL_NONE;
92
93 ob->egl.disp = eglGetDisplay((EGLNativeDisplayType)(ob->gbm));
94 if (ob->egl.disp == EGL_NO_DISPLAY)
95 {
96 ERR("eglGetDisplay() fail. code=%#x", eglGetError());
97 return EINA_FALSE;
98 }
99
100 if (!eglInitialize(ob->egl.disp, &maj, &min))
101 {
102 ERR("eglInitialize() fail. code=%#x", eglGetError());
103 return EINA_FALSE;
104 }
105
106 eglBindAPI(EGL_OPENGL_ES_API);
107 if (eglGetError() != EGL_SUCCESS)
108 {
109 ERR("eglBindAPI() fail. code=%#x", eglGetError());
110 return EINA_FALSE;
111 }
112
113 if (!eglChooseConfig(ob->egl.disp, cfg_attr, &ob->egl.config,
114 1, &ncfg) || (ncfg != 1))
115 {
116 ERR("eglChooseConfig() fail. code=%#x", eglGetError());
117 return EINA_FALSE;
118 }
119
120 ob->egl.surface[0] =
121 eglCreateWindowSurface(ob->egl.disp, ob->egl.config,
122 (EGLNativeWindowType)ob->surface, NULL);
123 if (ob->egl.surface[0] == EGL_NO_SURFACE)
124 {
125 ERR("eglCreateWindowSurface() fail for %p. code=%#x",
126 ob->surface, eglGetError());
127 return EINA_FALSE;
128 }
129
130 ob->egl.context[0] =
131 eglCreateContext(ob->egl.disp, ob->egl.config, context, ctx_attr);
132 if (ob->egl.context[0] == EGL_NO_CONTEXT)
133 {
134 ERR("eglCreateContext() fail. code=%#x", eglGetError());
135 return EINA_FALSE;
136 }
137
138 if (context == EGL_NO_CONTEXT) context = ob->egl.context[0];
139
140 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
141 ob->egl.surface[0], ob->egl.context[0]) == EGL_FALSE)
142 {
143 ERR("eglMakeCurrent() fail. code=%#x", eglGetError());
144 return EINA_FALSE;
145 }
146
147 vendor = glGetString(GL_VENDOR);
148 renderer = glGetString(GL_RENDERER);
149 version = glGetString(GL_VERSION);
150 glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION);
151 if (!vendor) vendor = (unsigned char *)"-UNKNOWN-";
152 if (!renderer) renderer = (unsigned char *)"-UNKNOWN-";
153 if (!version) version = (unsigned char *)"-UNKNOWN-";
154 if (!glslversion) glslversion = (unsigned char *)"-UNKNOWN-";
155 if (getenv("EVAS_GL_INFO"))
156 {
157 fprintf(stderr, "vendor : %s\n", vendor);
158 fprintf(stderr, "renderer: %s\n", renderer);
159 fprintf(stderr, "version : %s\n", version);
160 fprintf(stderr, "glsl ver: %s\n", glslversion);
161 }
162
163 if (strstr((const char *)vendor, "Mesa Project"))
164 {
165 if (strstr((const char *)renderer, "Software Rasterizer"))
166 blacklist = EINA_TRUE;
167 }
168 if (strstr((const char *)renderer, "softpipe"))
169 blacklist = EINA_TRUE;
170 if (strstr((const char *)renderer, "llvmpipe"))
171 blacklist = EINA_TRUE;
172
173 if ((blacklist) && (!getenv("EVAS_GL_NO_BLACKLIST")))
174 {
175 ERR("OpenGL Driver blacklisted:");
176 ERR("Vendor: %s", (const char *)vendor);
177 ERR("Renderer: %s", (const char *)renderer);
178 ERR("Version: %s", (const char *)version);
179 return EINA_FALSE;
180 }
181
182 ob->gl_context = glsym_evas_gl_common_context_new();
183 if (!ob->gl_context) return EINA_FALSE;
184
185#ifdef GL_GLES
186 ob->gl_context->egldisp = ob->egl.disp;
187 ob->gl_context->eglctxt = ob->egl.context[0];
188#endif
189
190 evas_outbuf_use(ob);
191 glsym_evas_gl_common_context_resize(ob->gl_context,
192 ob->w, ob->h, ob->rotation);
193
194 ob->surf = EINA_TRUE;
195
196 return EINA_TRUE;
197}
198
199Outbuf *
200evas_outbuf_new(Evas_Engine_Info_GL_Drm *info, int w, int h, Render_Engine_Swap_Mode swap_mode)
201{
202 Outbuf *ob;
203 char *num;
204 int i = 0;
205
206 /* try to allocate space for outbuf */
207 if (!(ob = calloc(1, sizeof(Outbuf)))) return NULL;
208
209 win_count++;
210
211 ob->w = w;
212 ob->h = h;
213 ob->info = info;
214 ob->depth = info->info.depth;
215 ob->rotation = info->info.rotation;
216 ob->destination_alpha = info->info.destination_alpha;
217 ob->vsync = info->info.vsync;
218 ob->gbm = info->info.gbm;
219 ob->surface = info->info.surface;
220 ob->swap_mode = swap_mode;
221 ob->priv.num = 2;
222
223 if ((num = getenv("EVAS_GL_DRM_BUFFERS")))
224 {
225 ob->priv.num = atoi(num);
226 if (ob->priv.num <= 0) ob->priv.num = 1;
227 else if (ob->priv.num > 4) ob->priv.num = 4;
228 }
229
230 if ((num = getenv("EVAS_GL_DRM_VSYNC")))
231 ob->vsync = atoi(num);
232
233 if (!_evas_outbuf_egl_setup(ob))
234 {
235 evas_outbuf_free(ob);
236 return NULL;
237 }
238
239 for (; i < ob->priv.num; i++)
240 {
241 ob->priv.buffer[i] =
242 ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h);
243 if (!ob->priv.buffer[i]) break;
244
245 DBG("Evas Engine Created Dumb Buffer");
246 DBG("\tFb: %d", ob->priv.buffer[i]->id);
247 DBG("\tHandle: %d", ob->priv.buffer[i]->hdl);
248 DBG("\tStride: %d", ob->priv.buffer[i]->stride);
249 DBG("\tSize: %d", ob->priv.buffer[i]->size);
250 DBG("\tW: %d\tH: %d",
251 ob->priv.buffer[i]->w, ob->priv.buffer[i]->h);
252 }
253
254 ecore_drm_fb_set(info->info.dev, ob->priv.buffer[0]);
255
256 return ob;
257}
258
259void
260evas_outbuf_free(Outbuf *ob)
261{
262 int i = 0, ref = 0;
263
264 win_count--;
265 evas_outbuf_use(ob);
266
267 if (ob == _evas_gl_drm_window) _evas_gl_drm_window = NULL;
268
269 if (ob->gl_context)
270 {
271 ref = ob->gl_context->references - 1;
272 glsym_evas_gl_common_context_free(ob->gl_context);
273 }
274
275 eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
276
277 if (ob->egl.context[0] != context)
278 eglDestroyContext(ob->egl.disp, ob->egl.context[0]);
279
280 if (ob->egl.surface[0] != EGL_NO_SURFACE)
281 eglDestroySurface(ob->egl.disp, ob->egl.surface[0]);
282
283//#if 0
284 if (ob->surface)
285 {
286 gbm_surface_destroy(ob->surface);
287 ob->info->info.surface = NULL;
288 }
289//#endif
290
291 if (ref == 0)
292 {
293 if (context) eglDestroyContext(ob->egl.disp, context);
294 eglTerminate(ob->egl.disp);
295 eglReleaseThread();
296 context = EGL_NO_CONTEXT;
297 }
298
299 for (; i < ob->priv.num; i++)
300 ecore_drm_fb_destroy(ob->priv.buffer[i]);
301
302 free(ob);
303}
304
305void
306evas_outbuf_use(Outbuf *ob)
307{
308 Eina_Bool force = EINA_FALSE;
309
310 glsym_evas_gl_preload_render_lock(_evas_outbuf_make_current, ob);
311
312 if (_evas_gl_drm_window)
313 {
314 if (eglGetCurrentContext() != _evas_gl_drm_window->egl.context[0])
315 force = EINA_TRUE;
316 }
317
318 if ((_evas_gl_drm_window != ob) || (force))
319 {
320 if (_evas_gl_drm_window)
321 {
322 glsym_evas_gl_common_context_use(_evas_gl_drm_window->gl_context);
323 glsym_evas_gl_common_context_flush(_evas_gl_drm_window->gl_context);
324 }
325
326 _evas_gl_drm_window = ob;
327
328 if (ob)
329 {
330 if (ob->egl.surface[0] != EGL_NO_SURFACE)
331 {
332 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
333 ob->egl.surface[0],
334 ob->egl.context[0]) == EGL_FALSE)
335 ERR("eglMakeCurrent() failed!");
336 }
337 }
338 }
339
340 if (ob) glsym_evas_gl_common_context_use(ob->gl_context);
341}
342
343void
344evas_outbuf_resurf(Outbuf *ob)
345{
346 if (ob->surf) return;
347 if (getenv("EVAS_GL_INFO")) printf("resurf %p\n", ob);
348
349 ob->egl.surface[0] =
350 eglCreateWindowSurface(ob->egl.disp, ob->egl.config,
351 (EGLNativeWindowType)ob->surface, NULL);
352
353 if (ob->egl.surface[0] == EGL_NO_SURFACE)
354 {
355 ERR("eglCreateWindowSurface() fail for %p. code=%#x",
356 ob->surface, eglGetError());
357 return;
358 }
359
360 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0], ob->egl.surface[0],
361 ob->egl.context[0]) == EGL_FALSE)
362 ERR("eglMakeCurrent() failed!");
363
364 ob->surf = EINA_TRUE;
365}
366
367void
368evas_outbuf_unsurf(Outbuf *ob)
369{
370 if (!ob->surf) return;
371 if (!getenv("EVAS_GL_WIN_RESURF")) return;
372 if (getenv("EVAS_GL_INFO")) printf("unsurf %p\n", ob);
373
374 if (_evas_gl_drm_window)
375 glsym_evas_gl_common_context_flush(_evas_gl_drm_window->gl_context);
376 if (_evas_gl_drm_window == ob)
377 {
378 eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE,
379 EGL_NO_SURFACE, EGL_NO_CONTEXT);
380 if (ob->egl.surface[0] != EGL_NO_SURFACE)
381 eglDestroySurface(ob->egl.disp, ob->egl.surface[0]);
382 ob->egl.surface[0] = EGL_NO_SURFACE;
383
384 _evas_gl_drm_window = NULL;
385 }
386
387 ob->surf = EINA_FALSE;
388}
389
390void
391evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth)
392{
393 int i = 0;
394
395 if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth;
396
397 /* check for changes */
398 if ((ob->w == w) && (ob->h == h) &&
399 (ob->destination_alpha == ob->info->info.destination_alpha) &&
400 ((int)ob->rotation == rot) && (ob->depth == depth))
401 return;
402
403 ob->w = w;
404 ob->h = h;
405 ob->depth = depth;
406 ob->rotation = rot;
407
408 /* destroy the old buffers */
409 for (; i < ob->priv.num; i++)
410 ecore_drm_fb_destroy(ob->priv.buffer[i]);
411
412 for (i = 0; i < ob->priv.num; i++)
413 {
414 ob->priv.buffer[i] =
415 ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h);
416 if (!ob->priv.buffer[i])
417 {
418 ERR("Failed to create buffer %d", i);
419 break;
420 }
421 }
422
423 evas_outbuf_use(ob);
424
425 glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot);
426
427 //TODO: need drm gbm surface destroy & re-create.?
428}
429
430Render_Engine_Swap_Mode
431evas_outbuf_buffer_state_get(Outbuf *ob)
432{
433 if (ob->swap_mode == MODE_AUTO && _extn_have_buffer_age)
434 {
435 Render_Engine_Swap_Mode swap_mode;
436 EGLint age = 0;
437
438 if (!eglQuerySurface(ob->egl.disp, ob->egl.surface[0],
439 EGL_BUFFER_AGE_EXT, &age))
440 age = 0;
441
442 if (age == 1) swap_mode = MODE_COPY;
443 else if (age == 2) swap_mode = MODE_DOUBLE;
444 else if (age == 3) swap_mode = MODE_TRIPLE;
445 else if (age == 4) swap_mode = MODE_QUADRUPLE;
446 else swap_mode = MODE_FULL;
447 if ((int)age != ob->priv.prev_age) swap_mode = MODE_FULL;
448 ob->priv.prev_age = age;
449
450 return swap_mode;
451 }
452
453 return ob->swap_mode;
454}
455
456int
457evas_outbuf_rot_get(Outbuf *ob)
458{
459 return ob->rotation;
460}
461
462Eina_Bool
463evas_outbuf_update_region_first_rect(Outbuf *ob)
464{
465 ob->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM;
466
467 glsym_evas_gl_preload_render_lock(_evas_outbuf_make_current, ob);
468 evas_outbuf_use(ob);
469
470 if (!_re_wincheck(ob)) return EINA_TRUE;
471
472 glsym_evas_gl_common_context_resize(ob->gl_context, ob->w, ob->h, ob->rotation);
473 glsym_evas_gl_common_context_flush(ob->gl_context);
474 glsym_evas_gl_common_context_newframe(ob->gl_context);
475
476 return EINA_FALSE;
477}
478
479void *
480evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx EINA_UNUSED, int *cy EINA_UNUSED, int *cw EINA_UNUSED, int *ch EINA_UNUSED)
481{
482 if ((w == ob->w) && (h == ob->h))
483 ob->gl_context->master_clip.enabled = EINA_FALSE;
484 else
485 {
486 ob->gl_context->master_clip.enabled = EINA_TRUE;
487 ob->gl_context->master_clip.x = x;
488 ob->gl_context->master_clip.y = y;
489 ob->gl_context->master_clip.w = w;
490 ob->gl_context->master_clip.h = h;
491 }
492
493 return ob->gl_context->def_surface;
494}
495
496void
497evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED)
498{
499 /* Is it really necessary to flush per region ? Shouldn't we be able to
500 still do that for the full canvas when doing partial update */
501 if (!_re_wincheck(ob)) return;
502 ob->drew = EINA_TRUE;
503 glsym_evas_gl_common_context_flush(ob->gl_context);
504}
505
506void
507evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
508{
509 /* Nothing to do here as we don't really create an image per area */
510}
511
512void
513evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode)
514{
515 if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end;
516
517 if (!_re_wincheck(ob)) goto end;
518 if (!ob->drew) goto end;
519
520 ob->drew = EINA_FALSE;
521 evas_outbuf_use(ob);
522 glsym_evas_gl_common_context_done(ob->gl_context);
523
524 if (!ob->vsync)
525 {
526 if (ob->info->info.vsync) eglSwapInterval(ob->egl.disp, 1);
527 else eglSwapInterval(ob->egl.disp, 0);
528 ob->vsync = 1;
529 }
530
531 /* if (ob->info->callback.pre_swap) */
532 /* ob->info->callback.pre_swap(ob->info->callback.data, ob->evas); */
533
534// TODO: Check eglSwapBuffersWithDamage for gl_drm and apply
535#if 0
536 if ((glsym_eglSwapBuffersWithDamage) && (ob->swap_mode != MODE_FULL))
537 {
538 EGLint num = 0, *result = NULL, i = 0;
539 Tilebuf_Rect *r;
540
541 // if partial swaps can be done use re->rects
542 num = eina_inlist_count(EINA_INLIST_GET(rects));
543 if (num > 0)
544 {
545 result = alloca(sizeof(EGLint) * 4 * num);
546 EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
547 {
548 int gw, gh;
549
550 gw = ob->gl_context->w;
551 gh = ob->gl_context->h;
552 switch (ob->rot)
553 {
554 case 0:
555 result[i + 0] = r->x;
556 result[i + 1] = gh - (r->y + r->h);
557 result[i + 2] = r->w;
558 result[i + 3] = r->h;
559 break;
560 case 90:
561 result[i + 0] = r->y;
562 result[i + 1] = r->x;
563 result[i + 2] = r->h;
564 result[i + 3] = r->w;
565 break;
566 case 180:
567 result[i + 0] = gw - (r->x + r->w);
568 result[i + 1] = r->y;
569 result[i + 2] = r->w;
570 result[i + 3] = r->h;
571 break;
572 case 270:
573 result[i + 0] = gh - (r->y + r->h);
574 result[i + 1] = gw - (r->x + r->w);
575 result[i + 2] = r->h;
576 result[i + 3] = r->w;
577 break;
578 default:
579 result[i + 0] = r->x;
580 result[i + 1] = gh - (r->y + r->h);
581 result[i + 2] = r->w;
582 result[i + 3] = r->h;
583 break;
584 }
585 i += 4;
586 }
587 glsym_eglSwapBuffersWithDamage(ob->egl.disp, ob->egl.surface[0],
588 result, num);
589 }
590 }
591 else
592#endif
593 eglSwapBuffers(ob->egl.disp, ob->egl.surface[0]);
594
595 /* if (ob->info->callback.post_swap) */
596 /* ob->info->callback.post_swap(ob->info->callback.data, ob->evas); */
597
598 //Flush GL Surface data to Framebuffer
599 _evas_outbuf_buffer_swap(ob, NULL, 0);
600
601 ob->priv.frame_cnt++;
602
603 end:
604 //TODO: Need render unlock after drm page flip?
605 glsym_evas_gl_preload_render_unlock(_evas_outbuf_make_current, ob);
606}
607
608Evas_Engine_GL_Context *
609evas_outbuf_gl_context_get(Outbuf *ob)
610{
611 return ob->gl_context;
612}
613
614void *
615evas_outbuf_egl_display_get(Outbuf *ob)
616{
617 return ob->egl.disp;
618}
619
620Context_3D *
621evas_outbuf_gl_context_new(Outbuf *ob)
622{
623 Context_3D *ctx;
624 int context_attrs[3] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
625
626 if (!ob) return NULL;
627
628 ctx = calloc(1, sizeof(Context_3D));
629 if (!ctx) return NULL;
630
631 ctx->context = eglCreateContext(ob->egl.disp, ob->egl.config,
632 ob->egl.context[0], context_attrs);
633
634 if (!ctx->context)
635 {
636 ERR("EGL context creation failed.");
637 goto error;
638 }
639
640 ctx->display = ob->egl.disp;
641 ctx->surface = ob->egl.surface[0];
642
643 return ctx;
644
645error:
646 free(ctx);
647 return NULL;
648}
649
650void
651evas_outbuf_gl_context_use(Context_3D *ctx)
652{
653 if (eglMakeCurrent(ctx->display, ctx->surface,
654 ctx->surface, ctx->context) == EGL_FALSE)
655 ERR("eglMakeCurrent() failed.");
656}