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// ----------------------------------------------------------------------------
30namespace android {
31// ----------------------------------------------------------------------------
32
33class EGLUtils
34{
35public:
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
54const 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
76status_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
121status_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