replicant-frameworks_native/libs/ui/ISurfaceComposer.cpp
Mathias Agopian 83c0446f27 some work to try to reduce the code size of some native libraries
- make sure that all binder Bn classes define a ctor and dtor in their respective library.
  This avoids duplication of the ctor/dtor in libraries where these objects are instantiated.
  This is also cleaner, should we want these ctor/dtor to do something one day.

- same change as above for some Bp classes and various other non-binder classes

- moved the definition of CHECK_INTERFACE() in IInterface.h instead of having it everywhere.

- improved the CHECK_INTERFACE() macro so it calls a single method in Parcel, instead of inlining its code everywhere

- IBinder::getInterfaceDescriptor() now returns a "const String16&" instead of String16, which saves calls to String16 and ~String16

- implemented a cache for BpBinder::getInterfaceDescriptor(), since this does an IPC. HOWEVER, this method never seems to be called.
  The cache makes BpBinder bigger, so we need to figure out if we need this method at all.
2009-05-26 16:12:20 -07:00

279 lines
9.4 KiB
C++

/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// tag as surfaceflinger
#define LOG_TAG "SurfaceFlinger"
#include <stdint.h>
#include <sys/types.h>
#include <binder/Parcel.h>
#include <binder/IMemory.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <ui/ISurfaceComposer.h>
#include <ui/DisplayInfo.h>
// ---------------------------------------------------------------------------
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
// ---------------------------------------------------------------------------
namespace android {
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
public:
BpSurfaceComposer(const sp<IBinder>& impl)
: BpInterface<ISurfaceComposer>(impl)
{
}
virtual sp<ISurfaceFlingerClient> createConnection()
{
uint32_t n;
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
return interface_cast<ISurfaceFlingerClient>(reply.readStrongBinder());
}
virtual sp<IMemory> getCblk() const
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply);
return interface_cast<IMemory>(reply.readStrongBinder());
}
virtual void openGlobalTransaction()
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::OPEN_GLOBAL_TRANSACTION, data, &reply);
}
virtual void closeGlobalTransaction()
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::CLOSE_GLOBAL_TRANSACTION, data, &reply);
}
virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeInt32(dpy);
data.writeInt32(flags);
remote()->transact(BnSurfaceComposer::FREEZE_DISPLAY, data, &reply);
return reply.readInt32();
}
virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeInt32(dpy);
data.writeInt32(flags);
remote()->transact(BnSurfaceComposer::UNFREEZE_DISPLAY, data, &reply);
return reply.readInt32();
}
virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeInt32(dpy);
data.writeInt32(orientation);
data.writeInt32(flags);
remote()->transact(BnSurfaceComposer::SET_ORIENTATION, data, &reply);
return reply.readInt32();
}
virtual void bootFinished()
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
}
virtual status_t requestGPU(
const sp<IGPUCallback>& callback, gpu_info_t* gpu)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeStrongBinder(callback->asBinder());
remote()->transact(BnSurfaceComposer::REQUEST_GPU, data, &reply);
gpu->regs = interface_cast<IMemory>(reply.readStrongBinder());
gpu->count = reply.readInt32();
// FIXME: for now, we don't dynamically allocate the regions array
size_t maxCount = sizeof(gpu->regions)/sizeof(*gpu->regions);
if (gpu->count > maxCount)
return BAD_VALUE;
for (size_t i=0 ; i<gpu->count ; i++) {
gpu->regions[i].region = interface_cast<IMemory>(reply.readStrongBinder());
gpu->regions[i].reserved = reply.readInt32();
}
return reply.readInt32();
}
virtual status_t revokeGPU()
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::REVOKE_GPU, data, &reply);
return reply.readInt32();
}
virtual void signal() const
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::SIGNAL, data, &reply, IBinder::FLAG_ONEWAY);
}
};
IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
// ----------------------------------------------------------------------
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> b = createConnection()->asBinder();
reply->writeStrongBinder(b);
} break;
case OPEN_GLOBAL_TRANSACTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
openGlobalTransaction();
} break;
case CLOSE_GLOBAL_TRANSACTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
closeGlobalTransaction();
} break;
case SET_ORIENTATION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
DisplayID dpy = data.readInt32();
int orientation = data.readInt32();
uint32_t flags = data.readInt32();
reply->writeInt32( setOrientation(dpy, orientation, flags) );
} break;
case FREEZE_DISPLAY: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
DisplayID dpy = data.readInt32();
uint32_t flags = data.readInt32();
reply->writeInt32( freezeDisplay(dpy, flags) );
} break;
case UNFREEZE_DISPLAY: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
DisplayID dpy = data.readInt32();
uint32_t flags = data.readInt32();
reply->writeInt32( unfreezeDisplay(dpy, flags) );
} break;
case BOOT_FINISHED: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
bootFinished();
} break;
case REVOKE_GPU: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
reply->writeInt32( revokeGPU() );
} break;
case SIGNAL: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
signal();
} break;
case GET_CBLK: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> b = getCblk()->asBinder();
reply->writeStrongBinder(b);
} break;
case REQUEST_GPU: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
// TODO: this should be protected by a permission
gpu_info_t info;
sp<IGPUCallback> callback
= interface_cast<IGPUCallback>(data.readStrongBinder());
status_t res = requestGPU(callback, &info);
// FIXME: for now, we don't dynamically allocate the regions array
size_t maxCount = sizeof(info.regions)/sizeof(*info.regions);
if (info.count > maxCount)
return BAD_VALUE;
reply->writeStrongBinder(info.regs->asBinder());
reply->writeInt32(info.count);
for (size_t i=0 ; i<info.count ; i++) {
reply->writeStrongBinder(info.regions[i].region->asBinder());
reply->writeInt32(info.regions[i].reserved);
}
reply->writeInt32(res);
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
return NO_ERROR;
}
// ----------------------------------------------------------------------------
enum {
// Note: BOOT_FINISHED must remain this value, it is called by ActivityManagerService.
GPU_LOST = IBinder::FIRST_CALL_TRANSACTION
};
class BpGPUCallback : public BpInterface<IGPUCallback>
{
public:
BpGPUCallback(const sp<IBinder>& impl)
: BpInterface<IGPUCallback>(impl)
{
}
virtual void gpuLost()
{
Parcel data, reply;
data.writeInterfaceToken(IGPUCallback::getInterfaceDescriptor());
remote()->transact(GPU_LOST, data, &reply, IBinder::FLAG_ONEWAY);
}
};
IMPLEMENT_META_INTERFACE(GPUCallback, "android.ui.IGPUCallback");
status_t BnGPUCallback::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case GPU_LOST: {
CHECK_INTERFACE(IGPUCallback, data, reply);
gpuLost();
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
};