remove multiplexing of multiple EGL implementation

from now on, the system can only have one EGL
implementation. this means the software and h/w renderer
cannot be used at the same time on a device. Of course, the
h/w renderer is always prefered; in its absence we
default to the software renderer.

Change-Id: Ib579f58055dd0ce4c4a99144131efa11c16ca3d3
This commit is contained in:
Mathias Agopian 2012-02-13 17:09:30 -08:00
parent a64366ee40
commit ada798b7ca
10 changed files with 259 additions and 428 deletions

View File

@ -118,12 +118,6 @@ status_t Loader::driver_t::set(void* hnd, int32_t api)
// ----------------------------------------------------------------------------
Loader::entry_t::entry_t(int dpy, int impl, const char* tag)
: dpy(dpy), impl(impl), tag(tag) {
}
// ----------------------------------------------------------------------------
Loader::Loader()
{
char line[256];
@ -131,8 +125,9 @@ Loader::Loader()
/* Special case for GLES emulation */
if (checkGlesEmulationStatus() == 0) {
ALOGD("Emulator without GPU support detected. Fallback to software renderer.");
gConfig.add( entry_t(0, 0, "android") );
ALOGD("Emulator without GPU support detected. "
"Fallback to software renderer.");
mDriverTag.setTo("android");
return;
}
@ -141,14 +136,16 @@ Loader::Loader()
if (cfg == NULL) {
// default config
ALOGD("egl.cfg not found, using default config");
gConfig.add( entry_t(0, 0, "android") );
mDriverTag.setTo("android");
} else {
while (fgets(line, 256, cfg)) {
int dpy;
int impl;
int dpy, impl;
if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) {
//ALOGD(">>> %u %u %s", dpy, impl, tag);
gConfig.add( entry_t(dpy, impl, tag) );
// We only load the h/w accelerated implementation
if (tag != String8("android")) {
mDriverTag = tag;
}
}
}
fclose(cfg);
@ -160,30 +157,12 @@ Loader::~Loader()
GLTrace_stop();
}
const char* Loader::getTag(int dpy, int impl)
void* Loader::open(egl_connection_t* cnx)
{
const Vector<entry_t>& cfgs(gConfig);
const size_t c = cfgs.size();
for (size_t i=0 ; i<c ; i++) {
if (dpy == cfgs[i].dpy)
if (impl == cfgs[i].impl)
return cfgs[i].tag.string();
}
return 0;
}
void* Loader::open(EGLNativeDisplayType display, int impl, egl_connection_t* cnx)
{
/*
* TODO: if we don't find display/0, then use 0/0
* (0/0 should always work)
*/
void* dso;
int index = int(display);
driver_t* hnd = 0;
char const* tag = getTag(index, impl);
char const* tag = mDriverTag.string();
if (tag) {
dso = load_driver("GLES", tag, cnx, EGL | GLESv1_CM | GLESv2);
if (dso) {
@ -193,16 +172,14 @@ void* Loader::open(EGLNativeDisplayType display, int impl, egl_connection_t* cnx
dso = load_driver("EGL", tag, cnx, EGL);
if (dso) {
hnd = new driver_t(dso);
// TODO: make this more automated
hnd->set( load_driver("GLESv1_CM", tag, cnx, GLESv1_CM), GLESv1_CM );
hnd->set( load_driver("GLESv2", tag, cnx, GLESv2), GLESv2 );
hnd->set( load_driver("GLESv2", tag, cnx, GLESv2), GLESv2 );
}
}
}
LOG_FATAL_IF(!index && !impl && !hnd,
LOG_FATAL_IF(!index && !hnd,
"couldn't find the default OpenGL ES implementation "
"for default display");

View File

@ -24,7 +24,6 @@
#include <utils/Errors.h>
#include <utils/Singleton.h>
#include <utils/String8.h>
#include <utils/Vector.h>
#include <EGL/egl.h>
@ -53,23 +52,13 @@ class Loader : public Singleton<Loader>
void* dso[3];
};
struct entry_t {
entry_t() { }
entry_t(int dpy, int impl, const char* tag);
int dpy;
int impl;
String8 tag;
};
Vector<entry_t> gConfig;
String8 mDriverTag;
getProcAddressType getProcAddress;
const char* getTag(int dpy, int impl);
public:
~Loader();
void* open(EGLNativeDisplayType display, int impl, egl_connection_t* cnx);
void* open(egl_connection_t* cnx);
status_t close(void* driver);
private:

View File

@ -48,8 +48,8 @@
namespace android {
// ----------------------------------------------------------------------------
egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS];
egl_connection_t gEGLImpl;
gl_hooks_t gHooks[2];
gl_hooks_t gHooksNoContext;
pthread_key_t gGLWrapperKey = -1;
@ -196,7 +196,7 @@ egl_connection_t* validate_display_config(EGLDisplay dpy, EGLConfig config,
if (intptr_t(config) >= dp->numTotalConfigs) {
return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
}
egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(config)].impl];
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso == 0) {
return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
}
@ -228,7 +228,7 @@ EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image)
// EGL.
egl_image_t const * const i = get_image(image);
return i->images[c->impl];
return i->image;
}
// ----------------------------------------------------------------------------
@ -266,34 +266,15 @@ static EGLBoolean egl_init_drivers_locked() {
// get our driver loader
Loader& loader(Loader::getInstance());
// dynamically load all our EGL implementations
egl_connection_t* cnx;
cnx = &gEGLImpl[IMPL_SOFTWARE];
// dynamically load our EGL implementation
egl_connection_t* cnx = &gEGLImpl;
if (cnx->dso == 0) {
cnx->hooks[GLESv1_INDEX] = &gHooks[GLESv1_INDEX][IMPL_SOFTWARE];
cnx->hooks[GLESv2_INDEX] = &gHooks[GLESv2_INDEX][IMPL_SOFTWARE];
cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 0, cnx);
cnx->hooks[GLESv1_INDEX] = &gHooks[GLESv1_INDEX];
cnx->hooks[GLESv2_INDEX] = &gHooks[GLESv2_INDEX];
cnx->dso = loader.open(cnx);
}
cnx = &gEGLImpl[IMPL_HARDWARE];
if (cnx->dso == 0) {
char value[PROPERTY_VALUE_MAX];
property_get("debug.egl.hw", value, "1");
if (atoi(value) != 0) {
cnx->hooks[GLESv1_INDEX] = &gHooks[GLESv1_INDEX][IMPL_HARDWARE];
cnx->hooks[GLESv2_INDEX] = &gHooks[GLESv2_INDEX][IMPL_HARDWARE];
cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 1, cnx);
} else {
ALOGD("3D hardware acceleration is disabled");
}
}
if (!gEGLImpl[IMPL_SOFTWARE].dso && !gEGLImpl[IMPL_HARDWARE].dso) {
return EGL_FALSE;
}
return EGL_TRUE;
return cnx->dso ? EGL_TRUE : EGL_FALSE;
}
static pthread_mutex_t sInitDriverMutex = PTHREAD_MUTEX_INITIALIZER;

View File

@ -44,6 +44,7 @@
#include "egl_impl.h"
#include "egl_object.h"
#include "egl_tls.h"
#include "egldefs.h"
using namespace android;
@ -255,7 +256,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
}
}
egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(ourConfig)].impl];
egl_connection_t* const cnx = &gEGLImpl;
if (found && cnx->dso) {
// and switch to the new list
attrib_list = const_cast<const EGLint *>(new_list);
@ -269,7 +270,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
// which one.
res = cnx->egl.eglChooseConfig(
dp->disp[ dp->configs[intptr_t(ourConfig)].impl ].dpy,
dp->disp.dpy,
attrib_list, configs, config_size, &n);
if (res && n>0) {
// n has to be 0 or 1, by construction, and we already know
@ -286,33 +287,32 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
}
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->egl.eglChooseConfig(
dp->disp[i].dpy, attrib_list, configs, config_size, &n)) {
if (configs) {
// now we need to convert these client EGLConfig to our
// internal EGLConfig format.
// This is done in O(n Log(n)) time.
for (int j=0 ; j<n ; j++) {
egl_config_t key(i, configs[j]);
intptr_t index = binarySearch<egl_config_t>(
dp->configs, 0, dp->numTotalConfigs, key);
if (index >= 0) {
configs[j] = EGLConfig(index);
} else {
return setError(EGL_BAD_CONFIG, EGL_FALSE);
}
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso) {
if (cnx->egl.eglChooseConfig(
dp->disp.dpy, attrib_list, configs, config_size, &n)) {
if (configs) {
// now we need to convert these client EGLConfig to our
// internal EGLConfig format.
// This is done in O(n Log(n)) time.
for (int j=0 ; j<n ; j++) {
egl_config_t key(configs[j]);
intptr_t index = binarySearch<egl_config_t>(
dp->configs, 0, dp->numTotalConfigs, key);
if (index >= 0) {
configs[j] = EGLConfig(index);
} else {
return setError(EGL_BAD_CONFIG, EGL_FALSE);
}
configs += n;
config_size -= n;
}
*num_config += n;
res = EGL_TRUE;
configs += n;
config_size -= n;
}
*num_config += n;
res = EGL_TRUE;
}
}
return res;
}
@ -330,7 +330,7 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
return EGL_TRUE;
}
return cnx->egl.eglGetConfigAttrib(
dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
dp->disp.dpy,
dp->configs[intptr_t(config)].config, attribute, value);
}
@ -347,7 +347,7 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
egl_display_t const* dp = 0;
egl_connection_t* cnx = validate_display_config(dpy, config, dp);
if (cnx) {
EGLDisplay iDpy = dp->disp[ dp->configs[intptr_t(config)].impl ].dpy;
EGLDisplay iDpy = dp->disp.dpy;
EGLConfig iConfig = dp->configs[intptr_t(config)].config;
EGLint format;
@ -379,8 +379,7 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
EGLSurface surface = cnx->egl.eglCreateWindowSurface(
iDpy, iConfig, window, attrib_list);
if (surface != EGL_NO_SURFACE) {
egl_surface_t* s = new egl_surface_t(dpy, config, window, surface,
dp->configs[intptr_t(config)].impl, cnx);
egl_surface_t* s = new egl_surface_t(dpy, config, window, surface, cnx);
return s;
}
@ -401,11 +400,10 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config,
egl_connection_t* cnx = validate_display_config(dpy, config, dp);
if (cnx) {
EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
dp->disp.dpy,
dp->configs[intptr_t(config)].config, pixmap, attrib_list);
if (surface != EGL_NO_SURFACE) {
egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface,
dp->configs[intptr_t(config)].impl, cnx);
egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface, cnx);
return s;
}
}
@ -421,11 +419,10 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
egl_connection_t* cnx = validate_display_config(dpy, config, dp);
if (cnx) {
EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
dp->disp.dpy,
dp->configs[intptr_t(config)].config, attrib_list);
if (surface != EGL_NO_SURFACE) {
egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface,
dp->configs[intptr_t(config)].impl, cnx);
egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface, cnx);
return s;
}
}
@ -444,8 +441,7 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
return setError(EGL_BAD_SURFACE, EGL_FALSE);
egl_surface_t * const s = get_surface(surface);
EGLBoolean result = s->cnx->egl.eglDestroySurface(
dp->disp[s->impl].dpy, s->surface);
EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
if (result == EGL_TRUE) {
_s.terminate();
}
@ -471,7 +467,7 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
*value = dp->configs[intptr_t(s->config)].configId;
} else {
result = s->cnx->egl.eglQuerySurface(
dp->disp[s->impl].dpy, s->surface, attribute, value);
dp->disp.dpy, s->surface, attribute, value);
}
return result;
@ -514,7 +510,7 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
share_list = c->context;
}
EGLContext context = cnx->egl.eglCreateContext(
dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
dp->disp.dpy,
dp->configs[intptr_t(config)].config,
share_list, attrib_list);
if (context != EGL_NO_CONTEXT) {
@ -533,8 +529,7 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
}
};
}
egl_context_t* c = new egl_context_t(dpy, context, config,
dp->configs[intptr_t(config)].impl, cnx, version);
egl_context_t* c = new egl_context_t(dpy, context, config, cnx, version);
#if EGL_TRACE
if (gEGLDebugLevel > 0)
GLTrace_eglCreateContext(version, c);
@ -558,8 +553,7 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
egl_context_t * const c = get_context(ctx);
EGLBoolean result = c->cnx->egl.eglDestroyContext(
dp->disp[c->impl].dpy, c->context);
EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
if (result == EGL_TRUE) {
_c.terminate();
}
@ -625,20 +619,12 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
// retrieve the underlying implementation's draw EGLSurface
if (draw != EGL_NO_SURFACE) {
d = get_surface(draw);
// make sure the EGLContext and EGLSurface passed in are for
// the same driver
if (c && d->impl != c->impl)
return setError(EGL_BAD_MATCH, EGL_FALSE);
impl_draw = d->surface;
}
// retrieve the underlying implementation's read EGLSurface
if (read != EGL_NO_SURFACE) {
r = get_surface(read);
// make sure the EGLContext and EGLSurface passed in are for
// the same driver
if (c && r->impl != c->impl)
return setError(EGL_BAD_MATCH, EGL_FALSE);
impl_read = r->surface;
}
@ -689,7 +675,7 @@ EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
} else {
// We need to remap EGL_CONFIG_IDs
result = c->cnx->egl.eglQueryContext(
dp->disp[c->impl].dpy, c->context, attribute, value);
dp->disp.dpy, c->context, attribute, value);
}
return result;
@ -744,64 +730,37 @@ EGLDisplay eglGetCurrentDisplay(void)
EGLBoolean eglWaitGL(void)
{
// could be called before eglInitialize(), but we wouldn't have a context
// then, and this function would return GL_TRUE, which isn't wrong.
clearError();
EGLBoolean res = EGL_TRUE;
EGLContext ctx = getContext();
if (ctx) {
egl_context_t const * const c = get_context(ctx);
if (!c) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
if (uint32_t(c->impl)>=2)
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
egl_connection_t* const cnx = &gEGLImpl[c->impl];
if (!cnx->dso)
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
res = cnx->egl.eglWaitGL();
}
return res;
egl_connection_t* const cnx = &gEGLImpl;
if (!cnx->dso)
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
return cnx->egl.eglWaitGL();
}
EGLBoolean eglWaitNative(EGLint engine)
{
// could be called before eglInitialize(), but we wouldn't have a context
// then, and this function would return GL_TRUE, which isn't wrong.
clearError();
EGLBoolean res = EGL_TRUE;
EGLContext ctx = getContext();
if (ctx) {
egl_context_t const * const c = get_context(ctx);
if (!c) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
if (uint32_t(c->impl)>=2)
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
egl_connection_t* const cnx = &gEGLImpl[c->impl];
if (!cnx->dso)
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
res = cnx->egl.eglWaitNative(engine);
}
return res;
egl_connection_t* const cnx = &gEGLImpl;
if (!cnx->dso)
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
return cnx->egl.eglWaitNative(engine);
}
EGLint eglGetError(void)
{
EGLint result = EGL_SUCCESS;
EGLint err;
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
err = EGL_SUCCESS;
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso)
err = cnx->egl.eglGetError();
if (err!=EGL_SUCCESS && result==EGL_SUCCESS)
result = err;
EGLint err = EGL_SUCCESS;
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso) {
err = cnx->egl.eglGetError();
}
err = egl_tls_t::getError();
if (result == EGL_SUCCESS)
result = err;
return result;
if (err == EGL_SUCCESS) {
err = egl_tls_t::getError();
}
return err;
}
// Note: Similar implementations of these functions also exist in
@ -885,20 +844,20 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
bool found = false;
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso && cnx->egl.eglGetProcAddress) {
found = true;
// Extensions are independent of the bound context
cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->egl.eglGetProcAddress) {
found = true;
// Extensions are independent of the bound context
cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
#if EGL_TRACE
debugHooks->ext.extensions[slot] =
gHooksTrace.ext.extensions[slot] =
debugHooks->ext.extensions[slot] =
gHooksTrace.ext.extensions[slot] =
#endif
cnx->egl.eglGetProcAddress(procname);
}
cnx->egl.eglGetProcAddress(procname);
}
if (found) {
addr = gExtensionForwarders[slot];
@ -937,7 +896,7 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
#endif
egl_surface_t const * const s = get_surface(draw);
return s->cnx->egl.eglSwapBuffers(dp->disp[s->impl].dpy, s->surface);
return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
}
EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface,
@ -953,8 +912,7 @@ EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface,
return setError(EGL_BAD_SURFACE, EGL_FALSE);
egl_surface_t const * const s = get_surface(surface);
return s->cnx->egl.eglCopyBuffers(
dp->disp[s->impl].dpy, s->surface, target);
return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
}
const char* eglQueryString(EGLDisplay dpy, EGLint name)
@ -973,12 +931,8 @@ const char* eglQueryString(EGLDisplay dpy, EGLint name)
return dp->getExtensionString();
case EGL_CLIENT_APIS:
return dp->getClientApiString();
case EGL_VERSION_HW_ANDROID: {
if (gEGLImpl[IMPL_HARDWARE].dso) {
return dp->disp[IMPL_HARDWARE].queryString.version;
}
return dp->disp[IMPL_SOFTWARE].queryString.version;
}
case EGL_VERSION_HW_ANDROID:
return dp->disp.queryString.version;
}
return setError(EGL_BAD_PARAMETER, (const char *)0);
}
@ -1003,7 +957,7 @@ EGLBoolean eglSurfaceAttrib(
egl_surface_t const * const s = get_surface(surface);
if (s->cnx->egl.eglSurfaceAttrib) {
return s->cnx->egl.eglSurfaceAttrib(
dp->disp[s->impl].dpy, s->surface, attribute, value);
dp->disp.dpy, s->surface, attribute, value);
}
return setError(EGL_BAD_SURFACE, EGL_FALSE);
}
@ -1023,7 +977,7 @@ EGLBoolean eglBindTexImage(
egl_surface_t const * const s = get_surface(surface);
if (s->cnx->egl.eglBindTexImage) {
return s->cnx->egl.eglBindTexImage(
dp->disp[s->impl].dpy, s->surface, buffer);
dp->disp.dpy, s->surface, buffer);
}
return setError(EGL_BAD_SURFACE, EGL_FALSE);
}
@ -1043,7 +997,7 @@ EGLBoolean eglReleaseTexImage(
egl_surface_t const * const s = get_surface(surface);
if (s->cnx->egl.eglReleaseTexImage) {
return s->cnx->egl.eglReleaseTexImage(
dp->disp[s->impl].dpy, s->surface, buffer);
dp->disp.dpy, s->surface, buffer);
}
return setError(EGL_BAD_SURFACE, EGL_FALSE);
}
@ -1056,17 +1010,11 @@ EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
if (!dp) return EGL_FALSE;
EGLBoolean res = EGL_TRUE;
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->egl.eglSwapInterval) {
if (cnx->egl.eglSwapInterval(
dp->disp[i].dpy, interval) == EGL_FALSE) {
res = EGL_FALSE;
}
}
}
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->egl.eglSwapInterval) {
res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
}
return res;
}
@ -1079,23 +1027,15 @@ EGLBoolean eglWaitClient(void)
{
clearError();
// could be called before eglInitialize(), but we wouldn't have a context
// then, and this function would return GL_TRUE, which isn't wrong.
EGLBoolean res = EGL_TRUE;
EGLContext ctx = getContext();
if (ctx) {
egl_context_t const * const c = get_context(ctx);
if (!c) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
if (uint32_t(c->impl)>=2)
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
egl_connection_t* const cnx = &gEGLImpl[c->impl];
if (!cnx->dso)
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
if (cnx->egl.eglWaitClient) {
res = cnx->egl.eglWaitClient();
} else {
res = cnx->egl.eglWaitGL();
}
egl_connection_t* const cnx = &gEGLImpl;
if (!cnx->dso)
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
EGLBoolean res;
if (cnx->egl.eglWaitClient) {
res = cnx->egl.eglWaitClient();
} else {
res = cnx->egl.eglWaitGL();
}
return res;
}
@ -1110,15 +1050,9 @@ EGLBoolean eglBindAPI(EGLenum api)
// bind this API on all EGLs
EGLBoolean res = EGL_TRUE;
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->egl.eglBindAPI) {
if (cnx->egl.eglBindAPI(api) == EGL_FALSE) {
res = EGL_FALSE;
}
}
}
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->egl.eglBindAPI) {
res = cnx->egl.eglBindAPI(api);
}
return res;
}
@ -1131,16 +1065,11 @@ EGLenum eglQueryAPI(void)
return setError(EGL_BAD_PARAMETER, EGL_FALSE);
}
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->egl.eglQueryAPI) {
// the first one we find is okay, because they all
// should be the same
return cnx->egl.eglQueryAPI();
}
}
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->egl.eglQueryAPI) {
return cnx->egl.eglQueryAPI();
}
// or, it can only be OpenGL ES
return EGL_OPENGL_ES_API;
}
@ -1152,14 +1081,11 @@ EGLBoolean eglReleaseThread(void)
// If there is context bound to the thread, release it
egl_display_t::loseCurrent(get_context(getContext()));
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->egl.eglReleaseThread) {
cnx->egl.eglReleaseThread();
}
}
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->egl.eglReleaseThread) {
cnx->egl.eglReleaseThread();
}
egl_tls_t::clearTLS();
#if EGL_TRACE
if (gEGLDebugLevel > 0)
@ -1179,7 +1105,7 @@ EGLSurface eglCreatePbufferFromClientBuffer(
if (!cnx) return EGL_FALSE;
if (cnx->egl.eglCreatePbufferFromClientBuffer) {
return cnx->egl.eglCreatePbufferFromClientBuffer(
dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
dp->disp.dpy,
buftype, buffer,
dp->configs[intptr_t(config)].config, attrib_list);
}
@ -1205,7 +1131,7 @@ EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
egl_surface_t const * const s = get_surface(surface);
if (s->cnx->egl.eglLockSurfaceKHR) {
return s->cnx->egl.eglLockSurfaceKHR(
dp->disp[s->impl].dpy, s->surface, attrib_list);
dp->disp.dpy, s->surface, attrib_list);
}
return setError(EGL_BAD_DISPLAY, EGL_FALSE);
}
@ -1223,8 +1149,7 @@ EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
egl_surface_t const * const s = get_surface(surface);
if (s->cnx->egl.eglUnlockSurfaceKHR) {
return s->cnx->egl.eglUnlockSurfaceKHR(
dp->disp[s->impl].dpy, s->surface);
return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
}
return setError(EGL_BAD_DISPLAY, EGL_FALSE);
}
@ -1244,12 +1169,12 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
egl_context_t * const c = get_context(ctx);
// since we have an EGLContext, we know which implementation to use
EGLImageKHR image = c->cnx->egl.eglCreateImageKHR(
dp->disp[c->impl].dpy, c->context, target, buffer, attrib_list);
dp->disp.dpy, c->context, target, buffer, attrib_list);
if (image == EGL_NO_IMAGE_KHR)
return image;
egl_image_t* result = new egl_image_t(dpy, ctx);
result->images[c->impl] = image;
result->image = image;
return (EGLImageKHR)result;
} else {
// EGL_NO_CONTEXT is a valid parameter
@ -1261,23 +1186,14 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
EGLint currentError = eglGetError();
EGLImageKHR implImages[IMPL_NUM_IMPLEMENTATIONS];
bool success = false;
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
implImages[i] = EGL_NO_IMAGE_KHR;
if (cnx->dso) {
if (cnx->egl.eglCreateImageKHR) {
implImages[i] = cnx->egl.eglCreateImageKHR(
dp->disp[i].dpy, ctx, target, buffer, attrib_list);
if (implImages[i] != EGL_NO_IMAGE_KHR) {
success = true;
}
}
}
EGLImageKHR implImage = EGL_NO_IMAGE_KHR;
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->egl.eglCreateImageKHR) {
implImage = cnx->egl.eglCreateImageKHR(
dp->disp.dpy, ctx, target, buffer, attrib_list);
}
if (!success) {
if (implImage == EGL_NO_IMAGE_KHR) {
// failure, if there was an error when we entered this function,
// the error flag must not be updated.
// Otherwise, the error is whatever happened in the implementation
@ -1289,13 +1205,12 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
} else {
// In case of success, we need to clear all error flags
// (especially those caused by the implementation that didn't
// succeed). TODO: we could avoid this if we knew this was
// a "full" success (all implementation succeeded).
// succeed).
eglGetError();
}
egl_image_t* result = new egl_image_t(dpy, ctx);
memcpy(result->images, implImages, sizeof(implImages));
result->image = implImage;
return (EGLImageKHR)result;
}
}
@ -1312,19 +1227,17 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
egl_image_t* image = get_image(img);
bool success = false;
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (image->images[i] != EGL_NO_IMAGE_KHR) {
if (cnx->dso) {
if (cnx->egl.eglDestroyImageKHR) {
if (cnx->egl.eglDestroyImageKHR(
dp->disp[i].dpy, image->images[i])) {
success = true;
}
}
egl_connection_t* const cnx = &gEGLImpl;
if (image->image != EGL_NO_IMAGE_KHR) {
if (cnx->dso && cnx->egl.eglDestroyImageKHR) {
if (cnx->egl.eglDestroyImageKHR(
dp->disp.dpy, image->image)) {
success = true;
}
}
}
if (!success)
return EGL_FALSE;
@ -1354,7 +1267,7 @@ EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_l
EGLSyncKHR result = EGL_NO_SYNC_KHR;
if (c->cnx->egl.eglCreateSyncKHR) {
EGLSyncKHR sync = c->cnx->egl.eglCreateSyncKHR(
dp->disp[c->impl].dpy, type, attrib_list);
dp->disp.dpy, type, attrib_list);
if (sync == EGL_NO_SYNC_KHR)
return sync;
result = (egl_sync_t*)new egl_sync_t(dpy, ctx, sync);
@ -1382,7 +1295,7 @@ EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
egl_context_t * const c = get_context(ctx);
if (c->cnx->egl.eglDestroySyncKHR) {
result = c->cnx->egl.eglDestroySyncKHR(
dp->disp[c->impl].dpy, syncObject->sync);
dp->disp.dpy, syncObject->sync);
if (result)
_s.terminate();
}
@ -1408,7 +1321,7 @@ EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTi
egl_context_t * const c = get_context(ctx);
if (c->cnx->egl.eglClientWaitSyncKHR) {
return c->cnx->egl.eglClientWaitSyncKHR(
dp->disp[c->impl].dpy, syncObject->sync, flags, timeout);
dp->disp.dpy, syncObject->sync, flags, timeout);
}
return EGL_FALSE;
@ -1434,7 +1347,7 @@ EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute
egl_context_t * const c = get_context(ctx);
if (c->cnx->egl.eglGetSyncAttribKHR) {
return c->cnx->egl.eglGetSyncAttribKHR(
dp->disp[c->impl].dpy, syncObject->sync, attribute, value);
dp->disp.dpy, syncObject->sync, attribute, value);
}
return EGL_FALSE;
@ -1458,12 +1371,10 @@ EGLuint64NV eglGetSystemTimeFrequencyNV()
}
EGLuint64NV ret = 0;
egl_connection_t* const cnx = &gEGLImpl[IMPL_HARDWARE];
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso) {
if (cnx->egl.eglGetSystemTimeFrequencyNV) {
return cnx->egl.eglGetSystemTimeFrequencyNV();
}
if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
return cnx->egl.eglGetSystemTimeFrequencyNV();
}
return setErrorQuiet(EGL_BAD_DISPLAY, 0);
@ -1478,12 +1389,10 @@ EGLuint64NV eglGetSystemTimeNV()
}
EGLuint64NV ret = 0;
egl_connection_t* const cnx = &gEGLImpl[IMPL_HARDWARE];
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso) {
if (cnx->egl.eglGetSystemTimeNV) {
return cnx->egl.eglGetSystemTimeNV();
}
if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
return cnx->egl.eglGetSystemTimeNV();
}
return setErrorQuiet(EGL_BAD_DISPLAY, 0);

View File

@ -83,39 +83,39 @@ egl_cache_t* egl_cache_t::get() {
void egl_cache_t::initialize(egl_display_t *display) {
Mutex::Autolock lock(mMutex);
for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
const char* exts = display->disp[i].queryString.extensions;
size_t bcExtLen = strlen(BC_EXT_STR);
size_t extsLen = strlen(exts);
bool equal = !strcmp(BC_EXT_STR, exts);
bool atStart = !strncmp(BC_EXT_STR " ", exts, bcExtLen+1);
bool atEnd = (bcExtLen+1) < extsLen &&
!strcmp(" " BC_EXT_STR, exts + extsLen - (bcExtLen+1));
bool inMiddle = strstr(exts, " " BC_EXT_STR " ");
if (equal || atStart || atEnd || inMiddle) {
PFNEGLSETBLOBCACHEFUNCSANDROIDPROC eglSetBlobCacheFuncsANDROID;
eglSetBlobCacheFuncsANDROID =
reinterpret_cast<PFNEGLSETBLOBCACHEFUNCSANDROIDPROC>(
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
const char* exts = display->disp.queryString.extensions;
size_t bcExtLen = strlen(BC_EXT_STR);
size_t extsLen = strlen(exts);
bool equal = !strcmp(BC_EXT_STR, exts);
bool atStart = !strncmp(BC_EXT_STR " ", exts, bcExtLen+1);
bool atEnd = (bcExtLen+1) < extsLen &&
!strcmp(" " BC_EXT_STR, exts + extsLen - (bcExtLen+1));
bool inMiddle = strstr(exts, " " BC_EXT_STR " ");
if (equal || atStart || atEnd || inMiddle) {
PFNEGLSETBLOBCACHEFUNCSANDROIDPROC eglSetBlobCacheFuncsANDROID;
eglSetBlobCacheFuncsANDROID =
reinterpret_cast<PFNEGLSETBLOBCACHEFUNCSANDROIDPROC>(
cnx->egl.eglGetProcAddress(
"eglSetBlobCacheFuncsANDROID"));
if (eglSetBlobCacheFuncsANDROID == NULL) {
ALOGE("EGL_ANDROID_blob_cache advertised by display %d, "
"but unable to get eglSetBlobCacheFuncsANDROID", i);
continue;
}
if (eglSetBlobCacheFuncsANDROID == NULL) {
ALOGE("EGL_ANDROID_blob_cache advertised, "
"but unable to get eglSetBlobCacheFuncsANDROID");
return;
}
eglSetBlobCacheFuncsANDROID(display->disp[i].dpy,
android::setBlob, android::getBlob);
EGLint err = cnx->egl.eglGetError();
if (err != EGL_SUCCESS) {
ALOGE("eglSetBlobCacheFuncsANDROID resulted in an error: "
"%#x", err);
}
eglSetBlobCacheFuncsANDROID(display->disp.dpy,
android::setBlob, android::getBlob);
EGLint err = cnx->egl.eglGetError();
if (err != EGL_SUCCESS) {
ALOGE("eglSetBlobCacheFuncsANDROID resulted in an error: "
"%#x", err);
}
}
}
mInitialized = true;
}

View File

@ -119,15 +119,13 @@ EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
// get our driver loader
Loader& loader(Loader::getInstance());
for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso && disp[i].dpy == EGL_NO_DISPLAY) {
EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
disp[i].dpy = dpy;
if (dpy == EGL_NO_DISPLAY) {
loader.close(cnx->dso);
cnx->dso = NULL;
}
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
disp.dpy = dpy;
if (dpy == EGL_NO_DISPLAY) {
loader.close(cnx->dso);
cnx->dso = NULL;
}
}
@ -160,12 +158,11 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
// initialize each EGL and
// build our own extension string first, based on the extension we know
// and the extension supported by our client implementation
for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
cnx->major = -1;
cnx->minor = -1;
if (!cnx->dso)
continue;
egl_connection_t* const cnx = &gEGLImpl;
cnx->major = -1;
cnx->minor = -1;
if (cnx->dso) {
#if defined(ADRENO130)
#warning "Adreno-130 eglInitialize() workaround"
@ -177,31 +174,30 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
* eglGetDisplay() before calling eglInitialize();
*/
if (i == IMPL_HARDWARE) {
disp[i].dpy =
cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
disp[i].dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
}
#endif
EGLDisplay idpy = disp[i].dpy;
EGLDisplay idpy = disp.dpy;
if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
//ALOGD("initialized %d dpy=%p, ver=%d.%d, cnx=%p",
// i, idpy, cnx->major, cnx->minor, cnx);
//ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
// idpy, cnx->major, cnx->minor, cnx);
// display is now initialized
disp[i].state = egl_display_t::INITIALIZED;
disp.state = egl_display_t::INITIALIZED;
// get the query-strings for this display for each implementation
disp[i].queryString.vendor = cnx->egl.eglQueryString(idpy,
disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
EGL_VENDOR);
disp[i].queryString.version = cnx->egl.eglQueryString(idpy,
disp.queryString.version = cnx->egl.eglQueryString(idpy,
EGL_VERSION);
disp[i].queryString.extensions = cnx->egl.eglQueryString(idpy,
disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
EGL_EXTENSIONS);
disp[i].queryString.clientApi = cnx->egl.eglQueryString(idpy,
disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
EGL_CLIENT_APIS);
} else {
ALOGW("%d: eglInitialize(%p) failed (%s)", i, idpy,
ALOGW("eglInitialize(%p) failed (%s)", idpy,
egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
}
}
@ -223,15 +219,13 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
if (len) {
// NOTE: we could avoid the copy if we had strnstr.
const String8 ext(start, len);
// now go through all implementations and look for this extension
for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
if (disp[i].queryString.extensions) {
// if we find it, add this extension string to our list
// (and don't forget the space)
const char* match = strstr(disp[i].queryString.extensions, ext.string());
if (match && (match[len] == ' ' || match[len] == 0)) {
mExtensionString.append(start, len+1);
}
// now look for this extension
if (disp.queryString.extensions) {
// if we find it, add this extension string to our list
// (and don't forget the space)
const char* match = strstr(disp.queryString.extensions, ext.string());
if (match && (match[len] == ' ' || match[len] == 0)) {
mExtensionString.append(start, len+1);
}
}
}
@ -243,18 +237,15 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
egl_cache_t::get()->initialize(this);
EGLBoolean res = EGL_FALSE;
for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
EGLint n;
if (cnx->egl.eglGetConfigs(disp[i].dpy, 0, 0, &n)) {
disp[i].config = (EGLConfig*) malloc(sizeof(EGLConfig) * n);
if (disp[i].config) {
if (cnx->egl.eglGetConfigs(disp[i].dpy, disp[i].config, n,
&disp[i].numConfigs)) {
numTotalConfigs += n;
res = EGL_TRUE;
}
if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
EGLint n;
if (cnx->egl.eglGetConfigs(disp.dpy, 0, 0, &n)) {
disp.config = (EGLConfig*) malloc(sizeof(EGLConfig) * n);
if (disp.config) {
if (cnx->egl.eglGetConfigs(disp.dpy, disp.config, n,
&disp.numConfigs)) {
numTotalConfigs += n;
res = EGL_TRUE;
}
}
}
@ -262,18 +253,16 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
if (res == EGL_TRUE) {
configs = new egl_config_t[numTotalConfigs];
for (int i = 0, k = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
for (int j = 0; j < disp[i].numConfigs; j++) {
configs[k].impl = i;
configs[k].config = disp[i].config[j];
configs[k].configId = k + 1; // CONFIG_ID start at 1
// store the implementation's CONFIG_ID
cnx->egl.eglGetConfigAttrib(disp[i].dpy, disp[i].config[j],
EGL_CONFIG_ID, &configs[k].implConfigId);
k++;
}
int k = 0;
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
for (int j = 0; j < disp.numConfigs; j++) {
configs[k].config = disp.config[j];
configs[k].configId = k + 1; // CONFIG_ID start at 1
// store the implementation's CONFIG_ID
cnx->egl.eglGetConfigAttrib(disp.dpy, disp.config[j],
EGL_CONFIG_ID, &configs[k].implConfigId);
k++;
}
}
@ -305,22 +294,20 @@ EGLBoolean egl_display_t::terminate() {
}
EGLBoolean res = EGL_FALSE;
for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso && disp[i].state == egl_display_t::INITIALIZED) {
if (cnx->egl.eglTerminate(disp[i].dpy) == EGL_FALSE) {
ALOGW("%d: eglTerminate(%p) failed (%s)", i, disp[i].dpy,
egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
}
// REVISIT: it's unclear what to do if eglTerminate() fails
free(disp[i].config);
disp[i].numConfigs = 0;
disp[i].config = 0;
disp[i].state = egl_display_t::TERMINATED;
res = EGL_TRUE;
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
}
// REVISIT: it's unclear what to do if eglTerminate() fails
free(disp.config);
disp.numConfigs = 0;
disp.config = 0;
disp.state = egl_display_t::TERMINATED;
res = EGL_TRUE;
}
// Mark all objects remaining in the list as terminated, unless
@ -390,13 +377,13 @@ EGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
Mutex::Autolock _l(lock);
if (c) {
result = c->cnx->egl.eglMakeCurrent(
disp[c->impl].dpy, impl_draw, impl_read, impl_ctx);
disp.dpy, impl_draw, impl_read, impl_ctx);
if (result == EGL_TRUE) {
c->onMakeCurrent(draw, read);
}
} else {
result = cur_c->cnx->egl.eglMakeCurrent(
disp[cur_c->impl].dpy, impl_draw, impl_read, impl_ctx);
disp.dpy, impl_draw, impl_read, impl_ctx);
if (result == EGL_TRUE) {
cur_c->onLooseCurrent();
}

View File

@ -46,15 +46,12 @@ class egl_connection_t;
struct egl_config_t {
egl_config_t() {}
egl_config_t(int impl, EGLConfig config)
: impl(impl), config(config), configId(0), implConfigId(0) { }
int impl; // the implementation this config is for
egl_config_t(EGLConfig config)
: config(config), configId(0), implConfigId(0) { }
EGLConfig config; // the implementation's EGLConfig
EGLint configId; // our CONFIG_ID
EGLint implConfigId; // the implementation's CONFIG_ID
inline bool operator < (const egl_config_t& rhs) const {
if (impl < rhs.impl) return true;
if (impl > rhs.impl) return false;
return config < rhs.config;
}
};
@ -126,7 +123,7 @@ private:
uint32_t magic;
public:
DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS];
DisplayImpl disp;
EGLint numTotalConfigs;
egl_config_t* configs;

View File

@ -64,9 +64,9 @@ bool egl_object_t::get(egl_display_t const* display, egl_object_t* object) {
// ----------------------------------------------------------------------------
egl_context_t::egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
int impl, egl_connection_t const* cnx, int version) :
egl_connection_t const* cnx, int version) :
egl_object_t(get_display(dpy)), dpy(dpy), context(context),
config(config), read(0), draw(0), impl(impl), cnx(cnx),
config(config), read(0), draw(0), cnx(cnx),
version(version)
{
}
@ -87,7 +87,7 @@ void egl_context_t::onMakeCurrent(EGLSurface draw, EGLSurface read) {
if (gl_extensions.isEmpty()) {
// call the implementation's glGetString(GL_EXTENSIONS)
const char* exts = (const char *)gEGLImpl[impl].hooks[version]->gl.glGetString(GL_EXTENSIONS);
const char* exts = (const char *)gEGLImpl.hooks[version]->gl.glGetString(GL_EXTENSIONS);
gl_extensions.setTo(exts);
if (gl_extensions.find("GL_EXT_debug_marker") < 0) {
String8 temp("GL_EXT_debug_marker ");

View File

@ -125,7 +125,7 @@ void egl_object_t::LocalRef<N,T>::terminate() {
// ----------------------------------------------------------------------------
class egl_surface_t: public egl_object_t {
class egl_surface_t : public egl_object_t {
protected:
~egl_surface_t() {
ANativeWindow* const window = win.get();
@ -140,15 +140,14 @@ public:
typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win,
EGLSurface surface, int impl, egl_connection_t const* cnx) :
EGLSurface surface, egl_connection_t const* cnx) :
egl_object_t(get_display(dpy)), dpy(dpy), surface(surface),
config(config), win(win), impl(impl), cnx(cnx) {
config(config), win(win), cnx(cnx) {
}
EGLDisplay dpy;
EGLSurface surface;
EGLConfig config;
sp<ANativeWindow> win;
int impl;
egl_connection_t const* cnx;
};
@ -159,7 +158,7 @@ public:
typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
int impl, egl_connection_t const* cnx, int version);
egl_connection_t const* cnx, int version);
void onLooseCurrent();
void onMakeCurrent(EGLSurface draw, EGLSurface read);
@ -169,7 +168,6 @@ public:
EGLConfig config;
EGLSurface read;
EGLSurface draw;
int impl;
egl_connection_t const* cnx;
int version;
String8 gl_extensions;
@ -182,12 +180,11 @@ public:
typedef egl_object_t::LocalRef<egl_image_t, EGLImageKHR> Ref;
egl_image_t(EGLDisplay dpy, EGLContext context) :
egl_object_t(get_display(dpy)), dpy(dpy), context(context) {
memset(images, 0, sizeof(images));
}
egl_object_t(get_display(dpy)),
dpy(dpy), context(context), image(EGL_NO_IMAGE_KHR) { }
EGLDisplay dpy;
EGLContext context;
EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS];
EGLImageKHR image;
};
class egl_sync_t: public egl_object_t {

View File

@ -29,15 +29,9 @@ namespace android {
// EGLDisplay are global, not attached to a given thread
const unsigned int NUM_DISPLAYS = 1;
enum {
IMPL_HARDWARE = 0,
IMPL_SOFTWARE,
IMPL_NUM_IMPLEMENTATIONS
};
enum {
GLESv1_INDEX = 0,
GLESv2_INDEX = 1,
GLESv2_INDEX = 1
};
// ----------------------------------------------------------------------------
@ -54,7 +48,7 @@ struct egl_connection_t
// ----------------------------------------------------------------------------
extern gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS];
extern gl_hooks_t gHooks[2];
extern gl_hooks_t gHooksNoContext;
extern pthread_key_t gGLWrapperKey;
extern "C" void gl_unimplemented();
@ -63,7 +57,7 @@ extern "C" void gl_noop();
extern char const * const gl_names[];
extern char const * const egl_names[];
extern egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
extern egl_connection_t gEGLImpl;
// ----------------------------------------------------------------------------
}; // namespace android