am 7623da43: split surface management from surface\'s buffers management
This commit is contained in:
@@ -122,7 +122,8 @@ public:
|
|||||||
volatile int8_t index[NUM_BUFFER_MAX];
|
volatile int8_t index[NUM_BUFFER_MAX];
|
||||||
|
|
||||||
int32_t identity; // surface's identity (const)
|
int32_t identity; // surface's identity (const)
|
||||||
int32_t reserved32[2];
|
int32_t token; // surface's token (for debugging)
|
||||||
|
int32_t reserved32[1];
|
||||||
Statistics stats;
|
Statistics stats;
|
||||||
int32_t reserved;
|
int32_t reserved;
|
||||||
BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes
|
BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes
|
||||||
|
|||||||
@@ -85,9 +85,12 @@ public:
|
|||||||
/* create connection with surface flinger, requires
|
/* create connection with surface flinger, requires
|
||||||
* ACCESS_SURFACE_FLINGER permission
|
* ACCESS_SURFACE_FLINGER permission
|
||||||
*/
|
*/
|
||||||
|
|
||||||
virtual sp<ISurfaceComposerClient> createConnection() = 0;
|
virtual sp<ISurfaceComposerClient> createConnection() = 0;
|
||||||
|
|
||||||
|
/* create a client connection with surface flinger
|
||||||
|
*/
|
||||||
|
virtual sp<ISurfaceComposerClient> createClientConnection() = 0;
|
||||||
|
|
||||||
/* retrieve the control block */
|
/* retrieve the control block */
|
||||||
virtual sp<IMemoryHeap> getCblk() const = 0;
|
virtual sp<IMemoryHeap> getCblk() const = 0;
|
||||||
|
|
||||||
@@ -123,6 +126,7 @@ public:
|
|||||||
// Java by ActivityManagerService.
|
// Java by ActivityManagerService.
|
||||||
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
|
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
|
||||||
CREATE_CONNECTION,
|
CREATE_CONNECTION,
|
||||||
|
CREATE_CLIENT_CONNECTION,
|
||||||
GET_CBLK,
|
GET_CBLK,
|
||||||
OPEN_GLOBAL_TRANSACTION,
|
OPEN_GLOBAL_TRANSACTION,
|
||||||
CLOSE_GLOBAL_TRANSACTION,
|
CLOSE_GLOBAL_TRANSACTION,
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
virtual sp<IMemoryHeap> getControlBlock() const = 0;
|
virtual sp<IMemoryHeap> getControlBlock() const = 0;
|
||||||
|
virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Requires ACCESS_SURFACE_FLINGER permission
|
* Requires ACCESS_SURFACE_FLINGER permission
|
||||||
|
|||||||
@@ -229,7 +229,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
void init();
|
void init();
|
||||||
status_t validate() const;
|
status_t validate() const;
|
||||||
status_t initCheck() const;
|
|
||||||
sp<ISurface> getISurface() const;
|
sp<ISurface> getISurface() const;
|
||||||
|
|
||||||
inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
|
inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
|
||||||
@@ -264,15 +263,15 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
sp<SurfaceClient> mClient;
|
GraphicBufferMapper& mBufferMapper;
|
||||||
|
SurfaceClient& mClient;
|
||||||
|
SharedBufferClient* mSharedBufferClient;
|
||||||
|
status_t mInitCheck;
|
||||||
sp<ISurface> mSurface;
|
sp<ISurface> mSurface;
|
||||||
SurfaceID mToken;
|
SurfaceID mToken;
|
||||||
uint32_t mIdentity;
|
uint32_t mIdentity;
|
||||||
PixelFormat mFormat;
|
PixelFormat mFormat;
|
||||||
uint32_t mFlags;
|
uint32_t mFlags;
|
||||||
GraphicBufferMapper& mBufferMapper;
|
|
||||||
SharedBufferClient* mSharedBufferClient;
|
|
||||||
status_t mInitCheck;
|
|
||||||
|
|
||||||
// protected by mSurfaceLock
|
// protected by mSurfaceLock
|
||||||
Rect mSwapRectangle;
|
Rect mSwapRectangle;
|
||||||
|
|||||||
@@ -22,8 +22,9 @@
|
|||||||
|
|
||||||
#include <binder/IBinder.h>
|
#include <binder/IBinder.h>
|
||||||
|
|
||||||
#include <utils/SortedVector.h>
|
|
||||||
#include <utils/RefBase.h>
|
#include <utils/RefBase.h>
|
||||||
|
#include <utils/Singleton.h>
|
||||||
|
#include <utils/SortedVector.h>
|
||||||
#include <utils/threads.h>
|
#include <utils/threads.h>
|
||||||
|
|
||||||
#include <ui/PixelFormat.h>
|
#include <ui/PixelFormat.h>
|
||||||
@@ -39,6 +40,22 @@ class Region;
|
|||||||
class SharedClient;
|
class SharedClient;
|
||||||
class ISurfaceComposer;
|
class ISurfaceComposer;
|
||||||
class DisplayInfo;
|
class DisplayInfo;
|
||||||
|
class surface_flinger_cblk_t;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class ComposerService : public Singleton<ComposerService>
|
||||||
|
{
|
||||||
|
// these are constants
|
||||||
|
sp<ISurfaceComposer> mComposerService;
|
||||||
|
sp<IMemoryHeap> mServerCblkMemory;
|
||||||
|
surface_flinger_cblk_t volatile* mServerCblk;
|
||||||
|
ComposerService();
|
||||||
|
friend class Singleton<ComposerService>;
|
||||||
|
public:
|
||||||
|
static sp<ISurfaceComposer> getComposerService();
|
||||||
|
static surface_flinger_cblk_t const volatile * getControlBlock();
|
||||||
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -152,25 +169,6 @@ private:
|
|||||||
sp<ISurfaceComposerClient> mClient;
|
sp<ISurfaceComposerClient> mClient;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class SurfaceClient : public RefBase
|
|
||||||
{
|
|
||||||
// all these attributes are constants
|
|
||||||
status_t mStatus;
|
|
||||||
SharedClient* mControl;
|
|
||||||
sp<IMemoryHeap> mControlMemory;
|
|
||||||
sp<IBinder> mConnection;
|
|
||||||
sp<ISurfaceComposer> mComposerService;
|
|
||||||
void init(const sp<IBinder>& conn);
|
|
||||||
public:
|
|
||||||
explicit SurfaceClient(const sp<IBinder>& conn);
|
|
||||||
explicit SurfaceClient(const sp<SurfaceComposerClient>& client);
|
|
||||||
status_t initCheck() const;
|
|
||||||
SharedClient* getSharedClient() const;
|
|
||||||
void signalServer() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
|
||||||
|
|||||||
@@ -93,10 +93,8 @@ public:
|
|||||||
|
|
||||||
void setIndex(int index);
|
void setIndex(int index);
|
||||||
int getIndex() const;
|
int getIndex() const;
|
||||||
void setVerticalStride(uint32_t vstride);
|
|
||||||
uint32_t getVerticalStride() const;
|
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
virtual ~GraphicBuffer();
|
virtual ~GraphicBuffer();
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -105,8 +103,12 @@ protected:
|
|||||||
ownData = 2,
|
ownData = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
|
inline const GraphicBufferMapper& getBufferMapper() const {
|
||||||
inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
|
return mBufferMapper;
|
||||||
|
}
|
||||||
|
inline GraphicBufferMapper& getBufferMapper() {
|
||||||
|
return mBufferMapper;
|
||||||
|
}
|
||||||
uint8_t mOwner;
|
uint8_t mOwner;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -134,7 +136,6 @@ private:
|
|||||||
|
|
||||||
GraphicBufferMapper& mBufferMapper;
|
GraphicBufferMapper& mBufferMapper;
|
||||||
ssize_t mInitCheck;
|
ssize_t mInitCheck;
|
||||||
uint32_t mVStride;
|
|
||||||
int mIndex;
|
int mIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -50,10 +50,9 @@ template <typename T> inline T min(T a, T b) {
|
|||||||
Layer::Layer(SurfaceFlinger* flinger,
|
Layer::Layer(SurfaceFlinger* flinger,
|
||||||
DisplayID display, const sp<Client>& client)
|
DisplayID display, const sp<Client>& client)
|
||||||
: LayerBaseClient(flinger, display, client),
|
: LayerBaseClient(flinger, display, client),
|
||||||
lcblk(NULL),
|
|
||||||
mSecure(false),
|
|
||||||
mNeedsBlending(true),
|
mNeedsBlending(true),
|
||||||
mNeedsDithering(false),
|
mNeedsDithering(false),
|
||||||
|
mSecure(false),
|
||||||
mTextureManager(mFlags),
|
mTextureManager(mFlags),
|
||||||
mBufferManager(mTextureManager),
|
mBufferManager(mTextureManager),
|
||||||
mWidth(0), mHeight(0), mFixedSize(false)
|
mWidth(0), mHeight(0), mFixedSize(false)
|
||||||
@@ -66,32 +65,43 @@ Layer::~Layer()
|
|||||||
EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
|
EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
|
||||||
mBufferManager.destroy(dpy);
|
mBufferManager.destroy(dpy);
|
||||||
|
|
||||||
// the actual buffers will be destroyed here
|
// we can use getUserClientUnsafe here because we know we're
|
||||||
delete lcblk;
|
// single-threaded at that point.
|
||||||
|
sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe());
|
||||||
|
if (ourClient != 0) {
|
||||||
|
ourClient->detachLayer(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get rid of this
|
status_t Layer::setToken(const sp<UserClient>& userClient,
|
||||||
void Layer::setToken(int32_t token)
|
SharedClient* sharedClient, int32_t token)
|
||||||
{
|
{
|
||||||
sp<Client> ourClient(client.promote());
|
SharedBufferServer* lcblk = new SharedBufferServer(
|
||||||
|
sharedClient, token, mBufferManager.getDefaultBufferCount(),
|
||||||
mToken = token;
|
|
||||||
|
|
||||||
// no OpenGL operation is possible here, since we might not be
|
|
||||||
// in the OpenGL thread.
|
|
||||||
lcblk = new SharedBufferServer(
|
|
||||||
ourClient->ctrlblk, token, mBufferManager.getDefaultBufferCount(),
|
|
||||||
getIdentity());
|
getIdentity());
|
||||||
|
|
||||||
mBufferManager.setActiveBufferIndex( lcblk->getFrontBuffer() );
|
status_t err = mUserClientRef.setToken(userClient, lcblk, token);
|
||||||
|
if (err != NO_ERROR) {
|
||||||
|
LOGE("ClientRef::setToken(%p, %p, %u) failed",
|
||||||
|
userClient.get(), lcblk, token);
|
||||||
|
delete lcblk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Layer::getToken() const
|
||||||
|
{
|
||||||
|
return mUserClientRef.getToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
// called with SurfaceFlinger::mStateLock as soon as the layer is entered
|
// called with SurfaceFlinger::mStateLock as soon as the layer is entered
|
||||||
// in the purgatory list
|
// in the purgatory list
|
||||||
void Layer::onRemoved()
|
void Layer::onRemoved()
|
||||||
{
|
{
|
||||||
sp<Client> ourClient(client.promote());
|
ClientRef::Access sharedClient(mUserClientRef);
|
||||||
if (ourClient != 0) {
|
SharedBufferServer* lcblk(sharedClient.get());
|
||||||
|
if (lcblk) {
|
||||||
// wake up the condition
|
// wake up the condition
|
||||||
lcblk->setStatus(NO_INIT);
|
lcblk->setStatus(NO_INIT);
|
||||||
}
|
}
|
||||||
@@ -237,10 +247,9 @@ bool Layer::needsFiltering() const
|
|||||||
|
|
||||||
status_t Layer::setBufferCount(int bufferCount)
|
status_t Layer::setBufferCount(int bufferCount)
|
||||||
{
|
{
|
||||||
// Ensures our client doesn't go away while we're accessing
|
ClientRef::Access sharedClient(mUserClientRef);
|
||||||
// the shared area.
|
SharedBufferServer* lcblk(sharedClient.get());
|
||||||
sp<Client> ourClient(client.promote());
|
if (!lcblk) {
|
||||||
if (ourClient == 0) {
|
|
||||||
// oops, the client is already gone
|
// oops, the client is already gone
|
||||||
return DEAD_OBJECT;
|
return DEAD_OBJECT;
|
||||||
}
|
}
|
||||||
@@ -259,7 +268,7 @@ sp<GraphicBuffer> Layer::requestBuffer(int index,
|
|||||||
{
|
{
|
||||||
sp<GraphicBuffer> buffer;
|
sp<GraphicBuffer> buffer;
|
||||||
|
|
||||||
if ((reqWidth | reqHeight | reqFormat) < 0)
|
if (int32_t(reqWidth | reqHeight | reqFormat) < 0)
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
||||||
if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
|
if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
|
||||||
@@ -267,8 +276,9 @@ sp<GraphicBuffer> Layer::requestBuffer(int index,
|
|||||||
|
|
||||||
// this ensures our client doesn't go away while we're accessing
|
// this ensures our client doesn't go away while we're accessing
|
||||||
// the shared area.
|
// the shared area.
|
||||||
sp<Client> ourClient(client.promote());
|
ClientRef::Access sharedClient(mUserClientRef);
|
||||||
if (ourClient == 0) {
|
SharedBufferServer* lcblk(sharedClient.get());
|
||||||
|
if (!lcblk) {
|
||||||
// oops, the client is already gone
|
// oops, the client is already gone
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
@@ -403,8 +413,9 @@ uint32_t Layer::doTransaction(uint32_t flags)
|
|||||||
// a buffer, it'll get the new size.
|
// a buffer, it'll get the new size.
|
||||||
setBufferSize(temp.requested_w, temp.requested_h);
|
setBufferSize(temp.requested_w, temp.requested_h);
|
||||||
|
|
||||||
sp<Client> ourClient(client.promote());
|
ClientRef::Access sharedClient(mUserClientRef);
|
||||||
if (ourClient != 0) {
|
SharedBufferServer* lcblk(sharedClient.get());
|
||||||
|
if (lcblk) {
|
||||||
// all buffers need reallocation
|
// all buffers need reallocation
|
||||||
lcblk->reallocateAll();
|
lcblk->reallocateAll();
|
||||||
}
|
}
|
||||||
@@ -442,8 +453,9 @@ bool Layer::isFixedSize() const {
|
|||||||
|
|
||||||
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
||||||
{
|
{
|
||||||
sp<Client> ourClient(client.promote());
|
ClientRef::Access sharedClient(mUserClientRef);
|
||||||
if (ourClient == 0) {
|
SharedBufferServer* lcblk(sharedClient.get());
|
||||||
|
if (!lcblk) {
|
||||||
// client died
|
// client died
|
||||||
recomputeVisibleRegions = true;
|
recomputeVisibleRegions = true;
|
||||||
return;
|
return;
|
||||||
@@ -458,14 +470,14 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buf < NO_ERROR) {
|
if (buf < NO_ERROR) {
|
||||||
LOGE("retireAndLock() buffer index (%d) out of range", buf);
|
LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
|
||||||
mPostedDirtyRegion.clear();
|
mPostedDirtyRegion.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we retired a buffer, which becomes the new front buffer
|
// we retired a buffer, which becomes the new front buffer
|
||||||
if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
|
if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
|
||||||
LOGE("retireAndLock() buffer index (%d) out of range", buf);
|
LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
|
||||||
mPostedDirtyRegion.clear();
|
mPostedDirtyRegion.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -560,11 +572,16 @@ void Layer::unlockPageFlip(
|
|||||||
|
|
||||||
void Layer::finishPageFlip()
|
void Layer::finishPageFlip()
|
||||||
{
|
{
|
||||||
sp<Client> ourClient(client.promote());
|
ClientRef::Access sharedClient(mUserClientRef);
|
||||||
if (ourClient != 0) {
|
SharedBufferServer* lcblk(sharedClient.get());
|
||||||
|
if (lcblk) {
|
||||||
int buf = mBufferManager.getActiveBufferIndex();
|
int buf = mBufferManager.getActiveBufferIndex();
|
||||||
status_t err = lcblk->unlock( buf );
|
if (buf >= 0) {
|
||||||
LOGE_IF(err!=NO_ERROR, "layer %p, buffer=%d wasn't locked!", this, buf);
|
status_t err = lcblk->unlock( buf );
|
||||||
|
LOGE_IF(err!=NO_ERROR,
|
||||||
|
"layer %p, buffer=%d wasn't locked!",
|
||||||
|
this, buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,8 +590,15 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
|
|||||||
{
|
{
|
||||||
LayerBaseClient::dump(result, buffer, SIZE);
|
LayerBaseClient::dump(result, buffer, SIZE);
|
||||||
|
|
||||||
SharedBufferStack::Statistics stats = lcblk->getStats();
|
ClientRef::Access sharedClient(mUserClientRef);
|
||||||
result.append( lcblk->dump(" ") );
|
SharedBufferServer* lcblk(sharedClient.get());
|
||||||
|
uint32_t totalTime = 0;
|
||||||
|
if (lcblk) {
|
||||||
|
SharedBufferStack::Statistics stats = lcblk->getStats();
|
||||||
|
totalTime= stats.totalTime;
|
||||||
|
result.append( lcblk->dump(" ") );
|
||||||
|
}
|
||||||
|
|
||||||
sp<const GraphicBuffer> buf0(getBuffer(0));
|
sp<const GraphicBuffer> buf0(getBuffer(0));
|
||||||
sp<const GraphicBuffer> buf1(getBuffer(1));
|
sp<const GraphicBuffer> buf1(getBuffer(1));
|
||||||
uint32_t w0=0, h0=0, s0=0;
|
uint32_t w0=0, h0=0, s0=0;
|
||||||
@@ -593,18 +617,59 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
|
|||||||
" "
|
" "
|
||||||
"format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
|
"format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
|
||||||
" freezeLock=%p, dq-q-time=%u us\n",
|
" freezeLock=%p, dq-q-time=%u us\n",
|
||||||
pixelFormat(),
|
mFormat, w0, h0, s0, w1, h1, s1,
|
||||||
w0, h0, s0, w1, h1, s1,
|
getFreezeLock().get(), totalTime);
|
||||||
getFreezeLock().get(), stats.totalTime);
|
|
||||||
|
|
||||||
result.append(buffer);
|
result.append(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Layer::ClientRef::ClientRef()
|
||||||
|
: mToken(-1) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Layer::ClientRef::~ClientRef() {
|
||||||
|
delete lcblk;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Layer::ClientRef::getToken() const {
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
return mToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
|
||||||
|
SharedBufferServer* sharedClient, int32_t token) {
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
if (mToken >= 0)
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
mUserClient = uc;
|
||||||
|
mToken = token;
|
||||||
|
lcblk = sharedClient;
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
|
||||||
|
return mUserClient.promote();
|
||||||
|
}
|
||||||
|
|
||||||
|
// this class gives us access to SharedBufferServer safely
|
||||||
|
// it makes sure the UserClient (and its associated shared memory)
|
||||||
|
// won't go away while we're accessing it.
|
||||||
|
Layer::ClientRef::Access::Access(const ClientRef& ref)
|
||||||
|
: lcblk(0)
|
||||||
|
{
|
||||||
|
Mutex::Autolock _l(ref.mLock);
|
||||||
|
mUserClientStrongRef = ref.mUserClient.promote();
|
||||||
|
if (mUserClientStrongRef != 0)
|
||||||
|
lcblk = ref.lcblk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
Layer::BufferManager::BufferManager(TextureManager& tm)
|
Layer::BufferManager::BufferManager(TextureManager& tm)
|
||||||
: mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
|
: mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
|
||||||
mActiveBuffer(0), mFailover(false)
|
mActiveBuffer(-1), mFailover(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,7 +690,6 @@ sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
|
status_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
|
||||||
// TODO: need to validate 'index'
|
|
||||||
mActiveBuffer = index;
|
mActiveBuffer = index;
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
@@ -636,7 +700,7 @@ size_t Layer::BufferManager::getActiveBufferIndex() const {
|
|||||||
|
|
||||||
Texture Layer::BufferManager::getActiveTexture() const {
|
Texture Layer::BufferManager::getActiveTexture() const {
|
||||||
Texture res;
|
Texture res;
|
||||||
if (mFailover) {
|
if (mFailover || mActiveBuffer<0) {
|
||||||
res = mFailoverTexture;
|
res = mFailoverTexture;
|
||||||
} else {
|
} else {
|
||||||
static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture;
|
static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture;
|
||||||
@@ -645,10 +709,14 @@ Texture Layer::BufferManager::getActiveTexture() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
|
sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
|
||||||
const size_t activeBuffer = mActiveBuffer;
|
sp<GraphicBuffer> result;
|
||||||
BufferData const * const buffers = mBufferData;
|
const ssize_t activeBuffer = mActiveBuffer;
|
||||||
Mutex::Autolock _l(mLock);
|
if (activeBuffer >= 0) {
|
||||||
return buffers[activeBuffer].buffer;
|
BufferData const * const buffers = mBufferData;
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
result = buffers[activeBuffer].buffer;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
|
sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
|
||||||
@@ -692,19 +760,22 @@ status_t Layer::BufferManager::destroy(EGLDisplay dpy)
|
|||||||
status_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
|
status_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
|
||||||
const sp<GraphicBuffer>& buffer)
|
const sp<GraphicBuffer>& buffer)
|
||||||
{
|
{
|
||||||
size_t index = mActiveBuffer;
|
status_t err = NO_INIT;
|
||||||
Image& texture(mBufferData[index].texture);
|
ssize_t index = mActiveBuffer;
|
||||||
status_t err = mTextureManager.initEglImage(&texture, dpy, buffer);
|
if (index >= 0) {
|
||||||
// if EGLImage fails, we switch to regular texture mode, and we
|
Image& texture(mBufferData[index].texture);
|
||||||
// free all resources associated with using EGLImages.
|
err = mTextureManager.initEglImage(&texture, dpy, buffer);
|
||||||
if (err == NO_ERROR) {
|
// if EGLImage fails, we switch to regular texture mode, and we
|
||||||
mFailover = false;
|
// free all resources associated with using EGLImages.
|
||||||
destroyTexture(&mFailoverTexture, dpy);
|
if (err == NO_ERROR) {
|
||||||
} else {
|
mFailover = false;
|
||||||
mFailover = true;
|
destroyTexture(&mFailoverTexture, dpy);
|
||||||
const size_t num = mNumBuffers;
|
} else {
|
||||||
for (size_t i=0 ; i<num ; i++) {
|
mFailover = true;
|
||||||
destroyTexture(&mBufferData[i].texture, dpy);
|
const size_t num = mNumBuffers;
|
||||||
|
for (size_t i=0 ; i<num ; i++) {
|
||||||
|
destroyTexture(&mBufferData[i].texture, dpy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ namespace android {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
|
class UserClient;
|
||||||
class FreezeLock;
|
class FreezeLock;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -45,21 +46,26 @@ class FreezeLock;
|
|||||||
class Layer : public LayerBaseClient
|
class Layer : public LayerBaseClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// lcblk is (almost) only accessed from the main SF thread, in the places
|
Layer(SurfaceFlinger* flinger, DisplayID display,
|
||||||
// where it's not, a reference to Client must be held
|
const sp<Client>& client);
|
||||||
SharedBufferServer* lcblk;
|
|
||||||
|
|
||||||
Layer(SurfaceFlinger* flinger, DisplayID display,
|
virtual ~Layer();
|
||||||
const sp<Client>& client);
|
|
||||||
|
|
||||||
virtual ~Layer();
|
virtual const char* getTypeId() const { return "Layer"; }
|
||||||
|
|
||||||
|
// the this layer's size and format
|
||||||
status_t setBuffers(uint32_t w, uint32_t h,
|
status_t setBuffers(uint32_t w, uint32_t h,
|
||||||
PixelFormat format, uint32_t flags=0);
|
PixelFormat format, uint32_t flags=0);
|
||||||
|
|
||||||
|
// associate a UserClient to this Layer
|
||||||
|
status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx);
|
||||||
|
int32_t getToken() const;
|
||||||
|
|
||||||
|
// Set this Layer's buffers size
|
||||||
void setBufferSize(uint32_t w, uint32_t h);
|
void setBufferSize(uint32_t w, uint32_t h);
|
||||||
bool isFixedSize() const;
|
bool isFixedSize() const;
|
||||||
|
|
||||||
|
// LayerBase interface
|
||||||
virtual void onDraw(const Region& clip) const;
|
virtual void onDraw(const Region& clip) const;
|
||||||
virtual uint32_t doTransaction(uint32_t transactionFlags);
|
virtual uint32_t doTransaction(uint32_t transactionFlags);
|
||||||
virtual void lockPageFlip(bool& recomputeVisibleRegions);
|
virtual void lockPageFlip(bool& recomputeVisibleRegions);
|
||||||
@@ -72,28 +78,26 @@ public:
|
|||||||
virtual sp<Surface> createSurface() const;
|
virtual sp<Surface> createSurface() const;
|
||||||
virtual status_t ditch();
|
virtual status_t ditch();
|
||||||
virtual void onRemoved();
|
virtual void onRemoved();
|
||||||
|
|
||||||
// only for debugging
|
|
||||||
inline sp<GraphicBuffer> getBuffer(int i) const { return mBufferManager.getBuffer(i); }
|
|
||||||
// only for debugging
|
|
||||||
inline const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; }
|
|
||||||
// only for debugging
|
|
||||||
inline PixelFormat pixelFormat() const { return mFormat; }
|
|
||||||
|
|
||||||
virtual const char* getTypeId() const { return "Layer"; }
|
// only for debugging
|
||||||
|
inline sp<GraphicBuffer> getBuffer(int i) const {
|
||||||
|
return mBufferManager.getBuffer(i); }
|
||||||
|
// only for debugging
|
||||||
|
inline const sp<FreezeLock>& getFreezeLock() const {
|
||||||
|
return mFreezeLock; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void dump(String8& result, char* scratch, size_t size) const;
|
virtual void dump(String8& result, char* scratch, size_t size) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reloadTexture(const Region& dirty);
|
void reloadTexture(const Region& dirty);
|
||||||
|
|
||||||
uint32_t getEffectiveUsage(uint32_t usage) const;
|
uint32_t getEffectiveUsage(uint32_t usage) const;
|
||||||
|
|
||||||
sp<GraphicBuffer> requestBuffer(int bufferIdx,
|
sp<GraphicBuffer> requestBuffer(int bufferIdx,
|
||||||
uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
|
uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
|
||||||
status_t setBufferCount(int bufferCount);
|
status_t setBufferCount(int bufferCount);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
class SurfaceLayer : public LayerBaseClient::Surface {
|
class SurfaceLayer : public LayerBaseClient::Surface {
|
||||||
public:
|
public:
|
||||||
SurfaceLayer(const sp<SurfaceFlinger>& flinger, const sp<Layer>& owner);
|
SurfaceLayer(const sp<SurfaceFlinger>& flinger, const sp<Layer>& owner);
|
||||||
@@ -107,93 +111,120 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
friend class SurfaceLayer;
|
friend class SurfaceLayer;
|
||||||
|
|
||||||
sp<Surface> mSurface;
|
|
||||||
|
|
||||||
bool mSecure;
|
// -----------------------------------------------------------------------
|
||||||
int32_t mFrontBufferIndex;
|
|
||||||
bool mNeedsBlending;
|
|
||||||
bool mNeedsDithering;
|
|
||||||
Region mPostedDirtyRegion;
|
|
||||||
sp<FreezeLock> mFreezeLock;
|
|
||||||
PixelFormat mFormat;
|
|
||||||
|
|
||||||
class BufferManager {
|
class ClientRef {
|
||||||
static const size_t NUM_BUFFERS = 2;
|
ClientRef(const ClientRef& rhs);
|
||||||
struct BufferData {
|
ClientRef& operator = (const ClientRef& rhs);
|
||||||
sp<GraphicBuffer> buffer;
|
mutable Mutex mLock;
|
||||||
Image texture;
|
// binder thread, page-flip thread
|
||||||
};
|
SharedBufferServer* lcblk;
|
||||||
// this lock protect mBufferData[].buffer but since there
|
wp<UserClient> mUserClient;
|
||||||
// is very little contention, we have only one like for
|
int32_t mToken;
|
||||||
// the whole array, we also use it to protect mNumBuffers.
|
public:
|
||||||
mutable Mutex mLock;
|
ClientRef();
|
||||||
BufferData mBufferData[SharedBufferStack::NUM_BUFFER_MAX];
|
~ClientRef();
|
||||||
size_t mNumBuffers;
|
int32_t getToken() const;
|
||||||
Texture mFailoverTexture;
|
status_t setToken(const sp<UserClient>& uc,
|
||||||
TextureManager& mTextureManager;
|
SharedBufferServer* sharedClient, int32_t token);
|
||||||
ssize_t mActiveBuffer;
|
sp<UserClient> getUserClientUnsafe() const;
|
||||||
bool mFailover;
|
class Access {
|
||||||
static status_t destroyTexture(Image* tex, EGLDisplay dpy);
|
Access(const Access& rhs);
|
||||||
|
Access& operator = (const Access& rhs);
|
||||||
|
sp<UserClient> mUserClientStrongRef;
|
||||||
|
SharedBufferServer* lcblk;
|
||||||
|
public:
|
||||||
|
Access(const ClientRef& ref);
|
||||||
|
inline SharedBufferServer* get() const { return lcblk; }
|
||||||
|
};
|
||||||
|
friend class Access;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
// -----------------------------------------------------------------------
|
||||||
static size_t getDefaultBufferCount() { return NUM_BUFFERS; }
|
|
||||||
BufferManager(TextureManager& tm);
|
|
||||||
~BufferManager();
|
|
||||||
|
|
||||||
// detach/attach buffer from/to given index
|
class BufferManager {
|
||||||
sp<GraphicBuffer> detachBuffer(size_t index);
|
static const size_t NUM_BUFFERS = 2;
|
||||||
status_t attachBuffer(size_t index, const sp<GraphicBuffer>& buffer);
|
struct BufferData {
|
||||||
|
sp<GraphicBuffer> buffer;
|
||||||
|
Image texture;
|
||||||
|
};
|
||||||
|
// this lock protect mBufferData[].buffer but since there
|
||||||
|
// is very little contention, we have only one like for
|
||||||
|
// the whole array, we also use it to protect mNumBuffers.
|
||||||
|
mutable Mutex mLock;
|
||||||
|
BufferData mBufferData[SharedBufferStack::NUM_BUFFER_MAX];
|
||||||
|
size_t mNumBuffers;
|
||||||
|
Texture mFailoverTexture;
|
||||||
|
TextureManager& mTextureManager;
|
||||||
|
ssize_t mActiveBuffer;
|
||||||
|
bool mFailover;
|
||||||
|
static status_t destroyTexture(Image* tex, EGLDisplay dpy);
|
||||||
|
|
||||||
// resize the number of active buffers
|
public:
|
||||||
status_t resize(size_t size);
|
static size_t getDefaultBufferCount() { return NUM_BUFFERS; }
|
||||||
|
BufferManager(TextureManager& tm);
|
||||||
|
~BufferManager();
|
||||||
|
|
||||||
// ----------------------------------------------
|
// detach/attach buffer from/to given index
|
||||||
// must be called from GL thread
|
sp<GraphicBuffer> detachBuffer(size_t index);
|
||||||
|
status_t attachBuffer(size_t index, const sp<GraphicBuffer>& buffer);
|
||||||
|
// resize the number of active buffers
|
||||||
|
status_t resize(size_t size);
|
||||||
|
|
||||||
// set/get active buffer index
|
// ----------------------------------------------
|
||||||
status_t setActiveBufferIndex(size_t index);
|
// must be called from GL thread
|
||||||
size_t getActiveBufferIndex() const;
|
|
||||||
|
|
||||||
// return the active buffer
|
// set/get active buffer index
|
||||||
sp<GraphicBuffer> getActiveBuffer() const;
|
status_t setActiveBufferIndex(size_t index);
|
||||||
|
size_t getActiveBufferIndex() const;
|
||||||
|
// return the active buffer
|
||||||
|
sp<GraphicBuffer> getActiveBuffer() const;
|
||||||
|
// return the active texture (or fail-over)
|
||||||
|
Texture getActiveTexture() const;
|
||||||
|
// frees resources associated with all buffers
|
||||||
|
status_t destroy(EGLDisplay dpy);
|
||||||
|
// load bitmap data into the active buffer
|
||||||
|
status_t loadTexture(const Region& dirty, const GGLSurface& t);
|
||||||
|
// make active buffer an EGLImage if needed
|
||||||
|
status_t initEglImage(EGLDisplay dpy,
|
||||||
|
const sp<GraphicBuffer>& buffer);
|
||||||
|
|
||||||
// return the active texture (or fail-over)
|
// ----------------------------------------------
|
||||||
Texture getActiveTexture() const;
|
// only for debugging
|
||||||
|
sp<GraphicBuffer> getBuffer(size_t index) const;
|
||||||
|
};
|
||||||
|
|
||||||
// frees resources associated with all buffers
|
// -----------------------------------------------------------------------
|
||||||
status_t destroy(EGLDisplay dpy);
|
|
||||||
|
|
||||||
// load bitmap data into the active buffer
|
// thread-safe
|
||||||
status_t loadTexture(const Region& dirty, const GGLSurface& t);
|
ClientRef mUserClientRef;
|
||||||
|
|
||||||
// make active buffer an EGLImage if needed
|
// constants
|
||||||
status_t initEglImage(EGLDisplay dpy,
|
sp<Surface> mSurface;
|
||||||
const sp<GraphicBuffer>& buffer);
|
PixelFormat mFormat;
|
||||||
|
bool mNeedsBlending;
|
||||||
|
bool mNeedsDithering;
|
||||||
|
|
||||||
// ----------------------------------------------
|
// page-flip thread (currently main thread)
|
||||||
// only for debugging
|
bool mSecure;
|
||||||
sp<GraphicBuffer> getBuffer(size_t index) const;
|
Region mPostedDirtyRegion;
|
||||||
};
|
|
||||||
|
|
||||||
TextureManager mTextureManager;
|
// page-flip thread and transaction thread (currently main thread)
|
||||||
BufferManager mBufferManager;
|
sp<FreezeLock> mFreezeLock;
|
||||||
|
|
||||||
// this lock protects mWidth and mHeight which are accessed from
|
// see threading usage in declaration
|
||||||
// the main thread and requestBuffer's binder transaction thread.
|
TextureManager mTextureManager;
|
||||||
mutable Mutex mLock;
|
BufferManager mBufferManager;
|
||||||
uint32_t mWidth;
|
|
||||||
uint32_t mHeight;
|
|
||||||
uint32_t mReqWidth;
|
|
||||||
uint32_t mReqHeight;
|
|
||||||
uint32_t mReqFormat;
|
|
||||||
bool mFixedSize;
|
|
||||||
|
|
||||||
// TODO: get rid of this
|
// binder thread, transaction thread
|
||||||
private:
|
mutable Mutex mLock;
|
||||||
virtual void setToken(int32_t token);
|
uint32_t mWidth;
|
||||||
virtual int32_t getToken() const { return mToken; }
|
uint32_t mHeight;
|
||||||
int32_t mToken;
|
uint32_t mReqWidth;
|
||||||
|
uint32_t mReqHeight;
|
||||||
|
uint32_t mReqFormat;
|
||||||
|
bool mFixedSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -151,7 +151,6 @@ bool LayerBase::setAlpha(uint8_t alpha) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
|
bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
|
||||||
// TODO: check the matrix has changed
|
|
||||||
mCurrentState.sequence++;
|
mCurrentState.sequence++;
|
||||||
mCurrentState.transform.set(
|
mCurrentState.transform.set(
|
||||||
matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
|
matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
|
||||||
@@ -159,7 +158,6 @@ bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool LayerBase::setTransparentRegionHint(const Region& transparent) {
|
bool LayerBase::setTransparentRegionHint(const Region& transparent) {
|
||||||
// TODO: check the region has changed
|
|
||||||
mCurrentState.sequence++;
|
mCurrentState.sequence++;
|
||||||
mCurrentState.transparentRegion = transparent;
|
mCurrentState.transparentRegion = transparent;
|
||||||
requestTransaction();
|
requestTransaction();
|
||||||
@@ -489,16 +487,16 @@ int32_t LayerBaseClient::sIdentity = 1;
|
|||||||
|
|
||||||
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client)
|
const sp<Client>& client)
|
||||||
: LayerBase(flinger, display), client(client),
|
: LayerBase(flinger, display), mClientRef(client),
|
||||||
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
|
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerBaseClient::~LayerBaseClient()
|
LayerBaseClient::~LayerBaseClient()
|
||||||
{
|
{
|
||||||
sp<Client> c(client.promote());
|
sp<Client> c(mClientRef.promote());
|
||||||
if (c != 0) {
|
if (c != 0) {
|
||||||
c->free(this);
|
c->detachLayer(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,7 +522,7 @@ void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
|
|||||||
{
|
{
|
||||||
LayerBase::dump(result, buffer, SIZE);
|
LayerBase::dump(result, buffer, SIZE);
|
||||||
|
|
||||||
sp<Client> client(this->client.promote());
|
sp<Client> client(mClientRef.promote());
|
||||||
snprintf(buffer, SIZE,
|
snprintf(buffer, SIZE,
|
||||||
" name=%s\n"
|
" name=%s\n"
|
||||||
" client=%p, identity=%u\n",
|
" client=%p, identity=%u\n",
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class DisplayHardware;
|
|||||||
class Client;
|
class Client;
|
||||||
class GraphicBuffer;
|
class GraphicBuffer;
|
||||||
class GraphicPlane;
|
class GraphicPlane;
|
||||||
|
class LayerBaseClient;
|
||||||
class SurfaceFlinger;
|
class SurfaceFlinger;
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
@@ -100,6 +101,8 @@ public:
|
|||||||
|
|
||||||
void invalidate();
|
void invalidate();
|
||||||
|
|
||||||
|
virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; }
|
||||||
|
|
||||||
virtual const char* getTypeId() const { return "LayerBase"; }
|
virtual const char* getTypeId() const { return "LayerBase"; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -268,14 +271,14 @@ class LayerBaseClient : public LayerBase
|
|||||||
public:
|
public:
|
||||||
class Surface;
|
class Surface;
|
||||||
|
|
||||||
const wp<Client> client;
|
|
||||||
|
|
||||||
LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client);
|
const sp<Client>& client);
|
||||||
virtual ~LayerBaseClient();
|
virtual ~LayerBaseClient();
|
||||||
|
|
||||||
sp<Surface> getSurface();
|
sp<Surface> getSurface();
|
||||||
virtual sp<Surface> createSurface() const;
|
virtual sp<Surface> createSurface() const;
|
||||||
|
virtual sp<LayerBaseClient> getLayerBaseClient() const {
|
||||||
|
return const_cast<LayerBaseClient*>(this); }
|
||||||
virtual const char* getTypeId() const { return "LayerBaseClient"; }
|
virtual const char* getTypeId() const { return "LayerBaseClient"; }
|
||||||
|
|
||||||
uint32_t getIdentity() const { return mIdentity; }
|
uint32_t getIdentity() const { return mIdentity; }
|
||||||
@@ -318,14 +321,10 @@ protected:
|
|||||||
private:
|
private:
|
||||||
mutable Mutex mLock;
|
mutable Mutex mLock;
|
||||||
mutable wp<Surface> mClientSurface;
|
mutable wp<Surface> mClientSurface;
|
||||||
|
const wp<Client> mClientRef;
|
||||||
// only read
|
// only read
|
||||||
const uint32_t mIdentity;
|
const uint32_t mIdentity;
|
||||||
static int32_t sIdentity;
|
static int32_t sIdentity;
|
||||||
|
|
||||||
// TODO: get rid of this
|
|
||||||
public:
|
|
||||||
virtual void setToken(int32_t token) { }
|
|
||||||
virtual int32_t getToken() const { return -1; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -236,6 +236,18 @@ sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
|
|||||||
return bclient;
|
return bclient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
|
||||||
|
{
|
||||||
|
sp<ISurfaceComposerClient> bclient;
|
||||||
|
sp<UserClient> client(new UserClient(this));
|
||||||
|
status_t err = client->initCheck();
|
||||||
|
if (err == NO_ERROR) {
|
||||||
|
bclient = client;
|
||||||
|
}
|
||||||
|
return bclient;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
|
const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
|
||||||
{
|
{
|
||||||
LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
|
LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
|
||||||
@@ -772,7 +784,8 @@ void SurfaceFlinger::commitTransaction()
|
|||||||
void SurfaceFlinger::handlePageFlip()
|
void SurfaceFlinger::handlePageFlip()
|
||||||
{
|
{
|
||||||
bool visibleRegions = mVisibleRegionsDirty;
|
bool visibleRegions = mVisibleRegionsDirty;
|
||||||
LayerVector& currentLayers = const_cast<LayerVector&>(mDrawingState.layersSortedByZ);
|
LayerVector& currentLayers = const_cast<LayerVector&>(
|
||||||
|
mDrawingState.layersSortedByZ);
|
||||||
visibleRegions |= lockPageFlip(currentLayers);
|
visibleRegions |= lockPageFlip(currentLayers);
|
||||||
|
|
||||||
const DisplayHardware& hw = graphicPlane(0).displayHardware();
|
const DisplayHardware& hw = graphicPlane(0).displayHardware();
|
||||||
@@ -794,7 +807,7 @@ bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
|
|||||||
size_t count = currentLayers.size();
|
size_t count = currentLayers.size();
|
||||||
sp<LayerBase> const* layers = currentLayers.array();
|
sp<LayerBase> const* layers = currentLayers.array();
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
const sp<LayerBase>& layer = layers[i];
|
const sp<LayerBase>& layer(layers[i]);
|
||||||
layer->lockPageFlip(recomputeVisibleRegions);
|
layer->lockPageFlip(recomputeVisibleRegions);
|
||||||
}
|
}
|
||||||
return recomputeVisibleRegions;
|
return recomputeVisibleRegions;
|
||||||
@@ -807,7 +820,7 @@ void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
|
|||||||
size_t count = currentLayers.size();
|
size_t count = currentLayers.size();
|
||||||
sp<LayerBase> const* layers = currentLayers.array();
|
sp<LayerBase> const* layers = currentLayers.array();
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
const sp<LayerBase>& layer = layers[i];
|
const sp<LayerBase>& layer(layers[i]);
|
||||||
layer->unlockPageFlip(planeTransform, mDirtyRegion);
|
layer->unlockPageFlip(planeTransform, mDirtyRegion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -839,7 +852,7 @@ void SurfaceFlinger::handleRepaint()
|
|||||||
// takes a rectangle, we must make sure to update that whole
|
// takes a rectangle, we must make sure to update that whole
|
||||||
// rectangle in that case
|
// rectangle in that case
|
||||||
if (flags & DisplayHardware::SWAP_RECTANGLE) {
|
if (flags & DisplayHardware::SWAP_RECTANGLE) {
|
||||||
// FIXME: we really should be able to pass a region to
|
// TODO: we really should be able to pass a region to
|
||||||
// SWAP_RECTANGLE so that we don't have to redraw all this.
|
// SWAP_RECTANGLE so that we don't have to redraw all this.
|
||||||
mDirtyRegion.set(mInvalidRegion.bounds());
|
mDirtyRegion.set(mInvalidRegion.bounds());
|
||||||
} else {
|
} else {
|
||||||
@@ -1060,6 +1073,10 @@ status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
|
|||||||
|
|
||||||
status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
|
status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
|
||||||
{
|
{
|
||||||
|
sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
|
||||||
|
if (lbc != 0) {
|
||||||
|
mLayerMap.removeItem( lbc->getSurface()->asBinder() );
|
||||||
|
}
|
||||||
ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
|
ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
mLayersRemoved = true;
|
mLayersRemoved = true;
|
||||||
@@ -1192,12 +1209,14 @@ sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
|
//LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
|
||||||
|
sp<Layer> normalLayer;
|
||||||
switch (flags & eFXSurfaceMask) {
|
switch (flags & eFXSurfaceMask) {
|
||||||
case eFXSurfaceNormal:
|
case eFXSurfaceNormal:
|
||||||
if (UNLIKELY(flags & ePushBuffers)) {
|
if (UNLIKELY(flags & ePushBuffers)) {
|
||||||
layer = createPushBuffersSurface(client, d, w, h, flags);
|
layer = createPushBuffersSurface(client, d, w, h, flags);
|
||||||
} else {
|
} else {
|
||||||
layer = createNormalSurface(client, d, w, h, flags, format);
|
normalLayer = createNormalSurface(client, d, w, h, flags, format);
|
||||||
|
layer = normalLayer;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case eFXSurfaceBlur:
|
case eFXSurfaceBlur:
|
||||||
@@ -1212,6 +1231,7 @@ sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
|
|||||||
layer->initStates(w, h, flags);
|
layer->initStates(w, h, flags);
|
||||||
layer->setName(name);
|
layer->setName(name);
|
||||||
ssize_t token = addClientLayer(client, layer);
|
ssize_t token = addClientLayer(client, layer);
|
||||||
|
|
||||||
surfaceHandle = layer->getSurface();
|
surfaceHandle = layer->getSurface();
|
||||||
if (surfaceHandle != 0) {
|
if (surfaceHandle != 0) {
|
||||||
params->token = token;
|
params->token = token;
|
||||||
@@ -1219,14 +1239,19 @@ sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
|
|||||||
params->width = w;
|
params->width = w;
|
||||||
params->height = h;
|
params->height = h;
|
||||||
params->format = format;
|
params->format = format;
|
||||||
|
if (normalLayer != 0) {
|
||||||
|
Mutex::Autolock _l(mStateLock);
|
||||||
|
mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTransactionFlags(eTransactionNeeded);
|
setTransactionFlags(eTransactionNeeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
return surfaceHandle;
|
return surfaceHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<LayerBaseClient> SurfaceFlinger::createNormalSurface(
|
sp<Layer> SurfaceFlinger::createNormalSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
uint32_t w, uint32_t h, uint32_t flags,
|
uint32_t w, uint32_t h, uint32_t flags,
|
||||||
PixelFormat& format)
|
PixelFormat& format)
|
||||||
@@ -1251,7 +1276,7 @@ sp<LayerBaseClient> SurfaceFlinger::createNormalSurface(
|
|||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<LayerBaseClient> SurfaceFlinger::createBlurSurface(
|
sp<LayerBlur> SurfaceFlinger::createBlurSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
uint32_t w, uint32_t h, uint32_t flags)
|
uint32_t w, uint32_t h, uint32_t flags)
|
||||||
{
|
{
|
||||||
@@ -1260,7 +1285,7 @@ sp<LayerBaseClient> SurfaceFlinger::createBlurSurface(
|
|||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<LayerBaseClient> SurfaceFlinger::createDimSurface(
|
sp<LayerDim> SurfaceFlinger::createDimSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
uint32_t w, uint32_t h, uint32_t flags)
|
uint32_t w, uint32_t h, uint32_t flags)
|
||||||
{
|
{
|
||||||
@@ -1269,7 +1294,7 @@ sp<LayerBaseClient> SurfaceFlinger::createDimSurface(
|
|||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<LayerBaseClient> SurfaceFlinger::createPushBuffersSurface(
|
sp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
uint32_t w, uint32_t h, uint32_t flags)
|
uint32_t w, uint32_t h, uint32_t flags)
|
||||||
{
|
{
|
||||||
@@ -1567,32 +1592,24 @@ status_t SurfaceFlinger::onTransact(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
#if 0
|
|
||||||
#pragma mark -
|
sp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
|
||||||
#endif
|
{
|
||||||
|
sp<Layer> result;
|
||||||
|
Mutex::Autolock _l(mStateLock);
|
||||||
|
result = mLayerMap.valueFor( sur->asBinder() ).promote();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
Client::Client(const sp<SurfaceFlinger>& flinger)
|
Client::Client(const sp<SurfaceFlinger>& flinger)
|
||||||
: ctrlblk(0), mBitmap(0), mFlinger(flinger)
|
: mFlinger(flinger), mNameGenerator(1)
|
||||||
{
|
{
|
||||||
const int pgsize = getpagesize();
|
|
||||||
const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
|
|
||||||
|
|
||||||
mCblkHeap = new MemoryHeapBase(cblksize, 0,
|
|
||||||
"SurfaceFlinger Client control-block");
|
|
||||||
|
|
||||||
ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
|
|
||||||
if (ctrlblk) { // construct the shared structure in-place.
|
|
||||||
new(ctrlblk) SharedClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::~Client()
|
Client::~Client()
|
||||||
{
|
{
|
||||||
if (ctrlblk) {
|
|
||||||
ctrlblk->~SharedClient(); // destroy our shared-structure.
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t count = mLayers.size();
|
const size_t count = mLayers.size();
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
|
sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
|
||||||
@@ -1603,32 +1620,18 @@ Client::~Client()
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t Client::initCheck() const {
|
status_t Client::initCheck() const {
|
||||||
return ctrlblk == 0 ? NO_INIT : NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
|
ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
|
||||||
{
|
{
|
||||||
// TODO: get rid of this
|
int32_t name = android_atomic_inc(&mNameGenerator);
|
||||||
int32_t name = 0;
|
|
||||||
while (mBitmap & (1LU<<name)) {
|
|
||||||
name++;
|
|
||||||
if (name >= 31)
|
|
||||||
return NO_MEMORY;
|
|
||||||
}
|
|
||||||
mBitmap |= 1LU<<name;
|
|
||||||
layer->setToken(name);
|
|
||||||
mLayers.add(name, layer);
|
mLayers.add(name, layer);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::free(LayerBaseClient const* layer)
|
void Client::detachLayer(const LayerBaseClient* layer)
|
||||||
{
|
{
|
||||||
// TODO: get rid of this
|
|
||||||
int32_t name = layer->getToken();
|
|
||||||
if (name >= 0) {
|
|
||||||
mBitmap &= ~(1LU<<name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we do a linear search here, because this doesn't happen often
|
// we do a linear search here, because this doesn't happen often
|
||||||
const size_t count = mLayers.size();
|
const size_t count = mLayers.size();
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
@@ -1649,12 +1652,15 @@ sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sp<IMemoryHeap> Client::getControlBlock() const {
|
sp<IMemoryHeap> Client::getControlBlock() const {
|
||||||
return mCblkHeap;
|
return 0;
|
||||||
|
}
|
||||||
|
ssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
sp<ISurface> Client::createSurface(
|
sp<ISurface> Client::createSurface(
|
||||||
ISurfaceComposerClient::surface_data_t* params,
|
ISurfaceComposerClient::surface_data_t* params, int pid,
|
||||||
int pid, const String8& name,
|
const String8& name,
|
||||||
DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
|
DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
|
||||||
uint32_t flags)
|
uint32_t flags)
|
||||||
{
|
{
|
||||||
return mFlinger->createSurface(this, pid, name, params,
|
return mFlinger->createSurface(this, pid, name, params,
|
||||||
@@ -1669,6 +1675,100 @@ status_t Client::setState(int32_t count, const layer_state_t* states) {
|
|||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
UserClient::UserClient(const sp<SurfaceFlinger>& flinger)
|
||||||
|
: ctrlblk(0), mBitmap(0), mFlinger(flinger)
|
||||||
|
{
|
||||||
|
const int pgsize = getpagesize();
|
||||||
|
const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
|
||||||
|
|
||||||
|
mCblkHeap = new MemoryHeapBase(cblksize, 0,
|
||||||
|
"SurfaceFlinger Client control-block");
|
||||||
|
|
||||||
|
ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
|
||||||
|
if (ctrlblk) { // construct the shared structure in-place.
|
||||||
|
new(ctrlblk) SharedClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UserClient::~UserClient()
|
||||||
|
{
|
||||||
|
if (ctrlblk) {
|
||||||
|
ctrlblk->~SharedClient(); // destroy our shared-structure.
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When a UserClient dies, it's unclear what to do exactly.
|
||||||
|
* We could go ahead and destroy all surfaces linked to that client
|
||||||
|
* however, it wouldn't be fair to the main Client
|
||||||
|
* (usually the the window-manager), which might want to re-target
|
||||||
|
* the layer to another UserClient.
|
||||||
|
* I think the best is to do nothing, or not much; in most cases the
|
||||||
|
* WM itself will go ahead and clean things up when it detects a client of
|
||||||
|
* his has died.
|
||||||
|
* The remaining question is what to display? currently we keep
|
||||||
|
* just keep the current buffer.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t UserClient::initCheck() const {
|
||||||
|
return ctrlblk == 0 ? NO_INIT : NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserClient::detachLayer(const Layer* layer)
|
||||||
|
{
|
||||||
|
int32_t name = layer->getToken();
|
||||||
|
if (name >= 0) {
|
||||||
|
android_atomic_and(~(1LU<<name), &mBitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<IMemoryHeap> UserClient::getControlBlock() const {
|
||||||
|
return mCblkHeap;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
|
||||||
|
{
|
||||||
|
int32_t name = NAME_NOT_FOUND;
|
||||||
|
sp<Layer> layer(mFlinger->getLayer(sur));
|
||||||
|
if (layer == 0) return name;
|
||||||
|
|
||||||
|
// this layer already has a token, just return it
|
||||||
|
// FIXME: we should check that this token is for the same client
|
||||||
|
name = layer->getToken();
|
||||||
|
if (name >= 0) return name;
|
||||||
|
|
||||||
|
name = 0;
|
||||||
|
do {
|
||||||
|
int32_t mask = 1LU<<name;
|
||||||
|
if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
|
||||||
|
// we found and locked that name
|
||||||
|
layer->setToken(const_cast<UserClient*>(this), ctrlblk, name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (++name > 31)
|
||||||
|
name = NO_MEMORY;
|
||||||
|
} while(name >= 0);
|
||||||
|
|
||||||
|
//LOGD("getTokenForSurface(%p) => %d", sur->asBinder().get(), name);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<ISurface> UserClient::createSurface(
|
||||||
|
ISurfaceComposerClient::surface_data_t* params, int pid,
|
||||||
|
const String8& name,
|
||||||
|
DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
|
||||||
|
uint32_t flags) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
status_t UserClient::destroySurface(SurfaceID sid) {
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
status_t UserClient::setState(int32_t count, const layer_state_t* states) {
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
GraphicPlane::GraphicPlane()
|
GraphicPlane::GraphicPlane()
|
||||||
: mHw(0)
|
: mHw(0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ class Client;
|
|||||||
class DisplayHardware;
|
class DisplayHardware;
|
||||||
class FreezeLock;
|
class FreezeLock;
|
||||||
class Layer;
|
class Layer;
|
||||||
|
class LayerBlur;
|
||||||
|
class LayerDim;
|
||||||
class LayerBuffer;
|
class LayerBuffer;
|
||||||
|
|
||||||
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
|
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
|
||||||
@@ -59,10 +61,6 @@ class LayerBuffer;
|
|||||||
|
|
||||||
class Client : public BnSurfaceComposerClient
|
class Client : public BnSurfaceComposerClient
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
// pointer to this client's control block
|
|
||||||
SharedClient* ctrlblk;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Client(const sp<SurfaceFlinger>& flinger);
|
Client(const sp<SurfaceFlinger>& flinger);
|
||||||
~Client();
|
~Client();
|
||||||
@@ -71,13 +69,14 @@ public:
|
|||||||
|
|
||||||
// protected by SurfaceFlinger::mStateLock
|
// protected by SurfaceFlinger::mStateLock
|
||||||
ssize_t attachLayer(const sp<LayerBaseClient>& layer);
|
ssize_t attachLayer(const sp<LayerBaseClient>& layer);
|
||||||
|
void detachLayer(const LayerBaseClient* layer);
|
||||||
sp<LayerBaseClient> getLayerUser(int32_t i) const;
|
sp<LayerBaseClient> getLayerUser(int32_t i) const;
|
||||||
void free(LayerBaseClient const* layer);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// ISurfaceComposerClient interface
|
// ISurfaceComposerClient interface
|
||||||
virtual sp<IMemoryHeap> getControlBlock() const;
|
virtual sp<IMemoryHeap> getControlBlock() const;
|
||||||
|
virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const;
|
||||||
virtual sp<ISurface> createSurface(
|
virtual sp<ISurface> createSurface(
|
||||||
surface_data_t* params, int pid, const String8& name,
|
surface_data_t* params, int pid, const String8& name,
|
||||||
DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
|
DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
|
||||||
@@ -85,8 +84,41 @@ private:
|
|||||||
virtual status_t destroySurface(SurfaceID surfaceId);
|
virtual status_t destroySurface(SurfaceID surfaceId);
|
||||||
virtual status_t setState(int32_t count, const layer_state_t* states);
|
virtual status_t setState(int32_t count, const layer_state_t* states);
|
||||||
|
|
||||||
uint32_t mBitmap;
|
|
||||||
DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers;
|
DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers;
|
||||||
|
sp<SurfaceFlinger> mFlinger;
|
||||||
|
int32_t mNameGenerator;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UserClient : public BnSurfaceComposerClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// pointer to this client's control block
|
||||||
|
SharedClient* ctrlblk;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UserClient(const sp<SurfaceFlinger>& flinger);
|
||||||
|
~UserClient();
|
||||||
|
|
||||||
|
status_t initCheck() const;
|
||||||
|
|
||||||
|
// protected by SurfaceFlinger::mStateLock
|
||||||
|
void detachLayer(const Layer* layer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// ISurfaceComposerClient interface
|
||||||
|
virtual sp<IMemoryHeap> getControlBlock() const;
|
||||||
|
virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const;
|
||||||
|
virtual sp<ISurface> createSurface(
|
||||||
|
surface_data_t* params, int pid, const String8& name,
|
||||||
|
DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
|
||||||
|
uint32_t flags);
|
||||||
|
virtual status_t destroySurface(SurfaceID surfaceId);
|
||||||
|
virtual status_t setState(int32_t count, const layer_state_t* states);
|
||||||
|
|
||||||
|
// atomic-ops
|
||||||
|
mutable volatile int32_t mBitmap;
|
||||||
|
|
||||||
sp<IMemoryHeap> mCblkHeap;
|
sp<IMemoryHeap> mCblkHeap;
|
||||||
sp<SurfaceFlinger> mFlinger;
|
sp<SurfaceFlinger> mFlinger;
|
||||||
};
|
};
|
||||||
@@ -152,6 +184,7 @@ public:
|
|||||||
|
|
||||||
// ISurfaceComposer interface
|
// ISurfaceComposer interface
|
||||||
virtual sp<ISurfaceComposerClient> createConnection();
|
virtual sp<ISurfaceComposerClient> createConnection();
|
||||||
|
virtual sp<ISurfaceComposerClient> createClientConnection();
|
||||||
virtual sp<IMemoryHeap> getCblk() const;
|
virtual sp<IMemoryHeap> getCblk() const;
|
||||||
virtual void bootFinished();
|
virtual void bootFinished();
|
||||||
virtual void openGlobalTransaction();
|
virtual void openGlobalTransaction();
|
||||||
@@ -166,11 +199,12 @@ public:
|
|||||||
|
|
||||||
overlay_control_device_t* getOverlayEngine() const;
|
overlay_control_device_t* getOverlayEngine() const;
|
||||||
|
|
||||||
|
|
||||||
status_t removeLayer(const sp<LayerBase>& layer);
|
status_t removeLayer(const sp<LayerBase>& layer);
|
||||||
status_t addLayer(const sp<LayerBase>& layer);
|
status_t addLayer(const sp<LayerBase>& layer);
|
||||||
status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
|
status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
|
||||||
|
|
||||||
|
sp<Layer> getLayer(const sp<ISurface>& sur) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Client;
|
friend class Client;
|
||||||
friend class LayerBase;
|
friend class LayerBase;
|
||||||
@@ -187,20 +221,20 @@ private:
|
|||||||
DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
|
DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
|
||||||
uint32_t flags);
|
uint32_t flags);
|
||||||
|
|
||||||
sp<LayerBaseClient> createNormalSurface(
|
sp<Layer> createNormalSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
uint32_t w, uint32_t h, uint32_t flags,
|
uint32_t w, uint32_t h, uint32_t flags,
|
||||||
PixelFormat& format);
|
PixelFormat& format);
|
||||||
|
|
||||||
sp<LayerBaseClient> createBlurSurface(
|
sp<LayerBlur> createBlurSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
uint32_t w, uint32_t h, uint32_t flags);
|
uint32_t w, uint32_t h, uint32_t flags);
|
||||||
|
|
||||||
sp<LayerBaseClient> createDimSurface(
|
sp<LayerDim> createDimSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
uint32_t w, uint32_t h, uint32_t flags);
|
uint32_t w, uint32_t h, uint32_t flags);
|
||||||
|
|
||||||
sp<LayerBaseClient> createPushBuffersSurface(
|
sp<LayerBuffer> createPushBuffersSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
uint32_t w, uint32_t h, uint32_t flags);
|
uint32_t w, uint32_t h, uint32_t flags);
|
||||||
|
|
||||||
@@ -307,8 +341,7 @@ private:
|
|||||||
|
|
||||||
status_t postMessageSync(const sp<MessageBase>& msg,
|
status_t postMessageSync(const sp<MessageBase>& msg,
|
||||||
nsecs_t reltime=0, uint32_t flags = 0);
|
nsecs_t reltime=0, uint32_t flags = 0);
|
||||||
|
|
||||||
|
|
||||||
// access must be protected by mStateLock
|
// access must be protected by mStateLock
|
||||||
mutable Mutex mStateLock;
|
mutable Mutex mStateLock;
|
||||||
State mCurrentState;
|
State mCurrentState;
|
||||||
@@ -321,6 +354,7 @@ private:
|
|||||||
// protected by mStateLock (but we could use another lock)
|
// protected by mStateLock (but we could use another lock)
|
||||||
GraphicPlane mGraphicPlanes[1];
|
GraphicPlane mGraphicPlanes[1];
|
||||||
bool mLayersRemoved;
|
bool mLayersRemoved;
|
||||||
|
DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayerMap;
|
||||||
|
|
||||||
// constant members (no synchronization needed for access)
|
// constant members (no synchronization needed for access)
|
||||||
sp<IMemoryHeap> mServerHeap;
|
sp<IMemoryHeap> mServerHeap;
|
||||||
|
|||||||
@@ -55,6 +55,15 @@ public:
|
|||||||
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
|
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual sp<ISurfaceComposerClient> createClientConnection()
|
||||||
|
{
|
||||||
|
uint32_t n;
|
||||||
|
Parcel data, reply;
|
||||||
|
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
|
||||||
|
remote()->transact(BnSurfaceComposer::CREATE_CLIENT_CONNECTION, data, &reply);
|
||||||
|
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
|
||||||
|
}
|
||||||
|
|
||||||
virtual sp<IMemoryHeap> getCblk() const
|
virtual sp<IMemoryHeap> getCblk() const
|
||||||
{
|
{
|
||||||
Parcel data, reply;
|
Parcel data, reply;
|
||||||
@@ -136,6 +145,11 @@ status_t BnSurfaceComposer::onTransact(
|
|||||||
sp<IBinder> b = createConnection()->asBinder();
|
sp<IBinder> b = createConnection()->asBinder();
|
||||||
reply->writeStrongBinder(b);
|
reply->writeStrongBinder(b);
|
||||||
} break;
|
} break;
|
||||||
|
case CREATE_CLIENT_CONNECTION: {
|
||||||
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
|
sp<IBinder> b = createClientConnection()->asBinder();
|
||||||
|
reply->writeStrongBinder(b);
|
||||||
|
} break;
|
||||||
case OPEN_GLOBAL_TRANSACTION: {
|
case OPEN_GLOBAL_TRANSACTION: {
|
||||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
openGlobalTransaction();
|
openGlobalTransaction();
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ namespace android {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
|
GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
|
||||||
|
GET_TOKEN,
|
||||||
CREATE_SURFACE,
|
CREATE_SURFACE,
|
||||||
DESTROY_SURFACE,
|
DESTROY_SURFACE,
|
||||||
SET_STATE
|
SET_STATE
|
||||||
@@ -72,6 +73,15 @@ public:
|
|||||||
return interface_cast<IMemoryHeap>(reply.readStrongBinder());
|
return interface_cast<IMemoryHeap>(reply.readStrongBinder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const
|
||||||
|
{
|
||||||
|
Parcel data, reply;
|
||||||
|
data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
|
||||||
|
data.writeStrongBinder(sur->asBinder());
|
||||||
|
remote()->transact(GET_TOKEN, data, &reply);
|
||||||
|
return reply.readInt32();
|
||||||
|
}
|
||||||
|
|
||||||
virtual sp<ISurface> createSurface( surface_data_t* params,
|
virtual sp<ISurface> createSurface( surface_data_t* params,
|
||||||
int pid,
|
int pid,
|
||||||
const String8& name,
|
const String8& name,
|
||||||
@@ -132,6 +142,13 @@ status_t BnSurfaceComposerClient::onTransact(
|
|||||||
reply->writeStrongBinder(ctl->asBinder());
|
reply->writeStrongBinder(ctl->asBinder());
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
} break;
|
} break;
|
||||||
|
case GET_TOKEN: {
|
||||||
|
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
|
||||||
|
sp<ISurface> sur = interface_cast<ISurface>(data.readStrongBinder());
|
||||||
|
ssize_t token = getTokenForSurface(sur);
|
||||||
|
reply->writeInt32(token);
|
||||||
|
return NO_ERROR;
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// these must be checked
|
// these must be checked
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ SharedBufferStack::SharedBufferStack()
|
|||||||
|
|
||||||
void SharedBufferStack::init(int32_t i)
|
void SharedBufferStack::init(int32_t i)
|
||||||
{
|
{
|
||||||
inUse = -1;
|
inUse = -2;
|
||||||
status = NO_ERROR;
|
status = NO_ERROR;
|
||||||
identity = i;
|
identity = i;
|
||||||
}
|
}
|
||||||
@@ -282,8 +282,10 @@ SharedBufferServer::UnlockUpdate::UnlockUpdate(
|
|||||||
}
|
}
|
||||||
ssize_t SharedBufferServer::UnlockUpdate::operator()() {
|
ssize_t SharedBufferServer::UnlockUpdate::operator()() {
|
||||||
if (stack.inUse != lockedBuffer) {
|
if (stack.inUse != lockedBuffer) {
|
||||||
LOGE("unlocking %d, but currently locked buffer is %d",
|
LOGE("unlocking %d, but currently locked buffer is %d "
|
||||||
lockedBuffer, stack.inUse);
|
"(identity=%d, token=%d)",
|
||||||
|
lockedBuffer, stack.inUse,
|
||||||
|
stack.identity, stack.token);
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
android_atomic_write(-1, &stack.inUse);
|
android_atomic_write(-1, &stack.inUse);
|
||||||
@@ -480,6 +482,7 @@ SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
|
|||||||
mNumBuffers(num)
|
mNumBuffers(num)
|
||||||
{
|
{
|
||||||
mSharedStack->init(identity);
|
mSharedStack->init(identity);
|
||||||
|
mSharedStack->token = surface;
|
||||||
mSharedStack->head = num-1;
|
mSharedStack->head = num-1;
|
||||||
mSharedStack->available = num;
|
mSharedStack->available = num;
|
||||||
mSharedStack->queued = 0;
|
mSharedStack->queued = 0;
|
||||||
|
|||||||
@@ -238,14 +238,12 @@ status_t SurfaceControl::writeSurfaceToParcel(
|
|||||||
{
|
{
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
uint32_t format = 0;
|
uint32_t format = 0;
|
||||||
SurfaceID token = -1;
|
|
||||||
uint32_t identity = 0;
|
uint32_t identity = 0;
|
||||||
uint32_t width = 0;
|
uint32_t width = 0;
|
||||||
uint32_t height = 0;
|
uint32_t height = 0;
|
||||||
sp<SurfaceComposerClient> client;
|
sp<SurfaceComposerClient> client;
|
||||||
sp<ISurface> sur;
|
sp<ISurface> sur;
|
||||||
if (SurfaceControl::isValid(control)) {
|
if (SurfaceControl::isValid(control)) {
|
||||||
token = control->mToken;
|
|
||||||
identity = control->mIdentity;
|
identity = control->mIdentity;
|
||||||
client = control->mClient;
|
client = control->mClient;
|
||||||
sur = control->mSurface;
|
sur = control->mSurface;
|
||||||
@@ -254,9 +252,7 @@ status_t SurfaceControl::writeSurfaceToParcel(
|
|||||||
format = control->mFormat;
|
format = control->mFormat;
|
||||||
flags = control->mFlags;
|
flags = control->mFlags;
|
||||||
}
|
}
|
||||||
parcel->writeStrongBinder(client!=0 ? client->connection() : NULL);
|
parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
|
||||||
parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
|
|
||||||
parcel->writeInt32(token);
|
|
||||||
parcel->writeInt32(identity);
|
parcel->writeInt32(identity);
|
||||||
parcel->writeInt32(width);
|
parcel->writeInt32(width);
|
||||||
parcel->writeInt32(height);
|
parcel->writeInt32(height);
|
||||||
@@ -278,31 +274,78 @@ sp<Surface> SurfaceControl::getSurface() const
|
|||||||
// Surface
|
// Surface
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
class SurfaceClient : public Singleton<SurfaceClient>
|
||||||
|
{
|
||||||
|
// all these attributes are constants
|
||||||
|
sp<ISurfaceComposer> mComposerService;
|
||||||
|
sp<ISurfaceComposerClient> mClient;
|
||||||
|
status_t mStatus;
|
||||||
|
SharedClient* mControl;
|
||||||
|
sp<IMemoryHeap> mControlMemory;
|
||||||
|
|
||||||
|
SurfaceClient()
|
||||||
|
: Singleton<SurfaceClient>(), mStatus(NO_INIT)
|
||||||
|
{
|
||||||
|
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
|
||||||
|
mComposerService = sf;
|
||||||
|
mClient = sf->createClientConnection();
|
||||||
|
if (mClient != NULL) {
|
||||||
|
mControlMemory = mClient->getControlBlock();
|
||||||
|
if (mControlMemory != NULL) {
|
||||||
|
mControl = static_cast<SharedClient *>(
|
||||||
|
mControlMemory->getBase());
|
||||||
|
if (mControl) {
|
||||||
|
mStatus = NO_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
friend class Singleton<SurfaceClient>;
|
||||||
|
public:
|
||||||
|
status_t initCheck() const {
|
||||||
|
return mStatus;
|
||||||
|
}
|
||||||
|
SharedClient* getSharedClient() const {
|
||||||
|
return mControl;
|
||||||
|
}
|
||||||
|
ssize_t getTokenForSurface(const sp<ISurface>& sur) const {
|
||||||
|
// TODO: we could cache a few tokens here to avoid an IPC
|
||||||
|
return mClient->getTokenForSurface(sur);
|
||||||
|
}
|
||||||
|
void signalServer() const {
|
||||||
|
mComposerService->signal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ANDROID_SINGLETON_STATIC_INSTANCE(SurfaceClient);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
Surface::Surface(const sp<SurfaceControl>& surface)
|
Surface::Surface(const sp<SurfaceControl>& surface)
|
||||||
: mSurface(surface->mSurface),
|
: mBufferMapper(GraphicBufferMapper::get()),
|
||||||
mToken(surface->mToken), mIdentity(surface->mIdentity),
|
mClient(SurfaceClient::getInstance()),
|
||||||
mFormat(surface->mFormat), mFlags(surface->mFlags),
|
mSharedBufferClient(NULL),
|
||||||
mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL),
|
|
||||||
mInitCheck(NO_INIT),
|
mInitCheck(NO_INIT),
|
||||||
|
mSurface(surface->mSurface),
|
||||||
|
mIdentity(surface->mIdentity),
|
||||||
|
mFormat(surface->mFormat), mFlags(surface->mFlags),
|
||||||
mWidth(surface->mWidth), mHeight(surface->mHeight)
|
mWidth(surface->mWidth), mHeight(surface->mHeight)
|
||||||
{
|
{
|
||||||
mClient = new SurfaceClient(surface->mClient);
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
Surface::Surface(const Parcel& parcel)
|
Surface::Surface(const Parcel& parcel)
|
||||||
: mBufferMapper(GraphicBufferMapper::get()),
|
: mBufferMapper(GraphicBufferMapper::get()),
|
||||||
mSharedBufferClient(NULL), mInitCheck(NO_INIT)
|
mClient(SurfaceClient::getInstance()),
|
||||||
|
mSharedBufferClient(NULL),
|
||||||
|
mInitCheck(NO_INIT)
|
||||||
{
|
{
|
||||||
sp<IBinder> conn = parcel.readStrongBinder();
|
|
||||||
mSurface = interface_cast<ISurface>(parcel.readStrongBinder());
|
mSurface = interface_cast<ISurface>(parcel.readStrongBinder());
|
||||||
mToken = parcel.readInt32();
|
|
||||||
mIdentity = parcel.readInt32();
|
mIdentity = parcel.readInt32();
|
||||||
mWidth = parcel.readInt32();
|
mWidth = parcel.readInt32();
|
||||||
mHeight = parcel.readInt32();
|
mHeight = parcel.readInt32();
|
||||||
mFormat = parcel.readInt32();
|
mFormat = parcel.readInt32();
|
||||||
mFlags = parcel.readInt32();
|
mFlags = parcel.readInt32();
|
||||||
mClient = new SurfaceClient(conn);
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,12 +373,14 @@ void Surface::init()
|
|||||||
mBuffers.setCapacity(2);
|
mBuffers.setCapacity(2);
|
||||||
mBuffers.insertAt(0, 2);
|
mBuffers.insertAt(0, 2);
|
||||||
|
|
||||||
if (mClient != 0 && mClient->initCheck() == NO_ERROR) {
|
if (mSurface != 0 && mClient.initCheck() == NO_ERROR) {
|
||||||
mSharedBufferClient = new SharedBufferClient(
|
mToken = mClient.getTokenForSurface(mSurface);
|
||||||
mClient->getSharedClient(), mToken, 2, mIdentity);
|
if (mToken >= 0) {
|
||||||
|
mSharedBufferClient = new SharedBufferClient(
|
||||||
|
mClient.getSharedClient(), mToken, 2, mIdentity);
|
||||||
|
mInitCheck = mClient.getSharedClient()->validate(mToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mInitCheck = initCheck();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Surface::~Surface()
|
Surface::~Surface()
|
||||||
@@ -352,25 +397,11 @@ Surface::~Surface()
|
|||||||
// clear all references and trigger an IPC now, to make sure things
|
// clear all references and trigger an IPC now, to make sure things
|
||||||
// happen without delay, since these resources are quite heavy.
|
// happen without delay, since these resources are quite heavy.
|
||||||
mBuffers.clear();
|
mBuffers.clear();
|
||||||
mClient.clear();
|
|
||||||
mSurface.clear();
|
mSurface.clear();
|
||||||
delete mSharedBufferClient;
|
delete mSharedBufferClient;
|
||||||
IPCThreadState::self()->flushCommands();
|
IPCThreadState::self()->flushCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t Surface::initCheck() const
|
|
||||||
{
|
|
||||||
if (mToken<0 || mClient==0 || mClient->initCheck() != NO_ERROR) {
|
|
||||||
return NO_INIT;
|
|
||||||
}
|
|
||||||
SharedClient const* cblk = mClient->getSharedClient();
|
|
||||||
if (cblk == 0) {
|
|
||||||
LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
|
|
||||||
return NO_INIT;
|
|
||||||
}
|
|
||||||
return cblk->validate(mToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Surface::isValid() {
|
bool Surface::isValid() {
|
||||||
return mInitCheck == NO_ERROR;
|
return mInitCheck == NO_ERROR;
|
||||||
}
|
}
|
||||||
@@ -379,8 +410,7 @@ status_t Surface::validate() const
|
|||||||
{
|
{
|
||||||
// check that we initialized ourself properly
|
// check that we initialized ourself properly
|
||||||
if (mInitCheck != NO_ERROR) {
|
if (mInitCheck != NO_ERROR) {
|
||||||
LOGE("invalid token (%d, identity=%u) or client (%p)",
|
LOGE("invalid token (%d, identity=%u)", mToken, mIdentity);
|
||||||
mToken, mIdentity, mClient.get());
|
|
||||||
return mInitCheck;
|
return mInitCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,8 +588,8 @@ int Surface::queueBuffer(android_native_buffer_t* buffer)
|
|||||||
LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
|
LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
|
||||||
|
|
||||||
if (err == NO_ERROR) {
|
if (err == NO_ERROR) {
|
||||||
// FIXME: can we avoid this IPC if we know there is one pending?
|
// TODO: can we avoid this IPC if we know there is one pending?
|
||||||
mClient->signalServer();
|
mClient.signalServer();
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,36 +42,26 @@
|
|||||||
namespace android {
|
namespace android {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
class ComposerService : public Singleton<ComposerService>
|
|
||||||
{
|
|
||||||
// these are constants
|
|
||||||
sp<ISurfaceComposer> mComposerService;
|
|
||||||
sp<IMemoryHeap> mServerCblkMemory;
|
|
||||||
surface_flinger_cblk_t volatile* mServerCblk;
|
|
||||||
|
|
||||||
ComposerService() : Singleton<ComposerService>() {
|
|
||||||
const String16 name("SurfaceFlinger");
|
|
||||||
while (getService(name, &mComposerService) != NO_ERROR) {
|
|
||||||
usleep(250000);
|
|
||||||
}
|
|
||||||
mServerCblkMemory = mComposerService->getCblk();
|
|
||||||
mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
|
|
||||||
mServerCblkMemory->getBase());
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class Singleton<ComposerService>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static sp<ISurfaceComposer> getComposerService() {
|
|
||||||
return ComposerService::getInstance().mComposerService;
|
|
||||||
}
|
|
||||||
static surface_flinger_cblk_t const volatile * getControlBlock() {
|
|
||||||
return ComposerService::getInstance().mServerCblk;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
|
ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
|
||||||
|
|
||||||
|
ComposerService::ComposerService()
|
||||||
|
: Singleton<ComposerService>() {
|
||||||
|
const String16 name("SurfaceFlinger");
|
||||||
|
while (getService(name, &mComposerService) != NO_ERROR) {
|
||||||
|
usleep(250000);
|
||||||
|
}
|
||||||
|
mServerCblkMemory = mComposerService->getCblk();
|
||||||
|
mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
|
||||||
|
mServerCblkMemory->getBase());
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<ISurfaceComposer> ComposerService::getComposerService() {
|
||||||
|
return ComposerService::getInstance().mComposerService;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_flinger_cblk_t const volatile * ComposerService::getControlBlock() {
|
||||||
|
return ComposerService::getInstance().mServerCblk;
|
||||||
|
}
|
||||||
|
|
||||||
static inline sp<ISurfaceComposer> getComposerService() {
|
static inline sp<ISurfaceComposer> getComposerService() {
|
||||||
return ComposerService::getComposerService();
|
return ComposerService::getComposerService();
|
||||||
@@ -556,42 +546,6 @@ status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
SurfaceClient::SurfaceClient(const sp<SurfaceComposerClient>& client)
|
|
||||||
: mStatus(NO_INIT), mControl(0)
|
|
||||||
{
|
|
||||||
if (client != 0) {
|
|
||||||
sp<IBinder> conn = client->connection();
|
|
||||||
init(conn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SurfaceClient::SurfaceClient(const sp<IBinder>& conn)
|
|
||||||
: mStatus(NO_INIT), mControl(0)
|
|
||||||
{
|
|
||||||
init(conn);
|
|
||||||
}
|
|
||||||
void SurfaceClient::init(const sp<IBinder>& conn)
|
|
||||||
{
|
|
||||||
mComposerService = getComposerService();
|
|
||||||
sp<ISurfaceComposerClient> sf(interface_cast<ISurfaceComposerClient>(conn));
|
|
||||||
if (sf != 0) {
|
|
||||||
mConnection = conn;
|
|
||||||
mControlMemory = sf->getControlBlock();
|
|
||||||
mControl = static_cast<SharedClient *>(mControlMemory->getBase());
|
|
||||||
mStatus = NO_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
status_t SurfaceClient::initCheck() const {
|
|
||||||
return mStatus;
|
|
||||||
}
|
|
||||||
SharedClient* SurfaceClient::getSharedClient() const {
|
|
||||||
return mControl;
|
|
||||||
}
|
|
||||||
void SurfaceClient::signalServer() const {
|
|
||||||
mComposerService->signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace android {
|
|||||||
|
|
||||||
GraphicBuffer::GraphicBuffer()
|
GraphicBuffer::GraphicBuffer()
|
||||||
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
|
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
|
||||||
mInitCheck(NO_ERROR), mVStride(0), mIndex(-1)
|
mInitCheck(NO_ERROR), mIndex(-1)
|
||||||
{
|
{
|
||||||
width =
|
width =
|
||||||
height =
|
height =
|
||||||
@@ -51,7 +51,7 @@ GraphicBuffer::GraphicBuffer()
|
|||||||
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
|
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
|
||||||
PixelFormat reqFormat, uint32_t reqUsage)
|
PixelFormat reqFormat, uint32_t reqUsage)
|
||||||
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
|
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
|
||||||
mInitCheck(NO_ERROR), mVStride(0), mIndex(-1)
|
mInitCheck(NO_ERROR), mIndex(-1)
|
||||||
{
|
{
|
||||||
width =
|
width =
|
||||||
height =
|
height =
|
||||||
@@ -67,7 +67,7 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
|
|||||||
uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
|
uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
|
||||||
: BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
|
: BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
|
||||||
mBufferMapper(GraphicBufferMapper::get()),
|
mBufferMapper(GraphicBufferMapper::get()),
|
||||||
mInitCheck(NO_ERROR), mVStride(0), mIndex(-1)
|
mInitCheck(NO_ERROR), mIndex(-1)
|
||||||
{
|
{
|
||||||
width = w;
|
width = w;
|
||||||
height = h;
|
height = h;
|
||||||
@@ -141,7 +141,6 @@ status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
|
|||||||
this->height = h;
|
this->height = h;
|
||||||
this->format = format;
|
this->format = format;
|
||||||
this->usage = reqUsage;
|
this->usage = reqUsage;
|
||||||
mVStride = 0;
|
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -182,7 +181,6 @@ status_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage)
|
|||||||
sur->height = height;
|
sur->height = height;
|
||||||
sur->stride = stride;
|
sur->stride = stride;
|
||||||
sur->format = format;
|
sur->format = format;
|
||||||
sur->vstride = mVStride;
|
|
||||||
sur->data = static_cast<GGLubyte*>(vaddr);
|
sur->data = static_cast<GGLubyte*>(vaddr);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@@ -276,14 +274,6 @@ int GraphicBuffer::getIndex() const {
|
|||||||
return mIndex;
|
return mIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicBuffer::setVerticalStride(uint32_t vstride) {
|
|
||||||
mVStride = vstride;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t GraphicBuffer::getVerticalStride() const {
|
|
||||||
return mVStride;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
|||||||
Reference in New Issue
Block a user