1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "HostConnection.h"
17 #include "ThreadInfo.h"
18 #include "eglDisplay.h"
19 #include "egl_ftable.h"
20 #include <cutils/log.h>
21 #include "gralloc_cb.h"
22 #include "GLClientState.h"
23 #include "GLSharedGroup.h"
24 #include "eglContext.h"
25 #include "ClientAPIExts.h"
26
27 #include "GLEncoder.h"
28 #ifdef WITH_GLES2
29 #include "GL2Encoder.h"
30 #endif
31
32 #include <private/ui/android_natives_priv.h>
33
34 template<typename T>
setErrorFunc(GLint error,T returnValue)35 static T setErrorFunc(GLint error, T returnValue) {
36 getEGLThreadInfo()->eglError = error;
37 return returnValue;
38 }
39
eglStrError(EGLint err)40 const char * eglStrError(EGLint err)
41 {
42 switch (err){
43 case EGL_SUCCESS: return "EGL_SUCCESS";
44 case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
45 case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
46 case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
47 case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
48 case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
49 case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
50 case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
51 case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
52 case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
53 case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
54 case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
55 case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
56 case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
57 case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
58 default: return "UNKNOWN";
59 }
60 }
61
62 #define LOG_EGL_ERRORS 1
63
64 #ifdef LOG_EGL_ERRORS
65
66 #define setErrorReturn(error, retVal) \
67 { \
68 LOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, error, eglStrError(error)); \
69 return setErrorFunc(error, retVal); \
70 }
71
72 #define RETURN_ERROR(ret,err) \
73 LOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, err, eglStrError(err)); \
74 getEGLThreadInfo()->eglError = err; \
75 return ret;
76
77 #else //!LOG_EGL_ERRORS
78
79 #define setErrorReturn(error, retVal) return setErrorFunc(error, retVal);
80
81 #define RETURN_ERROR(ret,err) \
82 getEGLThreadInfo()->eglError = err; \
83 return ret;
84
85 #endif //LOG_EGL_ERRORS
86
87 #define VALIDATE_CONFIG(cfg,ret) \
88 if(((int)cfg<0)||((int)cfg>s_display.getNumConfigs())) { \
89 RETURN_ERROR(ret,EGL_BAD_CONFIG); \
90 }
91
92 #define VALIDATE_DISPLAY(dpy,ret) \
93 if ((dpy) != (EGLDisplay)&s_display) { \
94 RETURN_ERROR(ret, EGL_BAD_DISPLAY); \
95 }
96
97 #define VALIDATE_DISPLAY_INIT(dpy,ret) \
98 VALIDATE_DISPLAY(dpy, ret) \
99 if (!s_display.initialized()) { \
100 RETURN_ERROR(ret, EGL_NOT_INITIALIZED); \
101 }
102
103 #define DEFINE_HOST_CONNECTION \
104 HostConnection *hostCon = HostConnection::get(); \
105 renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
106
107 #define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \
108 HostConnection *hostCon = HostConnection::get(); \
109 if (!hostCon) { \
110 LOGE("egl: Failed to get host connection\n"); \
111 return ret; \
112 } \
113 renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
114 if (!rcEnc) { \
115 LOGE("egl: Failed to get renderControl encoder context\n"); \
116 return ret; \
117 }
118
119 #define VALIDATE_CONTEXT_RETURN(context,ret) \
120 if (!context) { \
121 RETURN_ERROR(ret,EGL_BAD_CONTEXT); \
122 }
123
124 #define VALIDATE_SURFACE_RETURN(surface, ret) \
125 if (surface != EGL_NO_SURFACE) { \
126 egl_surface_t* s( static_cast<egl_surface_t*>(surface) ); \
127 if (!s->isValid()) \
128 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); \
129 if (s->dpy != (EGLDisplay)&s_display) \
130 setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); \
131 }
132
133
EGLContext_t(EGLDisplay dpy,EGLConfig config,EGLContext_t * shareCtx)134 EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx) :
135 dpy(dpy),
136 config(config),
137 read(EGL_NO_SURFACE),
138 draw(EGL_NO_SURFACE),
139 shareCtx(shareCtx),
140 rcContext(0),
141 versionString(NULL),
142 vendorString(NULL),
143 rendererString(NULL),
144 extensionString(NULL)
145 {
146 flags = 0;
147 version = 1;
148 clientState = new GLClientState();
149 if (shareCtx) sharedGroup = shareCtx->getSharedGroup();
150 else sharedGroup = GLSharedGroupPtr(new GLSharedGroup());
151 };
152
~EGLContext_t()153 EGLContext_t::~EGLContext_t()
154 {
155 delete clientState;
156 delete [] versionString;
157 delete [] vendorString;
158 delete [] rendererString;
159 delete [] extensionString;
160 }
161
162 // ----------------------------------------------------------------------------
163 //egl_surface_t
164
165 //we don't need to handle depth since it's handled when window created on the host
166
167 struct egl_surface_t {
168
169 EGLDisplay dpy;
170 EGLConfig config;
171
172
173 egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType);
174 virtual ~egl_surface_t();
175
176 virtual EGLBoolean rcCreate() = 0;
177 virtual EGLBoolean rcDestroy() = 0;
178
connectegl_surface_t179 virtual EGLBoolean connect() { return EGL_TRUE; }
disconnectegl_surface_t180 virtual void disconnect() {}
swapBuffersegl_surface_t181 virtual EGLBoolean swapBuffers() { return EGL_TRUE; }
182 virtual EGLint getSwapBehavior() const;
183
setRcSurfaceegl_surface_t184 void setRcSurface(uint32_t handle){ rcSurface = handle; }
getRcSurfaceegl_surface_t185 uint32_t getRcSurface(){ return rcSurface; }
186
isValidegl_surface_t187 virtual EGLBoolean isValid(){ return valid; }
getSurfaceTypeegl_surface_t188 EGLint getSurfaceType(){ return surfaceType; }
189
setWidthegl_surface_t190 void setWidth(EGLint w){ width = w; }
getWidthegl_surface_t191 EGLint getWidth(){ return width; }
setHeightegl_surface_t192 void setHeight(EGLint h){ height = h; }
getHeightegl_surface_t193 EGLint getHeight(){ return height; }
setTextureFormategl_surface_t194 void setTextureFormat(EGLint _texFormat){ texFormat = _texFormat; }
getTextureFormategl_surface_t195 EGLint getTextureFormat(){ return texFormat; }
setTextureTargetegl_surface_t196 void setTextureTarget(EGLint _texTarget){ texTarget = _texTarget; }
getTextureTargetegl_surface_t197 EGLint getTextureTarget(){ return texTarget; }
198
199 private:
200 //
201 //Surface attributes
202 //
203 EGLint width;
204 EGLint height;
205 EGLint texFormat;
206 EGLint texTarget;
207
208 protected:
209 EGLint surfaceType;
210 EGLBoolean valid;
211 uint32_t rcSurface; //handle to surface created via remote control
212
213
214 };
215
egl_surface_t(EGLDisplay dpy,EGLConfig config,EGLint surfaceType)216 egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType)
217 : dpy(dpy), config(config), surfaceType(surfaceType), valid(EGL_FALSE), rcSurface(0)
218 {
219 width = 0;
220 height = 0;
221 texFormat = EGL_NO_TEXTURE;
222 texTarget = EGL_NO_TEXTURE;
223 }
224
getSwapBehavior() const225 EGLint egl_surface_t::getSwapBehavior() const {
226 return EGL_BUFFER_PRESERVED;
227 }
228
~egl_surface_t()229 egl_surface_t::~egl_surface_t()
230 {
231 }
232
233 // ----------------------------------------------------------------------------
234 // egl_window_surface_t
235
236 struct egl_window_surface_t : public egl_surface_t {
237
238 egl_window_surface_t(
239 EGLDisplay dpy, EGLConfig config, EGLint surfType,
240 ANativeWindow* window);
241
242 ~egl_window_surface_t();
243
244 virtual EGLBoolean rcCreate();
245 virtual EGLBoolean rcDestroy();
246
247 virtual EGLBoolean connect();
248 virtual void disconnect();
249 virtual EGLBoolean swapBuffers();
250
251 private:
252 ANativeWindow* nativeWindow;
253 android_native_buffer_t* buffer;
254
255 };
256
257
egl_window_surface_t(EGLDisplay dpy,EGLConfig config,EGLint surfType,ANativeWindow * window)258 egl_window_surface_t::egl_window_surface_t (
259 EGLDisplay dpy, EGLConfig config, EGLint surfType,
260 ANativeWindow* window)
261 : egl_surface_t(dpy, config, surfType),
262 nativeWindow(window),
263 buffer(NULL)
264 {
265 // keep a reference on the window
266 nativeWindow->common.incRef(&nativeWindow->common);
267 EGLint w,h;
268 nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &w);
269 setWidth(w);
270 nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &h);
271 setHeight(h);
272 }
273
~egl_window_surface_t()274 egl_window_surface_t::~egl_window_surface_t() {
275 nativeWindow->common.decRef(&nativeWindow->common);
276 }
277
rcCreate()278 EGLBoolean egl_window_surface_t::rcCreate()
279 {
280 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
281 rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, getWidth(), getHeight());
282 if (!rcSurface) {
283 LOGE("rcCreateWindowSurface returned 0");
284 return EGL_FALSE;
285 }
286 valid = EGL_TRUE;
287 return EGL_TRUE;
288 }
289
rcDestroy()290 EGLBoolean egl_window_surface_t::rcDestroy()
291 {
292 if (!rcSurface) {
293 LOGE("rcDestroy called on invalid rcSurface");
294 return EGL_FALSE;
295 }
296
297 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
298 rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
299 rcSurface = 0;
300
301 return EGL_TRUE;
302 }
303
connect()304 EGLBoolean egl_window_surface_t::connect()
305 {
306 // dequeue a buffer
307 if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) {
308 setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
309 }
310
311 buffer->common.incRef(&buffer->common);
312
313 // lock the buffer
314 nativeWindow->lockBuffer(nativeWindow, buffer);
315
316 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
317 rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, ((cb_handle_t *)(buffer->handle))->hostHandle);
318
319 return EGL_TRUE;
320 }
321
disconnect()322 void egl_window_surface_t::disconnect()
323 {
324 if (buffer) {
325 nativeWindow->queueBuffer(nativeWindow, buffer);
326 buffer->common.decRef(&buffer->common);
327 buffer = 0;
328 }
329 }
330
swapBuffers()331 EGLBoolean egl_window_surface_t::swapBuffers()
332 {
333 if (!buffer) {
334 setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE);
335 }
336
337 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
338
339 rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface);
340
341 android_native_buffer_t* prevBuf = buffer;
342 //post the back buffer
343 nativeWindow->queueBuffer(nativeWindow, buffer);
344
345 buffer->common.incRef(&buffer->common);
346
347 if (prevBuf) {
348 prevBuf->common.decRef(&prevBuf->common);
349 }
350
351 // dequeue a new buffer
352 if (nativeWindow->dequeueBuffer(nativeWindow, &buffer)) {
353 setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
354 }
355
356 // lock the buffer
357 nativeWindow->lockBuffer(nativeWindow, buffer);
358
359 rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, ((cb_handle_t *)(buffer->handle))->hostHandle);
360
361 return EGL_TRUE;
362 }
363
364 // ----------------------------------------------------------------------------
365 //egl_pbuffer_surface_t
366
367 struct egl_pbuffer_surface_t : public egl_surface_t {
368
369 GLenum format;
370
371 egl_pbuffer_surface_t(
372 EGLDisplay dpy, EGLConfig config, EGLint surfType,
373 int32_t w, int32_t h, GLenum format);
374
375 virtual ~egl_pbuffer_surface_t();
376 virtual EGLBoolean rcCreate();
377 virtual EGLBoolean rcDestroy();
378
379 virtual EGLBoolean connect();
380
getRcColorBufferegl_pbuffer_surface_t381 uint32_t getRcColorBuffer(){ return rcColorBuffer; }
setRcColorBufferegl_pbuffer_surface_t382 void setRcColorBuffer(uint32_t colorBuffer){ rcColorBuffer = colorBuffer; }
383 private:
384 uint32_t rcColorBuffer;
385 };
386
egl_pbuffer_surface_t(EGLDisplay dpy,EGLConfig config,EGLint surfType,int32_t w,int32_t h,GLenum pixelFormat)387 egl_pbuffer_surface_t::egl_pbuffer_surface_t(
388 EGLDisplay dpy, EGLConfig config, EGLint surfType,
389 int32_t w, int32_t h, GLenum pixelFormat)
390 : egl_surface_t(dpy, config, surfType), format(pixelFormat)
391 {
392 setWidth(w);
393 setHeight(h);
394 }
395
~egl_pbuffer_surface_t()396 egl_pbuffer_surface_t::~egl_pbuffer_surface_t()
397 {
398 rcColorBuffer = 0;
399 }
400
rcCreate()401 EGLBoolean egl_pbuffer_surface_t::rcCreate()
402 {
403 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
404 rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, getWidth(), getHeight());
405 if (!rcSurface) {
406 LOGE("rcCreateWindowSurface returned 0");
407 return EGL_FALSE;
408 }
409 rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(), format);
410 if (!rcColorBuffer) {
411 LOGE("rcCreateColorBuffer returned 0");
412 return EGL_FALSE;
413 }
414
415 valid = EGL_TRUE;
416 return EGL_TRUE;
417 }
418
rcDestroy()419 EGLBoolean egl_pbuffer_surface_t::rcDestroy()
420 {
421 if ((!rcSurface)||(!rcColorBuffer)) {
422 LOGE("destroyRc called on invalid rcSurface");
423 return EGL_FALSE;
424 }
425
426 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
427 rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
428 rcEnc->rcDestroyColorBuffer(rcEnc, rcColorBuffer);
429 rcSurface = 0;
430
431 return EGL_TRUE;
432 }
433
connect()434 EGLBoolean egl_pbuffer_surface_t::connect()
435 {
436 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
437 rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, rcColorBuffer);
438
439 return EGL_TRUE;
440 }
441
getGLString(int glEnum)442 static const char *getGLString(int glEnum)
443 {
444 EGLThreadInfo *tInfo = getEGLThreadInfo();
445 if (!tInfo || !tInfo->currentContext) {
446 return NULL;
447 }
448
449 const char** strPtr = NULL;
450
451 #define GL_VENDOR 0x1F00
452 #define GL_RENDERER 0x1F01
453 #define GL_VERSION 0x1F02
454 #define GL_EXTENSIONS 0x1F03
455
456 switch(glEnum) {
457 case GL_VERSION:
458 strPtr = &tInfo->currentContext->versionString;
459 break;
460 case GL_VENDOR:
461 strPtr = &tInfo->currentContext->vendorString;
462 break;
463 case GL_RENDERER:
464 strPtr = &tInfo->currentContext->rendererString;
465 break;
466 case GL_EXTENSIONS:
467 strPtr = &tInfo->currentContext->extensionString;
468 break;
469 }
470
471 if (!strPtr) {
472 return NULL;
473 }
474
475 if (*strPtr != NULL) {
476 //
477 // string is already cached
478 //
479 return *strPtr;
480 }
481
482 //
483 // first query of that string - need to query host
484 //
485 DEFINE_AND_VALIDATE_HOST_CONNECTION(NULL);
486 char *hostStr = NULL;
487 int n = rcEnc->rcGetGLString(rcEnc, glEnum, NULL, 0);
488 if (n < 0) {
489 hostStr = new char[-n+1];
490 n = rcEnc->rcGetGLString(rcEnc, glEnum, hostStr, -n);
491 if (n <= 0) {
492 delete [] hostStr;
493 hostStr = NULL;
494 }
495 }
496
497 //
498 // keep the string in the context and return its value
499 //
500 *strPtr = hostStr;
501 return hostStr;
502 }
503
504 // ----------------------------------------------------------------------------
505
506 // The one and only supported display object.
507 static eglDisplay s_display;
508
509 static EGLClient_eglInterface s_eglIface = {
510 getThreadInfo: getEGLThreadInfo,
511 getGLString: getGLString
512 };
513
514 #define DBG_FUNC DBG("%s\n", __FUNCTION__)
eglGetDisplay(EGLNativeDisplayType display_id)515 EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
516 {
517 //
518 // we support only EGL_DEFAULT_DISPLAY.
519 //
520 if (display_id != EGL_DEFAULT_DISPLAY) {
521 return EGL_NO_DISPLAY;
522 }
523
524 return (EGLDisplay)&s_display;
525 }
526
eglInitialize(EGLDisplay dpy,EGLint * major,EGLint * minor)527 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
528 {
529 VALIDATE_DISPLAY(dpy,EGL_FALSE);
530
531 if (!s_display.initialize(&s_eglIface)) {
532 return EGL_FALSE;
533 }
534 if (major!=NULL)
535 *major = s_display.getVersionMajor();
536 if (minor!=NULL)
537 *minor = s_display.getVersionMinor();
538 return EGL_TRUE;
539 }
540
eglTerminate(EGLDisplay dpy)541 EGLBoolean eglTerminate(EGLDisplay dpy)
542 {
543 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
544
545 s_display.terminate();
546 return EGL_TRUE;
547 }
548
eglGetError()549 EGLint eglGetError()
550 {
551 EGLint error = getEGLThreadInfo()->eglError;
552 getEGLThreadInfo()->eglError = EGL_SUCCESS;
553 return error;
554 }
555
eglGetProcAddress(const char * procname)556 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
557 {
558 // search in EGL function table
559 for (int i=0; i<egl_num_funcs; i++) {
560 if (!strcmp(egl_funcs_by_name[i].name, procname)) {
561 return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc;
562 }
563 }
564
565 //
566 // Make sure display is initialized before searching in client APIs
567 //
568 if (!s_display.initialized()) {
569 if (!s_display.initialize(&s_eglIface)) {
570 return NULL;
571 }
572 }
573
574 // look in gles client api's extensions table
575 return (__eglMustCastToProperFunctionPointerType)ClientAPIExts::getProcAddress(procname);
576
577 // Fail - function not found.
578 return NULL;
579 }
580
eglQueryString(EGLDisplay dpy,EGLint name)581 const char* eglQueryString(EGLDisplay dpy, EGLint name)
582 {
583 VALIDATE_DISPLAY_INIT(dpy, NULL);
584
585 return s_display.queryString(name);
586 }
587
eglGetConfigs(EGLDisplay dpy,EGLConfig * configs,EGLint config_size,EGLint * num_config)588 EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
589 {
590 VALIDATE_DISPLAY_INIT(dpy, NULL);
591
592 if(!num_config) {
593 RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
594 }
595
596 GLint numConfigs = s_display.getNumConfigs();
597 if (!configs) {
598 *num_config = numConfigs;
599 return EGL_TRUE;
600 }
601
602 int i=0;
603 for (i=0 ; i<numConfigs && i<config_size ; i++) {
604 *configs++ = (EGLConfig)i;
605 }
606 *num_config = i;
607 return EGL_TRUE;
608 }
609
eglChooseConfig(EGLDisplay dpy,const EGLint * attrib_list,EGLConfig * configs,EGLint config_size,EGLint * num_config)610 EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
611 {
612 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
613
614 int attribs_size = 0;
615 if (attrib_list) {
616 const EGLint * attrib_p = attrib_list;
617 while (attrib_p[0] != EGL_NONE) {
618 attribs_size += 2;
619 attrib_p += 2;
620 }
621 attribs_size++; //for the terminating EGL_NONE
622 }
623
624 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
625 *num_config = rcEnc->rcChooseConfig(rcEnc, (EGLint*)attrib_list, attribs_size * sizeof(EGLint), (uint32_t*)configs, config_size);
626
627 return EGL_TRUE;
628 }
629
eglGetConfigAttrib(EGLDisplay dpy,EGLConfig config,EGLint attribute,EGLint * value)630 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
631 {
632 VALIDATE_DISPLAY_INIT(dpy, NULL);
633 VALIDATE_CONFIG(config, EGL_FALSE);
634
635 if (s_display.getConfigAttrib(config, attribute, value))
636 {
637 return EGL_TRUE;
638 }
639 else
640 {
641 RETURN_ERROR(EGL_FALSE, EGL_BAD_ATTRIBUTE);
642 }
643 }
644
eglCreateWindowSurface(EGLDisplay dpy,EGLConfig config,EGLNativeWindowType win,const EGLint * attrib_list)645 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
646 {
647 VALIDATE_DISPLAY_INIT(dpy, NULL);
648 VALIDATE_CONFIG(config, EGL_FALSE);
649 if (win == 0) {
650 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
651 }
652
653 EGLint surfaceType;
654 if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE;
655
656 if (!(surfaceType & EGL_WINDOW_BIT)) {
657 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
658 }
659
660 if (static_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
661 setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
662 }
663
664 egl_surface_t* surface;
665 surface = new egl_window_surface_t(&s_display, config, surfaceType, static_cast<ANativeWindow*>(win));
666 if (!surface)
667 setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
668 if (!surface->rcCreate()) {
669 delete surface;
670 setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
671 }
672
673 return surface;
674 }
675
eglCreatePbufferSurface(EGLDisplay dpy,EGLConfig config,const EGLint * attrib_list)676 EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
677 {
678 VALIDATE_DISPLAY_INIT(dpy, NULL);
679 VALIDATE_CONFIG(config, EGL_FALSE);
680
681 EGLint surfaceType;
682 if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE;
683
684 if (!(surfaceType & EGL_PBUFFER_BIT)) {
685 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
686 }
687
688 int32_t w = 0;
689 int32_t h = 0;
690 EGLint texFormat = EGL_NO_TEXTURE;
691 EGLint texTarget = EGL_NO_TEXTURE;
692 while (attrib_list[0]) {
693 switch (attrib_list[0]) {
694 case EGL_WIDTH:
695 w = attrib_list[1];
696 break;
697 case EGL_HEIGHT:
698 h = attrib_list[1];
699 break;
700 case EGL_TEXTURE_FORMAT:
701 texFormat = attrib_list[1];
702 break;
703 case EGL_TEXTURE_TARGET:
704 texTarget = attrib_list[1];
705 break;
706 default:
707 break;
708 };
709 attrib_list+=2;
710 }
711 if (((texFormat == EGL_NO_TEXTURE)&&(texTarget != EGL_NO_TEXTURE)) ||
712 ((texFormat != EGL_NO_TEXTURE)&&(texTarget == EGL_NO_TEXTURE))) {
713 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
714 }
715 // TODO: check EGL_TEXTURE_FORMAT - need to support eglBindTexImage
716
717 GLenum pixelFormat;
718 if (s_display.getConfigGLPixelFormat(config, &pixelFormat) == EGL_FALSE)
719 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
720
721 egl_surface_t* surface = new egl_pbuffer_surface_t(dpy, config, surfaceType, w, h, pixelFormat);
722 if (!surface)
723 setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
724 if (!surface->rcCreate()) {
725 delete surface;
726 setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
727 }
728
729 //setup attributes
730 surface->setTextureFormat(texFormat);
731 surface->setTextureTarget(texTarget);
732
733 return surface;
734 }
735
eglCreatePixmapSurface(EGLDisplay dpy,EGLConfig config,EGLNativePixmapType pixmap,const EGLint * attrib_list)736 EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
737 {
738 //XXX: Pixmap not supported. The host cannot render to a pixmap resource
739 // located on host. In order to support Pixmaps we should either punt
740 // to s/w rendering -or- let the host render to a buffer that will be
741 // copied back to guest at some sync point. None of those methods not
742 // implemented and pixmaps are not used with OpenGL anyway ...
743 return EGL_NO_SURFACE;
744 }
745
eglDestroySurface(EGLDisplay dpy,EGLSurface eglSurface)746 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
747 {
748 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
749 VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
750
751 egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
752
753 surface->disconnect();
754 surface->rcDestroy();
755 delete surface;
756
757 return EGL_TRUE;
758 }
759
eglQuerySurface(EGLDisplay dpy,EGLSurface eglSurface,EGLint attribute,EGLint * value)760 EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribute, EGLint *value)
761 {
762 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
763 VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
764
765 egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
766 EGLBoolean ret = EGL_TRUE;
767 switch (attribute) {
768 case EGL_CONFIG_ID:
769 ret = s_display.getConfigAttrib(surface->config, EGL_CONFIG_ID, value);
770 break;
771 case EGL_WIDTH:
772 *value = surface->getWidth();
773 break;
774 case EGL_HEIGHT:
775 *value = surface->getHeight();
776 break;
777 case EGL_TEXTURE_FORMAT:
778 *value = surface->getTextureFormat();
779 break;
780 case EGL_TEXTURE_TARGET:
781 *value = surface->getTextureTarget();
782 break;
783 case EGL_SWAP_BEHAVIOR:
784 *value = surface->getSwapBehavior();
785 break;
786 case EGL_LARGEST_PBUFFER:
787 // not modified for a window or pixmap surface
788 // and we ignore it when creating a PBuffer surface (default is EGL_FALSE)
789 if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = EGL_FALSE;
790 break;
791 //TODO: complete other attributes
792 default:
793 LOGE("eglQuerySurface %x EGL_BAD_ATTRIBUTE", attribute);
794 ret = setErrorFunc(EGL_BAD_ATTRIBUTE, EGL_FALSE);
795 break;
796 }
797
798 return ret;
799 }
800
eglBindAPI(EGLenum api)801 EGLBoolean eglBindAPI(EGLenum api)
802 {
803 if (api != EGL_OPENGL_ES_API)
804 setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
805 return EGL_TRUE;
806 }
807
eglQueryAPI()808 EGLenum eglQueryAPI()
809 {
810 return EGL_OPENGL_ES_API;
811 }
812
eglWaitClient()813 EGLBoolean eglWaitClient()
814 {
815 return eglWaitGL();
816 }
817
eglReleaseThread()818 EGLBoolean eglReleaseThread()
819 {
820 EGLThreadInfo *tInfo = getEGLThreadInfo();
821 if (tInfo && tInfo->currentContext) {
822 return eglMakeCurrent(&s_display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
823 }
824 return EGL_TRUE;
825 }
826
eglCreatePbufferFromClientBuffer(EGLDisplay dpy,EGLenum buftype,EGLClientBuffer buffer,EGLConfig config,const EGLint * attrib_list)827 EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
828 {
829 //TODO
830 LOGW("%s not implemented", __FUNCTION__);
831 return 0;
832 }
833
eglSurfaceAttrib(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint value)834 EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
835 {
836 //TODO
837 LOGW("%s not implemented", __FUNCTION__);
838 return 0;
839 }
840
eglBindTexImage(EGLDisplay dpy,EGLSurface eglSurface,EGLint buffer)841 EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface eglSurface, EGLint buffer)
842 {
843 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
844 VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
845 if (eglSurface == EGL_NO_SURFACE) {
846 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
847 }
848
849 if (buffer != EGL_BACK_BUFFER) {
850 setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
851 }
852
853 egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
854
855 if (surface->getTextureFormat() == EGL_NO_TEXTURE) {
856 setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
857 }
858
859 if (!(surface->getSurfaceType() & EGL_PBUFFER_BIT)) {
860 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
861 }
862
863 //It's now safe to cast to pbuffer surface
864 egl_pbuffer_surface_t* pbSurface = (egl_pbuffer_surface_t*)surface;
865
866 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
867 rcEnc->rcBindTexture(rcEnc, pbSurface->getRcColorBuffer());
868
869 return GL_TRUE;
870 }
871
eglReleaseTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)872 EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
873 {
874 //TODO
875 LOGW("%s not implemented", __FUNCTION__);
876 return 0;
877 }
878
eglSwapInterval(EGLDisplay dpy,EGLint interval)879 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
880 {
881 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
882
883 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
884 rcEnc->rcFBSetSwapInterval(rcEnc, interval); //TODO: implement on the host
885 return EGL_TRUE;
886 }
887
eglCreateContext(EGLDisplay dpy,EGLConfig config,EGLContext share_context,const EGLint * attrib_list)888 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
889 {
890 VALIDATE_DISPLAY_INIT(dpy, EGL_NO_CONTEXT);
891 VALIDATE_CONFIG(config, EGL_NO_CONTEXT);
892
893 EGLint version = 1; //default
894 while (attrib_list && attrib_list[0]) {
895 if (attrib_list[0] == EGL_CONTEXT_CLIENT_VERSION) version = attrib_list[1];
896 attrib_list+=2;
897 }
898
899 uint32_t rcShareCtx = 0;
900 EGLContext_t * shareCtx = NULL;
901 if (share_context) {
902 shareCtx = static_cast<EGLContext_t*>(share_context);
903 rcShareCtx = shareCtx->rcContext;
904 if (shareCtx->dpy != dpy)
905 setErrorReturn(EGL_BAD_MATCH, EGL_NO_CONTEXT);
906 }
907
908 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT);
909 uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uint32_t)config, rcShareCtx, version);
910 if (!rcContext) {
911 LOGE("rcCreateContext returned 0");
912 setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
913 }
914
915 EGLContext_t * context = new EGLContext_t(dpy, config, shareCtx);
916 if (!context)
917 setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
918
919 context->version = version;
920 context->rcContext = rcContext;
921
922
923 return context;
924 }
925
eglDestroyContext(EGLDisplay dpy,EGLContext ctx)926 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
927 {
928 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
929 VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE);
930
931 EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
932
933 if (getEGLThreadInfo()->currentContext == context)
934 {
935 eglMakeCurrent(dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
936 }
937
938 if (context->rcContext) {
939 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
940 rcEnc->rcDestroyContext(rcEnc, context->rcContext);
941 context->rcContext = 0;
942 }
943
944 delete context;
945 return EGL_TRUE;
946 }
947
eglMakeCurrent(EGLDisplay dpy,EGLSurface draw,EGLSurface read,EGLContext ctx)948 EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
949 {
950 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
951 VALIDATE_SURFACE_RETURN(draw, EGL_FALSE);
952 VALIDATE_SURFACE_RETURN(read, EGL_FALSE);
953
954 if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT))
955 setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
956 if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT))
957 setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
958
959 EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
960 uint32_t ctxHandle = (context) ? context->rcContext : 0;
961 egl_surface_t * drawSurf = static_cast<egl_surface_t *>(draw);
962 uint32_t drawHandle = (drawSurf) ? drawSurf->getRcSurface() : 0;
963 egl_surface_t * readSurf = static_cast<egl_surface_t *>(read);
964 uint32_t readHandle = (readSurf) ? readSurf->getRcSurface() : 0;
965
966 //
967 // Nothing to do if no binding change has made
968 //
969 EGLThreadInfo *tInfo = getEGLThreadInfo();
970 if (tInfo->currentContext == context &&
971 (context == NULL ||
972 (context && context->draw == draw && context->read == read))) {
973 return EGL_TRUE;
974 }
975
976 if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) {
977 //context is current to another thread
978 setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE);
979 }
980
981 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
982 if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) {
983 LOGE("rcMakeCurrent returned EGL_FALSE");
984 setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE);
985 }
986
987 //
988 // Disconnect from the previous drawable
989 //
990 if (tInfo->currentContext && tInfo->currentContext->draw) {
991 egl_surface_t * prevDrawSurf = static_cast<egl_surface_t *>(tInfo->currentContext->draw);
992 prevDrawSurf->disconnect();
993 }
994
995 //Now make the local bind
996 if (context) {
997 context->draw = draw;
998 context->read = read;
999 context->flags |= EGLContext_t::IS_CURRENT;
1000 //set the client state
1001 if (context->version == 2) {
1002 hostCon->gl2Encoder()->setClientState(context->getClientState());
1003 hostCon->gl2Encoder()->setSharedGroup(context->getSharedGroup());
1004 }
1005 else {
1006 hostCon->glEncoder()->setClientState(context->getClientState());
1007 hostCon->glEncoder()->setSharedGroup(context->getSharedGroup());
1008 }
1009 }
1010 else {
1011 //release ClientState & SharedGroup
1012 if (tInfo->currentContext->version == 2) {
1013 hostCon->gl2Encoder()->setClientState(NULL);
1014 hostCon->gl2Encoder()->setSharedGroup(GLSharedGroupPtr(NULL));
1015 }
1016 else {
1017 hostCon->glEncoder()->setClientState(NULL);
1018 hostCon->glEncoder()->setSharedGroup(GLSharedGroupPtr(NULL));
1019 }
1020
1021 }
1022
1023 if (tInfo->currentContext)
1024 tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT;
1025
1026 //Now make current
1027 tInfo->currentContext = context;
1028
1029 //Check maybe we need to init the encoder, if it's first eglMakeCurrent
1030 if (tInfo->currentContext) {
1031 if (tInfo->currentContext->version == 2) {
1032 if (!hostCon->gl2Encoder()->isInitialized()) {
1033 s_display.gles2_iface()->init();
1034 hostCon->gl2Encoder()->setInitialized();
1035 ClientAPIExts::initClientFuncs(s_display.gles2_iface(), 1);
1036 }
1037 }
1038 else {
1039 if (!hostCon->glEncoder()->isInitialized()) {
1040 s_display.gles_iface()->init();
1041 hostCon->glEncoder()->setInitialized();
1042 ClientAPIExts::initClientFuncs(s_display.gles_iface(), 0);
1043 }
1044 }
1045 }
1046
1047 //connect the color buffer
1048 if (drawSurf)
1049 drawSurf->connect();
1050
1051 return EGL_TRUE;
1052 }
1053
eglGetCurrentContext()1054 EGLContext eglGetCurrentContext()
1055 {
1056 return getEGLThreadInfo()->currentContext;
1057 }
1058
eglGetCurrentSurface(EGLint readdraw)1059 EGLSurface eglGetCurrentSurface(EGLint readdraw)
1060 {
1061 EGLContext_t * context = getEGLThreadInfo()->currentContext;
1062 if (!context)
1063 return EGL_NO_SURFACE; //not an error
1064
1065 switch (readdraw) {
1066 case EGL_READ:
1067 return context->read;
1068 case EGL_DRAW:
1069 return context->draw;
1070 default:
1071 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
1072 }
1073 }
1074
eglGetCurrentDisplay()1075 EGLDisplay eglGetCurrentDisplay()
1076 {
1077 EGLContext_t * context = getEGLThreadInfo()->currentContext;
1078 if (!context)
1079 return EGL_NO_DISPLAY; //not an error
1080
1081 return context->dpy;
1082 }
1083
eglQueryContext(EGLDisplay dpy,EGLContext ctx,EGLint attribute,EGLint * value)1084 EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
1085 {
1086 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
1087 VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE);
1088
1089 EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
1090
1091 EGLBoolean ret = EGL_TRUE;
1092 switch (attribute) {
1093 case EGL_CONFIG_ID:
1094 ret = s_display.getConfigAttrib(context->config, EGL_CONFIG_ID, value);
1095 break;
1096 case EGL_CONTEXT_CLIENT_TYPE:
1097 *value = EGL_OPENGL_ES_API;
1098 break;
1099 case EGL_CONTEXT_CLIENT_VERSION:
1100 *value = context->version;
1101 break;
1102 case EGL_RENDER_BUFFER:
1103 if (!context->draw)
1104 *value = EGL_NONE;
1105 else
1106 *value = EGL_BACK_BUFFER; //single buffer not supported
1107 break;
1108 default:
1109 LOGE("eglQueryContext %x EGL_BAD_ATTRIBUTE", attribute);
1110 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE);
1111 break;
1112 }
1113
1114 return ret;
1115 }
1116
eglWaitGL()1117 EGLBoolean eglWaitGL()
1118 {
1119 EGLThreadInfo *tInfo = getEGLThreadInfo();
1120 if (!tInfo || !tInfo->currentContext) {
1121 return EGL_FALSE;
1122 }
1123
1124 if (tInfo->currentContext->version == 2) {
1125 s_display.gles2_iface()->finish();
1126 }
1127 else {
1128 s_display.gles_iface()->finish();
1129 }
1130
1131 return EGL_TRUE;
1132 }
1133
eglWaitNative(EGLint engine)1134 EGLBoolean eglWaitNative(EGLint engine)
1135 {
1136 return EGL_TRUE;
1137 }
1138
eglSwapBuffers(EGLDisplay dpy,EGLSurface eglSurface)1139 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface)
1140 {
1141 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
1142 if (eglSurface == EGL_NO_SURFACE)
1143 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
1144
1145 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
1146
1147 egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface);
1148 if (!d->isValid())
1149 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
1150 if (d->dpy != dpy)
1151 setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE);
1152
1153 // post the surface
1154 d->swapBuffers();
1155
1156 hostCon->flush();
1157 return EGL_TRUE;
1158 }
1159
eglCopyBuffers(EGLDisplay dpy,EGLSurface surface,EGLNativePixmapType target)1160 EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
1161 {
1162 //TODO :later
1163 return 0;
1164 }
1165
eglLockSurfaceKHR(EGLDisplay display,EGLSurface surface,const EGLint * attrib_list)1166 EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
1167 {
1168 //TODO later
1169 return 0;
1170 }
1171
eglUnlockSurfaceKHR(EGLDisplay display,EGLSurface surface)1172 EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
1173 {
1174 //TODO later
1175 return 0;
1176 }
1177
eglCreateImageKHR(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)1178 EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
1179 {
1180 VALIDATE_DISPLAY_INIT(dpy, EGL_NO_IMAGE_KHR);
1181 if (ctx != EGL_NO_CONTEXT) {
1182 setErrorReturn(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1183 }
1184 if (target != EGL_NATIVE_BUFFER_ANDROID) {
1185 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
1186 }
1187
1188 android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
1189
1190 if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
1191 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
1192
1193 if (native_buffer->common.version != sizeof(android_native_buffer_t))
1194 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
1195
1196 switch (native_buffer->format) {
1197 case HAL_PIXEL_FORMAT_RGBA_8888:
1198 case HAL_PIXEL_FORMAT_RGBX_8888:
1199 case HAL_PIXEL_FORMAT_RGB_888:
1200 case HAL_PIXEL_FORMAT_RGB_565:
1201 case HAL_PIXEL_FORMAT_BGRA_8888:
1202 case HAL_PIXEL_FORMAT_RGBA_5551:
1203 case HAL_PIXEL_FORMAT_RGBA_4444:
1204 break;
1205 default:
1206 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
1207 }
1208
1209 native_buffer->common.incRef(&native_buffer->common);
1210 return (EGLImageKHR)native_buffer;
1211 }
1212
eglDestroyImageKHR(EGLDisplay dpy,EGLImageKHR img)1213 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
1214 {
1215 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
1216 android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;
1217
1218 if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
1219 setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
1220
1221 if (native_buffer->common.version != sizeof(android_native_buffer_t))
1222 setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
1223
1224 native_buffer->common.decRef(&native_buffer->common);
1225
1226 return EGL_TRUE;
1227 }
1228
eglCreateSyncKHR(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list)1229 EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1230 {
1231 //TODO later
1232 return 0;
1233 }
1234
eglDestroySyncKHR(EGLDisplay dpy,EGLSyncKHR sync)1235 EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1236 {
1237 //TODO later
1238 return 0;
1239 }
1240
eglClientWaitSyncKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags,EGLTimeKHR timeout)1241 EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
1242 {
1243 //TODO
1244 return 0;
1245 }
1246
eglSignalSyncKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLenum mode)1247 EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
1248 {
1249 //TODO later
1250 return 0;
1251 }
1252
eglGetSyncAttribKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint attribute,EGLint * value)1253 EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
1254 {
1255 //TODO later
1256 return 0;
1257 }
1258
eglSetSwapRectangleANDROID(EGLDisplay dpy,EGLSurface draw,EGLint left,EGLint top,EGLint width,EGLint height)1259 EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height)
1260 {
1261 //TODO later
1262 return 0;
1263 }
1264