implement connect/disconnect in our native_window_t implementations

the framebuffer implementation doesn't do anything special with this
but the surfaceflinger implementation makes sure the surface is not used
by two APIs simultaneously.

Change-Id: Id4ca8ef7093d68846abc2ac814327cc40a64b66b
This commit is contained in:
Mathias Agopian
2010-03-11 15:06:54 -08:00
parent f6331a4974
commit 2f7540e78f
3 changed files with 92 additions and 7 deletions

View File

@@ -210,9 +210,16 @@ private:
status_t dequeueBuffer(sp<GraphicBuffer>* buffer);
void dispatch_setUsage(va_list args);
int dispatch_connect(va_list args);
int dispatch_disconnect(va_list args);
void setUsage(uint32_t reqUsage);
int connect(int api);
int disconnect(int api);
uint32_t getUsage() const;
int getConnectedApi() const;
// constants
sp<SurfaceComposerClient> mClient;
@@ -227,6 +234,7 @@ private:
// protected by mSurfaceLock
Rect mSwapRectangle;
uint32_t mUsage;
int mConnected;
// protected by mSurfaceLock. These are also used from lock/unlock
// but in that case, they must be called form the same thread.

View File

@@ -353,6 +353,7 @@ void Surface::init()
const_cast<uint32_t&>(android_native_window_t::flags) = 0;
// be default we request a hardware surface
mUsage = GRALLOC_USAGE_HW_RENDER;
mConnected = 0;
mNeedFullUpdate = false;
}
@@ -579,28 +580,93 @@ int Surface::perform(int operation, va_list args)
{
int res = NO_ERROR;
switch (operation) {
case NATIVE_WINDOW_SET_USAGE:
setUsage( va_arg(args, int) );
break;
default:
res = NAME_NOT_FOUND;
break;
case NATIVE_WINDOW_SET_USAGE:
dispatch_setUsage( args );
break;
case NATIVE_WINDOW_CONNECT:
res = dispatch_connect( args );
break;
case NATIVE_WINDOW_DISCONNECT:
res = dispatch_disconnect( args );
break;
default:
res = NAME_NOT_FOUND;
break;
}
return res;
}
void Surface::dispatch_setUsage(va_list args) {
int usage = va_arg(args, int);
setUsage( usage );
}
int Surface::dispatch_connect(va_list args) {
int api = va_arg(args, int);
return connect( api );
}
int Surface::dispatch_disconnect(va_list args) {
int api = va_arg(args, int);
return disconnect( api );
}
void Surface::setUsage(uint32_t reqUsage)
{
Mutex::Autolock _l(mSurfaceLock);
mUsage = reqUsage;
}
int Surface::connect(int api)
{
Mutex::Autolock _l(mSurfaceLock);
int err = NO_ERROR;
switch (api) {
case NATIVE_WINDOW_API_EGL:
if (mConnected) {
err = -EINVAL;
} else {
mConnected = api;
}
break;
default:
err = -EINVAL;
break;
}
return err;
}
int Surface::disconnect(int api)
{
Mutex::Autolock _l(mSurfaceLock);
int err = NO_ERROR;
switch (api) {
case NATIVE_WINDOW_API_EGL:
if (mConnected == api) {
mConnected = 0;
} else {
err = -EINVAL;
}
break;
default:
err = -EINVAL;
break;
}
return err;
}
uint32_t Surface::getUsage() const
{
Mutex::Autolock _l(mSurfaceLock);
return mUsage;
}
int Surface::getConnectedApi() const
{
Mutex::Autolock _l(mSurfaceLock);
return mConnected;
}
// ----------------------------------------------------------------------------
status_t Surface::lock(SurfaceInfo* info, bool blocking) {
@@ -609,11 +675,20 @@ status_t Surface::lock(SurfaceInfo* info, bool blocking) {
status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
{
if (getConnectedApi()) {
LOGE("Surface::lock(%p) failed. Already connected to another API",
(android_native_window_t*)this);
CallStack stack;
stack.update();
stack.dump("");
return INVALID_OPERATION;
}
if (mApiLock.tryLock() != NO_ERROR) {
LOGE("calling Surface::lock from different threads!");
CallStack stack;
stack.update();
stack.dump("Surface::lock called from different threads");
stack.dump("");
return WOULD_BLOCK;
}

View File

@@ -250,6 +250,8 @@ int FramebufferNativeWindow::perform(android_native_window_t* window,
{
switch (operation) {
case NATIVE_WINDOW_SET_USAGE:
case NATIVE_WINDOW_CONNECT:
case NATIVE_WINDOW_DISCONNECT:
break;
default:
return NAME_NOT_FOUND;