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:
parent
a64366ee40
commit
ada798b7ca
|
@ -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");
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 ");
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue