am 124d1804: am 7ef79e49: EmuGL: don\'t [de]queue buffers in eglMakeCurrent

* commit '124d18041b8c262f47e16a3e10d26f35e9deb597':
  EmuGL: don't [de]queue buffers in eglMakeCurrent
This commit is contained in:
Jesse Hall
2012-02-27 13:57:57 -08:00
committed by Android Git Automerger

View File

@@ -124,8 +124,6 @@ const char * eglStrError(EGLint err)
#define VALIDATE_SURFACE_RETURN(surface, ret) \ #define VALIDATE_SURFACE_RETURN(surface, ret) \
if (surface != EGL_NO_SURFACE) { \ if (surface != EGL_NO_SURFACE) { \
egl_surface_t* s( static_cast<egl_surface_t*>(surface) ); \ egl_surface_t* s( static_cast<egl_surface_t*>(surface) ); \
if (!s->isValid()) \
setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); \
if (s->dpy != (EGLDisplay)&s_display) \ if (s->dpy != (EGLDisplay)&s_display) \
setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); \ setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); \
} }
@@ -175,49 +173,39 @@ struct egl_surface_t {
egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType); egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType);
virtual ~egl_surface_t(); virtual ~egl_surface_t();
virtual EGLBoolean rcCreate() = 0;
virtual EGLBoolean rcDestroy() = 0;
virtual EGLBoolean connect() { return EGL_TRUE; }
virtual void disconnect() {}
virtual void setSwapInterval(int interval) = 0; virtual void setSwapInterval(int interval) = 0;
virtual EGLBoolean swapBuffers() { return EGL_TRUE; } virtual EGLBoolean swapBuffers() = 0;
virtual EGLint getSwapBehavior() const;
void setRcSurface(uint32_t handle){ rcSurface = handle; } EGLint getSwapBehavior() const;
uint32_t getRcSurface(){ return rcSurface; } uint32_t getRcSurface() { return rcSurface; }
EGLint getSurfaceType() { return surfaceType; }
virtual EGLBoolean isValid(){ return valid; }
EGLint getSurfaceType(){ return surfaceType; }
void setWidth(EGLint w){ width = w; }
EGLint getWidth(){ return width; } EGLint getWidth(){ return width; }
void setHeight(EGLint h){ height = h; }
EGLint getHeight(){ return height; } EGLint getHeight(){ return height; }
void setTextureFormat(EGLint _texFormat){ texFormat = _texFormat; } void setTextureFormat(EGLint _texFormat) { texFormat = _texFormat; }
EGLint getTextureFormat(){ return texFormat; } EGLint getTextureFormat() { return texFormat; }
void setTextureTarget(EGLint _texTarget){ texTarget = _texTarget; } void setTextureTarget(EGLint _texTarget) { texTarget = _texTarget; }
EGLint getTextureTarget(){ return texTarget; } EGLint getTextureTarget() { return texTarget; }
private: private:
// //
//Surface attributes //Surface attributes
// //
EGLint width; EGLint width;
EGLint height; EGLint height;
EGLint texFormat; EGLint texFormat;
EGLint texTarget; EGLint texTarget;
protected: protected:
EGLint surfaceType; void setWidth(EGLint w) { width = w; }
EGLBoolean valid; void setHeight(EGLint h) { height = h; }
uint32_t rcSurface; //handle to surface created via remote control
EGLint surfaceType;
uint32_t rcSurface; //handle to surface created via remote control
}; };
egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType) egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType)
: dpy(dpy), config(config), surfaceType(surfaceType), valid(EGL_FALSE), rcSurface(0) : dpy(dpy), config(config), surfaceType(surfaceType), rcSurface(0)
{ {
width = 0; width = 0;
height = 0; height = 0;
@@ -226,7 +214,7 @@ egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceTyp
} }
EGLint egl_surface_t::getSwapBehavior() const { EGLint egl_surface_t::getSwapBehavior() const {
return EGL_BUFFER_PRESERVED; return EGL_BUFFER_PRESERVED;
} }
egl_surface_t::~egl_surface_t() egl_surface_t::~egl_surface_t()
@@ -237,32 +225,29 @@ egl_surface_t::~egl_surface_t()
// egl_window_surface_t // egl_window_surface_t
struct egl_window_surface_t : public egl_surface_t { struct egl_window_surface_t : public egl_surface_t {
static egl_window_surface_t* create(
egl_window_surface_t(
EGLDisplay dpy, EGLConfig config, EGLint surfType, EGLDisplay dpy, EGLConfig config, EGLint surfType,
ANativeWindow* window); ANativeWindow* window);
~egl_window_surface_t(); virtual ~egl_window_surface_t();
virtual EGLBoolean rcCreate(); virtual void setSwapInterval(int interval);
virtual EGLBoolean rcDestroy(); virtual EGLBoolean swapBuffers();
virtual EGLBoolean connect();
virtual void disconnect();
virtual void setSwapInterval(int interval);
virtual EGLBoolean swapBuffers();
private: private:
ANativeWindow* nativeWindow; egl_window_surface_t(
android_native_buffer_t* buffer; EGLDisplay dpy, EGLConfig config, EGLint surfType,
ANativeWindow* window);
EGLBoolean init();
ANativeWindow* nativeWindow;
android_native_buffer_t* buffer;
}; };
egl_window_surface_t::egl_window_surface_t ( egl_window_surface_t::egl_window_surface_t (
EGLDisplay dpy, EGLConfig config, EGLint surfType, EGLDisplay dpy, EGLConfig config, EGLint surfType,
ANativeWindow* window) ANativeWindow* window)
: egl_surface_t(dpy, config, surfType), : egl_surface_t(dpy, config, surfType),
nativeWindow(window), nativeWindow(window),
buffer(NULL) buffer(NULL)
{ {
@@ -275,58 +260,48 @@ egl_window_surface_t::egl_window_surface_t (
setHeight(h); setHeight(h);
} }
egl_window_surface_t::~egl_window_surface_t() { EGLBoolean egl_window_surface_t::init()
nativeWindow->common.decRef(&nativeWindow->common);
}
EGLBoolean egl_window_surface_t::rcCreate()
{ {
if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) {
setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
}
nativeWindow->lockBuffer(nativeWindow, buffer);
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, getWidth(), getHeight()); rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config,
getWidth(), getHeight());
if (!rcSurface) { if (!rcSurface) {
LOGE("rcCreateWindowSurface returned 0"); LOGE("rcCreateWindowSurface returned 0");
return EGL_FALSE; return EGL_FALSE;
} }
valid = EGL_TRUE; rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
((cb_handle_t*)(buffer->handle))->hostHandle);
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean egl_window_surface_t::rcDestroy() egl_window_surface_t* egl_window_surface_t::create(
EGLDisplay dpy, EGLConfig config, EGLint surfType,
ANativeWindow* window)
{ {
if (!rcSurface) { egl_window_surface_t* wnd = new egl_window_surface_t(
LOGE("rcDestroy called on invalid rcSurface"); dpy, config, surfType, window);
return EGL_FALSE; if (wnd && !wnd->init()) {
delete wnd;
wnd = NULL;
} }
return wnd;
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
rcSurface = 0;
return EGL_TRUE;
} }
EGLBoolean egl_window_surface_t::connect() egl_window_surface_t::~egl_window_surface_t() {
{ DEFINE_HOST_CONNECTION;
// dequeue a buffer if (rcSurface && rcEnc) {
if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) { rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
} }
// lock the buffer
nativeWindow->lockBuffer(nativeWindow, buffer);
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, ((cb_handle_t *)(buffer->handle))->hostHandle);
return EGL_TRUE;
}
void egl_window_surface_t::disconnect()
{
if (buffer) { if (buffer) {
nativeWindow->queueBuffer(nativeWindow, buffer); nativeWindow->cancelBuffer(nativeWindow, buffer);
buffer = 0;
} }
nativeWindow->common.decRef(&nativeWindow->common);
} }
void egl_window_surface_t::setSwapInterval(int interval) void egl_window_surface_t::setSwapInterval(int interval)
@@ -336,26 +311,19 @@ void egl_window_surface_t::setSwapInterval(int interval)
EGLBoolean egl_window_surface_t::swapBuffers() EGLBoolean egl_window_surface_t::swapBuffers()
{ {
if (!buffer) {
setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE);
}
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface); rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface);
//post the back buffer
nativeWindow->queueBuffer(nativeWindow, buffer); nativeWindow->queueBuffer(nativeWindow, buffer);
// dequeue a new buffer
if (nativeWindow->dequeueBuffer(nativeWindow, &buffer)) { if (nativeWindow->dequeueBuffer(nativeWindow, &buffer)) {
buffer = NULL;
setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE); setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
} }
// lock the buffer
nativeWindow->lockBuffer(nativeWindow, buffer); nativeWindow->lockBuffer(nativeWindow, buffer);
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;
} }
@@ -364,30 +332,28 @@ EGLBoolean egl_window_surface_t::swapBuffers()
//egl_pbuffer_surface_t //egl_pbuffer_surface_t
struct egl_pbuffer_surface_t : public egl_surface_t { struct egl_pbuffer_surface_t : public egl_surface_t {
static egl_pbuffer_surface_t* create(EGLDisplay dpy, EGLConfig config,
GLenum format; EGLint surfType, int32_t w, int32_t h, GLenum pixelFormat);
egl_pbuffer_surface_t(
EGLDisplay dpy, EGLConfig config, EGLint surfType,
int32_t w, int32_t h, GLenum format);
virtual ~egl_pbuffer_surface_t(); virtual ~egl_pbuffer_surface_t();
virtual EGLBoolean rcCreate();
virtual EGLBoolean rcDestroy();
virtual EGLBoolean connect(); virtual void setSwapInterval(int interval) {}
virtual void setSwapInterval(int interval) {} virtual EGLBoolean swapBuffers() { return EGL_TRUE; }
uint32_t getRcColorBuffer() { return rcColorBuffer; }
uint32_t getRcColorBuffer(){ return rcColorBuffer; }
void setRcColorBuffer(uint32_t colorBuffer){ rcColorBuffer = colorBuffer; }
private: private:
egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfType,
int32_t w, int32_t h);
EGLBoolean init(GLenum format);
uint32_t rcColorBuffer; uint32_t rcColorBuffer;
}; };
egl_pbuffer_surface_t::egl_pbuffer_surface_t( egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config,
EGLDisplay dpy, EGLConfig config, EGLint surfType, EGLint surfType, int32_t w, int32_t h)
int32_t w, int32_t h, GLenum pixelFormat) : egl_surface_t(dpy, config, surfType),
: egl_surface_t(dpy, config, surfType), format(pixelFormat) rcColorBuffer(0)
{ {
setWidth(w); setWidth(w);
setHeight(h); setHeight(h);
@@ -395,50 +361,49 @@ egl_pbuffer_surface_t::egl_pbuffer_surface_t(
egl_pbuffer_surface_t::~egl_pbuffer_surface_t() egl_pbuffer_surface_t::~egl_pbuffer_surface_t()
{ {
rcColorBuffer = 0; DEFINE_HOST_CONNECTION;
if (rcEnc) {
if (rcColorBuffer) rcEnc->rcCloseColorBuffer(rcEnc, rcColorBuffer);
if (rcSurface) rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
}
} }
EGLBoolean egl_pbuffer_surface_t::rcCreate() EGLBoolean egl_pbuffer_surface_t::init(GLenum pixelFormat)
{ {
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, getWidth(), getHeight());
rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config,
getWidth(), getHeight());
if (!rcSurface) { if (!rcSurface) {
LOGE("rcCreateWindowSurface returned 0"); LOGE("rcCreateWindowSurface returned 0");
return EGL_FALSE; return EGL_FALSE;
} }
rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(), format);
rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(),
pixelFormat);
if (!rcColorBuffer) { if (!rcColorBuffer) {
LOGE("rcCreateColorBuffer returned 0"); LOGE("rcCreateColorBuffer returned 0");
return EGL_FALSE; return EGL_FALSE;
} }
valid = EGL_TRUE;
return EGL_TRUE;
}
EGLBoolean egl_pbuffer_surface_t::rcDestroy()
{
if ((!rcSurface)||(!rcColorBuffer)) {
LOGE("destroyRc called on invalid rcSurface");
return EGL_FALSE;
}
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
rcEnc->rcCloseColorBuffer(rcEnc, rcColorBuffer);
rcSurface = 0;
return EGL_TRUE;
}
EGLBoolean egl_pbuffer_surface_t::connect()
{
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, rcColorBuffer); rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, rcColorBuffer);
return EGL_TRUE; return EGL_TRUE;
} }
egl_pbuffer_surface_t* egl_pbuffer_surface_t::create(EGLDisplay dpy,
EGLConfig config, EGLint surfType, int32_t w, int32_t h,
GLenum pixelFormat)
{
egl_pbuffer_surface_t* pb = new egl_pbuffer_surface_t(dpy, config, surfType,
w, h);
if (pb && !pb->init(pixelFormat)) {
delete pb;
pb = NULL;
}
return pb;
}
static const char *getGLString(int glEnum) static const char *getGLString(int glEnum)
{ {
EGLThreadInfo *tInfo = getEGLThreadInfo(); EGLThreadInfo *tInfo = getEGLThreadInfo();
@@ -661,12 +626,9 @@ EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWin
setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
} }
egl_surface_t* surface; egl_surface_t* surface = egl_window_surface_t::create(
surface = new egl_window_surface_t(&s_display, config, surfaceType, static_cast<ANativeWindow*>(win)); &s_display, config, surfaceType, static_cast<ANativeWindow*>(win));
if (!surface) if (!surface) {
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
if (!surface->rcCreate()) {
delete surface;
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
} }
@@ -718,11 +680,9 @@ EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLin
if (s_display.getConfigGLPixelFormat(config, &pixelFormat) == EGL_FALSE) if (s_display.getConfigGLPixelFormat(config, &pixelFormat) == EGL_FALSE)
setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
egl_surface_t* surface = new egl_pbuffer_surface_t(dpy, config, surfaceType, w, h, pixelFormat); egl_surface_t* surface = egl_pbuffer_surface_t::create(dpy, config,
if (!surface) surfaceType, w, h, pixelFormat);
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE); if (!surface) {
if (!surface->rcCreate()) {
delete surface;
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
} }
@@ -748,10 +708,7 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) ); egl_surface_t* surface(static_cast<egl_surface_t*>(eglSurface));
surface->disconnect();
surface->rcDestroy();
delete surface; delete surface;
return EGL_TRUE; return EGL_TRUE;
@@ -995,14 +952,6 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE); setErrorReturn(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;
@@ -1055,10 +1004,6 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC
} }
} }
//connect the color buffer
if (drawSurf)
drawSurf->connect();
return EGL_TRUE; return EGL_TRUE;
} }
@@ -1156,8 +1101,6 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface)
DEFINE_AND_VALIDATE_HOST_CONNECTION(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())
setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
if (d->dpy != dpy) if (d->dpy != dpy)
setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE);