am a569aede: am aa77b777: Merge "emulator opengl: some system egl fixes after a review."

* commit 'a569aedecf988b121055bc96957136e5517560dd':
  emulator opengl: some system egl fixes after a review.
This commit is contained in:
David Turner
2011-06-17 04:43:22 -07:00
committed by Android Git Automerger
3 changed files with 156 additions and 38 deletions

View File

@@ -9,6 +9,7 @@ typedef struct {
typedef struct { typedef struct {
void* (*getProcAddress)(const char *funcName); void* (*getProcAddress)(const char *funcName);
void (*finish)();
} EGLClient_glesInterface; } EGLClient_glesInterface;
// //

View File

@@ -86,17 +86,19 @@ static T setError(GLint error, T returnValue) {
struct EGLContext_t { struct EGLContext_t {
//XXX: do we need this?
enum { enum {
IS_CURRENT = 0x00010000, IS_CURRENT = 0x00010000,
NEVER_CURRENT = 0x00020000 NEVER_CURRENT = 0x00020000
}; };
EGLContext_t(EGLDisplay dpy, EGLConfig config) : dpy(dpy), config(config), read(EGL_NO_SURFACE), draw(EGL_NO_SURFACE), rcContext(0) { version = 1; }; EGLContext_t(EGLDisplay dpy, EGLConfig config) : dpy(dpy), config(config),
read(EGL_NO_SURFACE), draw(EGL_NO_SURFACE),
rcContext(0) {
flags = 0;
version = 1;
};
~EGLContext_t(){}; ~EGLContext_t(){};
// EGLBoolean rcCreate(); uint32_t flags;
// EGLBoolean rcDestroy();
uint32_t flags; //XXX: do we need this?
EGLDisplay dpy; EGLDisplay dpy;
EGLConfig config; EGLConfig config;
EGLSurface read; EGLSurface read;
@@ -181,7 +183,8 @@ egl_window_surface_t::egl_window_surface_t (
EGLDisplay dpy, EGLConfig config, EGLDisplay dpy, EGLConfig config,
ANativeWindow* window) ANativeWindow* window)
: egl_surface_t(dpy, config), : egl_surface_t(dpy, config),
nativeWindow(window) nativeWindow(window),
buffer(NULL)
{ {
// keep a reference on the window // keep a reference on the window
nativeWindow->common.incRef(&nativeWindow->common); nativeWindow->common.incRef(&nativeWindow->common);
@@ -225,6 +228,7 @@ EGLBoolean egl_window_surface_t::connect()
if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) { if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) {
return setError(EGL_BAD_ALLOC, EGL_FALSE); return setError(EGL_BAD_ALLOC, EGL_FALSE);
} }
buffer->common.incRef(&buffer->common);
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, ((cb_handle_t *)(buffer->handle))->hostHandle); rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, ((cb_handle_t *)(buffer->handle))->hostHandle);
@@ -234,7 +238,11 @@ EGLBoolean egl_window_surface_t::connect()
void egl_window_surface_t::disconnect() void egl_window_surface_t::disconnect()
{ {
//TODO: do we need this? if (buffer) {
nativeWindow->queueBuffer(nativeWindow, buffer);
buffer->common.decRef(&buffer->common);
buffer = 0;
}
} }
EGLBoolean egl_window_surface_t::swapBuffers() EGLBoolean egl_window_surface_t::swapBuffers()
@@ -243,6 +251,8 @@ EGLBoolean egl_window_surface_t::swapBuffers()
return setError(EGL_BAD_ACCESS, EGL_FALSE); return setError(EGL_BAD_ACCESS, EGL_FALSE);
} }
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
//post the back buffer //post the back buffer
nativeWindow->queueBuffer(nativeWindow, buffer); nativeWindow->queueBuffer(nativeWindow, buffer);
@@ -251,7 +261,6 @@ EGLBoolean egl_window_surface_t::swapBuffers()
return setError(EGL_BAD_ALLOC, EGL_FALSE); return setError(EGL_BAD_ALLOC, EGL_FALSE);
} }
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, ((cb_handle_t *)(buffer->handle))->hostHandle); rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, ((cb_handle_t *)(buffer->handle))->hostHandle);
return EGL_TRUE; return EGL_TRUE;
@@ -277,6 +286,8 @@ struct egl_pbuffer_surface_t : public egl_surface_t {
virtual EGLBoolean rcCreate(); virtual EGLBoolean rcCreate();
virtual EGLBoolean rcDestroy(); virtual EGLBoolean rcDestroy();
virtual EGLBoolean connect();
uint32_t getRcColorBuffer(){ return rcColorBuffer; } uint32_t getRcColorBuffer(){ return rcColorBuffer; }
void setRcColorBuffer(uint32_t colorBuffer){ rcColorBuffer = colorBuffer; } void setRcColorBuffer(uint32_t colorBuffer){ rcColorBuffer = colorBuffer; }
private: private:
@@ -329,6 +340,13 @@ EGLBoolean egl_pbuffer_surface_t::rcDestroy()
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean egl_pbuffer_surface_t::connect()
{
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, rcColorBuffer);
return EGL_TRUE;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -502,8 +520,7 @@ EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWin
{ {
VALIDATE_DISPLAY_INIT(dpy, NULL); VALIDATE_DISPLAY_INIT(dpy, NULL);
VALIDATE_CONFIG(config, EGL_FALSE); VALIDATE_CONFIG(config, EGL_FALSE);
if (win == 0) if (win == 0) {
{
return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
} }
@@ -549,6 +566,7 @@ EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLin
if (attrib_list[0] == EGL_HEIGHT) h = attrib_list[1]; if (attrib_list[0] == EGL_HEIGHT) h = attrib_list[1];
attrib_list+=2; attrib_list+=2;
} }
// TODO: check EGL_TEXTURE_FORMAT - need to support eglBindTexImage
GLenum pixelFormat; GLenum pixelFormat;
if (s_display.getConfigPixelFormat(config, &pixelFormat) == EGL_FALSE) if (s_display.getConfigPixelFormat(config, &pixelFormat) == EGL_FALSE)
@@ -582,6 +600,7 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) ); egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
surface->disconnect();
surface->rcDestroy(); surface->rcDestroy();
delete surface; delete surface;
@@ -627,44 +646,51 @@ EGLenum eglQueryAPI()
} }
EGLBoolean eglWaitClient() EGLBoolean eglWaitClient()
{ //TODO {
return 0; return eglWaitGL();
} }
EGLBoolean eglReleaseThread() EGLBoolean eglReleaseThread()
{ {
//TODO EGLThreadInfo *tInfo = getEGLThreadInfo();
return 0; if (tInfo && tInfo->currentContext) {
return eglMakeCurrent(&s_display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
}
return EGL_TRUE;
} }
EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
{ {
//TODO //TODO
LOGW("%s not implemented", __FUNCTION__);
return 0; return 0;
} }
EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
{ {
//TODO //TODO
LOGW("%s not implemented", __FUNCTION__);
return 0; return 0;
} }
EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{ {
//TODO //TODO
LOGW("%s not implemented", __FUNCTION__);
return 0; return 0;
} }
EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{ {
//TODO //TODO
LOGW("%s not implemented", __FUNCTION__);
return 0; return 0;
} }
EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
{ {
//TODO //TODO
LOGW("%s not implemented", __FUNCTION__);
return 0; return 0;
} }
@@ -698,7 +724,7 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_c
if (!context) if (!context)
return setError(EGL_BAD_ALLOC, EGL_NO_CONTEXT); return setError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
context->version = 1; context->version = version;
context->rcContext = rcContext; context->rcContext = rcContext;
@@ -711,15 +737,18 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE); VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE);
EGLContext_t * context = static_cast<EGLContext_t*>(ctx); EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
if (getEGLThreadInfo()->currentContext == context)
{
eglMakeCurrent(dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
}
if (context->rcContext) { if (context->rcContext) {
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcEnc->rcDestroyContext(rcEnc, context->rcContext); rcEnc->rcDestroyContext(rcEnc, context->rcContext);
context->rcContext = 0; context->rcContext = 0;
} }
if (getEGLThreadInfo()->currentContext == context)
getEGLThreadInfo()->currentContext = NULL;
delete context; delete context;
return EGL_TRUE; return EGL_TRUE;
} }
@@ -742,19 +771,49 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
egl_surface_t * readSurf = static_cast<egl_surface_t *>(read); egl_surface_t * readSurf = static_cast<egl_surface_t *>(read);
uint32_t readHandle = (readSurf) ? readSurf->getRcSurface() : 0; uint32_t readHandle = (readSurf) ? readSurf->getRcSurface() : 0;
//
// Nothing to do if no binding change has made
//
EGLThreadInfo *tInfo = getEGLThreadInfo();
if (tInfo->currentContext == context &&
context &&
context->draw == draw &&
context->read == read) {
return EGL_TRUE;
}
if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) {
//context is current to another thread
return setError(EGL_BAD_ACCESS, EGL_FALSE);
}
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) { if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) {
LOGE("rcMakeCurrent returned EGL_FALSE"); LOGE("rcMakeCurrent returned EGL_FALSE");
return setError(EGL_BAD_CONTEXT, EGL_FALSE); return setError(EGL_BAD_CONTEXT, EGL_FALSE);
} }
//
// Disconnect from the previous drawable
//
if (tInfo->currentContext && tInfo->currentContext->draw) {
egl_surface_t * prevDrawSurf = static_cast<egl_surface_t *>(tInfo->currentContext->draw);
prevDrawSurf->disconnect();
}
//Now make the local bind //Now make the local bind
if (context) { if (context) {
context->draw = draw; context->draw = draw;
context->read = read; context->read = read;
context->flags |= EGLContext_t::IS_CURRENT;
} }
if (tInfo->currentContext)
tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT;
//Now make current //Now make current
getEGLThreadInfo()->currentContext = context; tInfo->currentContext = context;
//connect the color buffer //connect the color buffer
if (drawSurf) if (drawSurf)
@@ -826,14 +885,24 @@ EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGL
EGLBoolean eglWaitGL() EGLBoolean eglWaitGL()
{ {
//TODO EGLThreadInfo *tInfo = getEGLThreadInfo();
return 0; if (!tInfo || !tInfo->currentContext) {
return EGL_FALSE;
}
if (tInfo->currentContext->version == 2) {
s_display.gles2_iface()->finish();
}
else {
s_display.gles_iface()->finish();
}
return EGL_TRUE;
} }
EGLBoolean eglWaitNative(EGLint engine) EGLBoolean eglWaitNative(EGLint engine)
{ {
//TODO return EGL_TRUE;
return 0;
} }
EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface) EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface)
@@ -842,6 +911,8 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface)
if (eglSurface == EGL_NO_SURFACE) if (eglSurface == EGL_NO_SURFACE)
return setError(EGL_BAD_SURFACE, EGL_FALSE); return setError(EGL_BAD_SURFACE, EGL_FALSE);
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface); egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface);
if (!d->isValid()) if (!d->isValid())
return setError(EGL_BAD_SURFACE, EGL_FALSE); return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -851,48 +922,90 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface)
// post the surface // post the surface
d->swapBuffers(); d->swapBuffers();
hostCon->flush();
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
{ {
//TODO //TODO :later
return 0; return 0;
} }
EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list) EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
{ {
//TODO //TODO later
return 0; return 0;
} }
EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface) EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
{ {
//TODO //TODO later
return 0; return 0;
} }
EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
{ {
//TODO VALIDATE_DISPLAY_INIT(dpy, EGL_NO_IMAGE_KHR);
return 0;
if (ctx != EGL_NO_CONTEXT) {
return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
}
if (target != EGL_NATIVE_BUFFER_ANDROID) {
return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
if (native_buffer->common.version != sizeof(android_native_buffer_t))
return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
switch (native_buffer->format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGBA_5551:
case HAL_PIXEL_FORMAT_RGBA_4444:
break;
default:
return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
native_buffer->common.incRef(&native_buffer->common);
return (EGLImageKHR)native_buffer;
} }
EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
{ {
//TODO VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
return 0;
android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;
if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
return setError(EGL_BAD_PARAMETER, EGL_FALSE);
if (native_buffer->common.version != sizeof(android_native_buffer_t))
return setError(EGL_BAD_PARAMETER, EGL_FALSE);
native_buffer->common.decRef(&native_buffer->common);
return EGL_TRUE;
} }
EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
{ {
//TODO //TODO later
return 0; return 0;
} }
EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
{ {
//TODO //TODO later
return 0; return 0;
} }
@@ -904,18 +1017,18 @@ EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTi
EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
{ {
//TODO //TODO later
return 0; return 0;
} }
EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
{ {
//TODO //TODO later
return 0; return 0;
} }
EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height) EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height)
{ {
//TODO //TODO later
return 0; return 0;
} }

View File

@@ -383,7 +383,11 @@ EGLBoolean eglDisplay::getAttribValue(EGLConfig config, EGLint attribIdx, EGLint
EGLBoolean eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value) EGLBoolean eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value)
{ {
return getAttribValue(config, m_attribs.valueFor(attrib), value); //Though it seems that valueFor() is thread-safe, we don't take chanses
pthread_mutex_lock(&m_lock);
EGLBoolean ret = getAttribValue(config, m_attribs.valueFor(attrib), value);
pthread_mutex_unlock(&m_lock);
return ret;
} }
EGLBoolean eglDisplay::getConfigPixelFormat(EGLConfig config, GLenum * format) EGLBoolean eglDisplay::getConfigPixelFormat(EGLConfig config, GLenum * format)