1 /*
2  * Copyright (C) 2009 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 
17 
18 #ifndef ANDROID_UI_EGLUTILS_H
19 #define ANDROID_UI_EGLUTILS_H
20 
21 #include <stdint.h>
22 #include <stdlib.h>
23 
24 #include <system/window.h>
25 #include <utils/Errors.h>
26 #include <EGL/egl.h>
27 
28 
29 // ----------------------------------------------------------------------------
30 namespace android {
31 // ----------------------------------------------------------------------------
32 
33 class EGLUtils
34 {
35 public:
36 
37     static inline const char *strerror(EGLint err);
38 
39     static inline status_t selectConfigForPixelFormat(
40             EGLDisplay dpy,
41             EGLint const* attrs,
42             int32_t format,
43             EGLConfig* outConfig);
44 
45     static inline status_t selectConfigForNativeWindow(
46             EGLDisplay dpy,
47             EGLint const* attrs,
48             EGLNativeWindowType window,
49             EGLConfig* outConfig);
50 };
51 
52 // ----------------------------------------------------------------------------
53 
strerror(EGLint err)54 const char *EGLUtils::strerror(EGLint err)
55 {
56     switch (err){
57         case EGL_SUCCESS:           return "EGL_SUCCESS";
58         case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
59         case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
60         case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
61         case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
62         case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
63         case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
64         case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
65         case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
66         case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
67         case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
68         case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
69         case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
70         case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
71         case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
72         default: return "UNKNOWN";
73     }
74 }
75 
selectConfigForPixelFormat(EGLDisplay dpy,EGLint const * attrs,int32_t format,EGLConfig * outConfig)76 status_t EGLUtils::selectConfigForPixelFormat(
77         EGLDisplay dpy,
78         EGLint const* attrs,
79         int32_t format,
80         EGLConfig* outConfig)
81 {
82     EGLint numConfigs = -1, n=0;
83 
84     if (!attrs)
85         return BAD_VALUE;
86 
87     if (outConfig == NULL)
88         return BAD_VALUE;
89 
90     // Get all the "potential match" configs...
91     if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
92         return BAD_VALUE;
93 
94     EGLConfig* const configs = (EGLConfig*)malloc(sizeof(EGLConfig)*numConfigs);
95     if (eglChooseConfig(dpy, attrs, configs, numConfigs, &n) == EGL_FALSE) {
96         free(configs);
97         return BAD_VALUE;
98     }
99 
100     int i;
101     EGLConfig config = NULL;
102     for (i=0 ; i<n ; i++) {
103         EGLint nativeVisualId = 0;
104         eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
105         if (nativeVisualId>0 && format == nativeVisualId) {
106             config = configs[i];
107             break;
108         }
109     }
110 
111     free(configs);
112 
113     if (i<n) {
114         *outConfig = config;
115         return NO_ERROR;
116     }
117 
118     return NAME_NOT_FOUND;
119 }
120 
selectConfigForNativeWindow(EGLDisplay dpy,EGLint const * attrs,EGLNativeWindowType window,EGLConfig * outConfig)121 status_t EGLUtils::selectConfigForNativeWindow(
122         EGLDisplay dpy,
123         EGLint const* attrs,
124         EGLNativeWindowType window,
125         EGLConfig* outConfig)
126 {
127     int err;
128     int format;
129 
130     if (!window)
131         return BAD_VALUE;
132 
133     if ((err = window->query(window, NATIVE_WINDOW_FORMAT, &format)) < 0) {
134         return err;
135     }
136 
137     return selectConfigForPixelFormat(dpy, attrs, format, outConfig);
138 }
139 
140 // ----------------------------------------------------------------------------
141 }; // namespace android
142 // ----------------------------------------------------------------------------
143 
144 #endif /* ANDROID_UI_EGLUTILS_H */
145