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:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user