• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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