Loader.cpp revision de58697644a52a614ad9498aa087e95d4a223673
1de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian/*
2de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** Copyright 2007, The Android Open Source Project
3de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian **
4de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** Licensed under the Apache License, Version 2.0 (the "License");
5de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** you may not use this file except in compliance with the License.
6de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** You may obtain a copy of the License at
7de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian **
8de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian **     http://www.apache.org/licenses/LICENSE-2.0
9de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian **
10de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** Unless required by applicable law or agreed to in writing, software
11de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** distributed under the License is distributed on an "AS IS" BASIS,
12de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** See the License for the specific language governing permissions and
14de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** limitations under the License.
15de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian */
16de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
17de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include <ctype.h>
18de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include <stdlib.h>
19de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include <stdio.h>
20de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include <string.h>
21de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include <errno.h>
22de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include <dlfcn.h>
23de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include <limits.h>
24de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
25de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include <cutils/log.h>
26de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
27de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include <EGL/egl.h>
28de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
29de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include "hooks.h"
30de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include "egl_impl.h"
31de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
32de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include "Loader.h"
33de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
34de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ----------------------------------------------------------------------------
35de58697644a52a614ad9498aa087e95d4a223673Mathias Agopiannamespace android {
36de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ----------------------------------------------------------------------------
37de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
38de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
39de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian/*
40de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian * EGL drivers are called
41de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian *
42de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian * /system/lib/egl/lib{[EGL|GLESv1_CM|GLESv2] | GLES}_$TAG.so
43de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian *
44de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian */
45de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
46de58697644a52a614ad9498aa087e95d4a223673Mathias AgopianANDROID_SINGLETON_STATIC_INSTANCE( Loader )
47de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
48de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ----------------------------------------------------------------------------
49de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
50de58697644a52a614ad9498aa087e95d4a223673Mathias AgopianLoader::driver_t::driver_t(void* gles)
51de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{
52de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    dso[0] = gles;
53de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    for (size_t i=1 ; i<NELEM(dso) ; i++)
54de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        dso[i] = 0;
55de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
56de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
57de58697644a52a614ad9498aa087e95d4a223673Mathias AgopianLoader::driver_t::~driver_t()
58de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{
59de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    for (size_t i=0 ; i<NELEM(dso) ; i++) {
60de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        if (dso[i]) {
61de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            dlclose(dso[i]);
62de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            dso[i] = 0;
63de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        }
64de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    }
65de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
66de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
67de58697644a52a614ad9498aa087e95d4a223673Mathias Agopianstatus_t Loader::driver_t::set(void* hnd, int32_t api)
68de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{
69de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    switch (api) {
70de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        case EGL:
71de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            dso[0] = hnd;
72de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            break;
73de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        case GLESv1_CM:
74de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            dso[1] = hnd;
75de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            break;
76de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        case GLESv2:
77de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            dso[2] = hnd;
78de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            break;
79de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        default:
80de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            return BAD_INDEX;
81de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    }
82de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    return NO_ERROR;
83de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
84de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
85de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ----------------------------------------------------------------------------
86de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
87de58697644a52a614ad9498aa087e95d4a223673Mathias AgopianLoader::entry_t::entry_t(int dpy, int impl, const char* tag)
88de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    : dpy(dpy), impl(impl), tag(tag) {
89de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
90de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
91de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ----------------------------------------------------------------------------
92de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
93de58697644a52a614ad9498aa087e95d4a223673Mathias AgopianLoader::Loader()
94de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{
95de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    char line[256];
96de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    char tag[256];
97de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r");
98de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    if (cfg == NULL) {
99de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        // default config
100de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        LOGD("egl.cfg not found, using default config");
101de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        gConfig.add( entry_t(0, 0, "android") );
102de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    } else {
103de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        while (fgets(line, 256, cfg)) {
104de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            int dpy;
105de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            int impl;
106de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) {
107de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                LOGD(">>> %u %u %s", dpy, impl, tag);
108de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                gConfig.add( entry_t(dpy, impl, tag) );
109de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            }
110de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        }
111de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        fclose(cfg);
112de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    }
113de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
114de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
115de58697644a52a614ad9498aa087e95d4a223673Mathias AgopianLoader::~Loader()
116de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{
117de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
118de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
119de58697644a52a614ad9498aa087e95d4a223673Mathias Agopianconst char* Loader::getTag(int dpy, int impl)
120de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{
121de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    const Vector<entry_t>& cfgs(gConfig);
122de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    const size_t c = cfgs.size();
123de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    for (size_t i=0 ; i<c ; i++) {
124de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        if (dpy == cfgs[i].dpy)
125de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            if (impl == cfgs[i].impl)
126de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                return cfgs[i].tag.string();
127de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    }
128de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    return 0;
129de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
130de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
131de58697644a52a614ad9498aa087e95d4a223673Mathias Agopianvoid* Loader::open(EGLNativeDisplayType display, int impl, gl_hooks_t* hooks)
132de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{
133de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    /*
134de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian     * TODO: if we don't find display/0, then use 0/0
135de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian     * (0/0 should always work)
136de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian     */
137de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
138de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    void* dso;
139de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    char path[PATH_MAX];
140de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    int index = int(display);
141de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    driver_t* hnd = 0;
142de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    const char* const format = "egl/lib%s_%s.so";
143de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
144de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    char const* tag = getTag(index, impl);
145de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    if (tag) {
146de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        snprintf(path, PATH_MAX, format, "GLES", tag);
147de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        dso = load_driver(path, hooks, EGL | GLESv1_CM | GLESv2);
148de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        if (dso) {
149de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            hnd = new driver_t(dso);
150de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        } else {
151de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            // Always load EGL first
152de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            snprintf(path, PATH_MAX, "lib%s_%s.so", "EGL", tag);
153de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            dso = load_driver(path, hooks, EGL);
154de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            if (dso) {
155de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                hnd = new driver_t(dso);
156de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
157de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                // TODO: make this more automated
158de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                snprintf(path, PATH_MAX, format, "GLESv1_CM", tag);
159de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                hnd->set( load_driver(path, hooks, GLESv1_CM), GLESv1_CM );
160de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
161de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                snprintf(path, PATH_MAX, format, "GLESv2", tag);
162de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                hnd->set( load_driver(path, hooks, GLESv2), GLESv2 );
163de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            }
164de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        }
165de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    }
166de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
167de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    LOG_FATAL_IF(!index && !impl && !hnd,
168de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            "couldn't't find the default OpenGL ES implementation "
169de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            "for default display");
170de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
171de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    return (void*)hnd;
172de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
173de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
174de58697644a52a614ad9498aa087e95d4a223673Mathias Agopianstatus_t Loader::close(void* driver)
175de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{
176de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    driver_t* hnd = (driver_t*)driver;
177de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    delete hnd;
178de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    return NO_ERROR;
179de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
180de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
181de58697644a52a614ad9498aa087e95d4a223673Mathias Agopianvoid Loader::init_api(void* dso,
182de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        char const * const * api,
183de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        __eglMustCastToProperFunctionPointerType* curr,
184de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        getProcAddressType getProcAddress)
185de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{
186de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    char scrap[256];
187de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    while (*api) {
188de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        char const * name = *api;
189de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        __eglMustCastToProperFunctionPointerType f =
190de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
191de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        if (f == NULL) {
192de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            // couldn't find the entry-point, use eglGetProcAddress()
193de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            f = getProcAddress(name);
194de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        }
195de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        if (f == NULL) {
196de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            // Try without the OES postfix
197de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            ssize_t index = ssize_t(strlen(name)) - 3;
198de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            if ((index>0 && (index<255)) && (!strcmp(name+index, "OES"))) {
199de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                strncpy(scrap, name, index);
200de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                scrap[index] = 0;
201de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap);
202de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                //LOGD_IF(f, "found <%s> instead", scrap);
203de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            }
204de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        }
205de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        if (f == NULL) {
206de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            // Try with the OES postfix
207de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            ssize_t index = ssize_t(strlen(name)) - 3;
208de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            if ((index>0 && (index<252)) && (strcmp(name+index, "OES"))) {
209de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                strncpy(scrap, name, index);
210de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                scrap[index] = 0;
211de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                strcat(scrap, "OES");
212de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap);
213de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                //LOGD_IF(f, "found <%s> instead", scrap);
214de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            }
215de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        }
216de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        if (f == NULL) {
217de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            //LOGD("%s", name);
218de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented;
219de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        }
220de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        *curr++ = f;
221de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        api++;
222de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    }
223de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
224de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
225de58697644a52a614ad9498aa087e95d4a223673Mathias Agopianvoid *Loader::load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask)
226de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{
227de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    //LOGD("%s", driver);
228de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL);
229de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    LOGE_IF(!dso,
230de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            "couldn't load <%s> library (%s)",
231de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            driver, dlerror());
232de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    if (dso == 0)
233de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        return 0;
234de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
235de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    if (mask & EGL) {
236de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
237de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
238de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        LOGE_IF(!getProcAddress,
239de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                "can't find eglGetProcAddress() in %s", driver);
240de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
241de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        gl_hooks_t::egl_t* egl = &hooks->egl;
242de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        __eglMustCastToProperFunctionPointerType* curr =
243de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            (__eglMustCastToProperFunctionPointerType*)egl;
244de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        char const * const * api = egl_names;
245de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        while (*api) {
246de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            char const * name = *api;
247de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            __eglMustCastToProperFunctionPointerType f =
248de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
249de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            if (f == NULL) {
250de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                // couldn't find the entry-point, use eglGetProcAddress()
251de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                f = getProcAddress(name);
252de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                if (f == NULL) {
253de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                    f = (__eglMustCastToProperFunctionPointerType)0;
254de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                }
255de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            }
256de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            *curr++ = f;
257de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            api++;
258de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        }
259de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    }
260de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
261de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    if (mask & GLESv1_CM) {
262de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian        init_api(dso, gl_names,
263de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                (__eglMustCastToProperFunctionPointerType*)&hooks->gl,
264de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian                getProcAddress);
265de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    }
266de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
267de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    if (mask & GLESv2) {
268de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian      init_api(dso, gl2_names,
269de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            (__eglMustCastToProperFunctionPointerType*)&hooks->gl2,
270de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian            getProcAddress);
271de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    }
272de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
273de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian    return dso;
274de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}
275de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian
276de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ----------------------------------------------------------------------------
277de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}; // namespace android
278de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ----------------------------------------------------------------------------
279