clean-up client management.
simplified things a lot, the biggest change is that the concept of "ClientID" is now gone, instead we simply use references. Change-Id: Icbc57f80865884aa5f35ad0d0a0db26f19f9f7ce
This commit is contained in:
@@ -14,7 +14,6 @@ LOCAL_SRC_FILES:= \
|
|||||||
MessageQueue.cpp \
|
MessageQueue.cpp \
|
||||||
SurfaceFlinger.cpp \
|
SurfaceFlinger.cpp \
|
||||||
TextureManager.cpp \
|
TextureManager.cpp \
|
||||||
Tokenizer.cpp \
|
|
||||||
Transform.cpp
|
Transform.cpp
|
||||||
|
|
||||||
LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
|
LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ template <typename T> inline T min(T a, T b) {
|
|||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
Layer::Layer(SurfaceFlinger* flinger, DisplayID display,
|
Layer::Layer(SurfaceFlinger* flinger,
|
||||||
const sp<Client>& client, int32_t i)
|
DisplayID display, const sp<Client>& client)
|
||||||
: LayerBaseClient(flinger, display, client, i),
|
: LayerBaseClient(flinger, display, client),
|
||||||
lcblk(NULL),
|
lcblk(NULL),
|
||||||
mSecure(false),
|
mSecure(false),
|
||||||
mNeedsBlending(true),
|
mNeedsBlending(true),
|
||||||
@@ -58,13 +58,6 @@ Layer::Layer(SurfaceFlinger* flinger, DisplayID display,
|
|||||||
mBufferManager(mTextureManager),
|
mBufferManager(mTextureManager),
|
||||||
mWidth(0), mHeight(0), mFixedSize(false)
|
mWidth(0), mHeight(0), mFixedSize(false)
|
||||||
{
|
{
|
||||||
// no OpenGL operation is possible here, since we might not be
|
|
||||||
// in the OpenGL thread.
|
|
||||||
lcblk = new SharedBufferServer(
|
|
||||||
client->ctrlblk, i, mBufferManager.getDefaultBufferCount(),
|
|
||||||
getIdentity());
|
|
||||||
|
|
||||||
mBufferManager.setActiveBufferIndex( lcblk->getFrontBuffer() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer::~Layer()
|
Layer::~Layer()
|
||||||
@@ -77,12 +70,31 @@ Layer::~Layer()
|
|||||||
delete lcblk;
|
delete lcblk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: get rid of this
|
||||||
|
void Layer::setToken(int32_t token)
|
||||||
|
{
|
||||||
|
sp<Client> ourClient(client.promote());
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
mBufferManager.setActiveBufferIndex( lcblk->getFrontBuffer() );
|
||||||
|
}
|
||||||
|
|
||||||
// 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()
|
||||||
{
|
{
|
||||||
// wake up the condition
|
sp<Client> ourClient(client.promote());
|
||||||
lcblk->setStatus(NO_INIT);
|
if (ourClient != 0) {
|
||||||
|
// wake up the condition
|
||||||
|
lcblk->setStatus(NO_INIT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<LayerBaseClient::Surface> Layer::createSurface() const
|
sp<LayerBaseClient::Surface> Layer::createSurface() const
|
||||||
@@ -140,7 +152,7 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
|
|||||||
int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
|
int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
|
||||||
mNeedsDithering = layerRedsize > displayRedSize;
|
mNeedsDithering = layerRedsize > displayRedSize;
|
||||||
|
|
||||||
mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
|
mSurface = new SurfaceLayer(mFlinger, this);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,8 +403,11 @@ 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);
|
||||||
|
|
||||||
// all buffers need reallocation
|
sp<Client> ourClient(client.promote());
|
||||||
lcblk->reallocateAll();
|
if (ourClient != 0) {
|
||||||
|
// all buffers need reallocation
|
||||||
|
lcblk->reallocateAll();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// record the new size
|
// record the new size
|
||||||
setBufferSize(temp.requested_w, temp.requested_h);
|
setBufferSize(temp.requested_w, temp.requested_h);
|
||||||
@@ -427,6 +442,13 @@ bool Layer::isFixedSize() const {
|
|||||||
|
|
||||||
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
||||||
{
|
{
|
||||||
|
sp<Client> ourClient(client.promote());
|
||||||
|
if (ourClient == 0) {
|
||||||
|
// client died
|
||||||
|
recomputeVisibleRegions = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t buf = lcblk->retireAndLock();
|
ssize_t buf = lcblk->retireAndLock();
|
||||||
if (buf == NOT_ENOUGH_DATA) {
|
if (buf == NOT_ENOUGH_DATA) {
|
||||||
// NOTE: This is not an error, it simply means there is nothing to
|
// NOTE: This is not an error, it simply means there is nothing to
|
||||||
@@ -538,9 +560,12 @@ void Layer::unlockPageFlip(
|
|||||||
|
|
||||||
void Layer::finishPageFlip()
|
void Layer::finishPageFlip()
|
||||||
{
|
{
|
||||||
int buf = mBufferManager.getActiveBufferIndex();
|
sp<Client> ourClient(client.promote());
|
||||||
status_t err = lcblk->unlock( buf );
|
if (ourClient != 0) {
|
||||||
LOGE_IF(err!=NO_ERROR, "layer %p, buffer=%d wasn't locked!", this, buf);
|
int buf = mBufferManager.getActiveBufferIndex();
|
||||||
|
status_t err = lcblk->unlock( buf );
|
||||||
|
LOGE_IF(err!=NO_ERROR, "layer %p, buffer=%d wasn't locked!", this, buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -707,8 +732,8 @@ status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy)
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
|
Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
|
||||||
SurfaceID id, const sp<Layer>& owner)
|
const sp<Layer>& owner)
|
||||||
: Surface(flinger, id, owner->getIdentity(), owner)
|
: Surface(flinger, owner->getIdentity(), owner)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
SharedBufferServer* lcblk;
|
SharedBufferServer* lcblk;
|
||||||
|
|
||||||
Layer(SurfaceFlinger* flinger, DisplayID display,
|
Layer(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client, int32_t i);
|
const sp<Client>& client);
|
||||||
|
|
||||||
virtual ~Layer();
|
virtual ~Layer();
|
||||||
|
|
||||||
@@ -96,8 +96,7 @@ private:
|
|||||||
|
|
||||||
class SurfaceLayer : public LayerBaseClient::Surface {
|
class SurfaceLayer : public LayerBaseClient::Surface {
|
||||||
public:
|
public:
|
||||||
SurfaceLayer(const sp<SurfaceFlinger>& flinger,
|
SurfaceLayer(const sp<SurfaceFlinger>& flinger, const sp<Layer>& owner);
|
||||||
SurfaceID id, const sp<Layer>& owner);
|
|
||||||
~SurfaceLayer();
|
~SurfaceLayer();
|
||||||
private:
|
private:
|
||||||
virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
|
virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
|
||||||
@@ -189,6 +188,12 @@ private:
|
|||||||
uint32_t mReqHeight;
|
uint32_t mReqHeight;
|
||||||
uint32_t mReqFormat;
|
uint32_t mReqFormat;
|
||||||
bool mFixedSize;
|
bool mFixedSize;
|
||||||
|
|
||||||
|
// TODO: get rid of this
|
||||||
|
private:
|
||||||
|
virtual void setToken(int32_t token);
|
||||||
|
virtual int32_t getToken() const { return mToken; }
|
||||||
|
int32_t mToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -488,37 +488,20 @@ void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
|
|||||||
int32_t LayerBaseClient::sIdentity = 1;
|
int32_t LayerBaseClient::sIdentity = 1;
|
||||||
|
|
||||||
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client, int32_t i)
|
const sp<Client>& client)
|
||||||
: LayerBase(flinger, display), client(client), mIndex(i),
|
: LayerBase(flinger, display), client(client),
|
||||||
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
|
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerBaseClient::onFirstRef()
|
|
||||||
{
|
|
||||||
sp<Client> client(this->client.promote());
|
|
||||||
if (client != 0) {
|
|
||||||
client->bindLayer(this, mIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerBaseClient::~LayerBaseClient()
|
LayerBaseClient::~LayerBaseClient()
|
||||||
{
|
{
|
||||||
sp<Client> client(this->client.promote());
|
sp<Client> c(client.promote());
|
||||||
if (client != 0) {
|
if (c != 0) {
|
||||||
client->free(mIndex);
|
c->free(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t LayerBaseClient::serverIndex() const
|
|
||||||
{
|
|
||||||
sp<Client> client(this->client.promote());
|
|
||||||
if (client != 0) {
|
|
||||||
return (client->cid<<16)|mIndex;
|
|
||||||
}
|
|
||||||
return ssize_t(0xFFFF0000 | mIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
|
sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
|
||||||
{
|
{
|
||||||
sp<Surface> s;
|
sp<Surface> s;
|
||||||
@@ -533,7 +516,7 @@ sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
|
|||||||
|
|
||||||
sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
|
sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
|
||||||
{
|
{
|
||||||
return new Surface(mFlinger, clientIndex(), mIdentity,
|
return new Surface(mFlinger, mIdentity,
|
||||||
const_cast<LayerBaseClient *>(this));
|
const_cast<LayerBaseClient *>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,10 +527,9 @@ void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
|
|||||||
sp<Client> client(this->client.promote());
|
sp<Client> client(this->client.promote());
|
||||||
snprintf(buffer, SIZE,
|
snprintf(buffer, SIZE,
|
||||||
" name=%s\n"
|
" name=%s\n"
|
||||||
" id=0x%08x, client=0x%08x, identity=%u\n",
|
" client=%p, identity=%u\n",
|
||||||
getName().string(),
|
getName().string(),
|
||||||
clientIndex(), client.get() ? client->cid : 0,
|
client.get(), getIdentity());
|
||||||
getIdentity());
|
|
||||||
|
|
||||||
result.append(buffer);
|
result.append(buffer);
|
||||||
}
|
}
|
||||||
@@ -556,9 +538,9 @@ void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
|
|||||||
|
|
||||||
LayerBaseClient::Surface::Surface(
|
LayerBaseClient::Surface::Surface(
|
||||||
const sp<SurfaceFlinger>& flinger,
|
const sp<SurfaceFlinger>& flinger,
|
||||||
SurfaceID id, int identity,
|
int identity,
|
||||||
const sp<LayerBaseClient>& owner)
|
const sp<LayerBaseClient>& owner)
|
||||||
: mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner)
|
: mFlinger(flinger), mIdentity(identity), mOwner(owner)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ public:
|
|||||||
void invalidate();
|
void invalidate();
|
||||||
|
|
||||||
virtual const char* getTypeId() const { return "LayerBase"; }
|
virtual const char* getTypeId() const { return "LayerBase"; }
|
||||||
virtual ssize_t serverIndex() const { return -1; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* draw - performs some global clipping optimizations
|
* draw - performs some global clipping optimizations
|
||||||
@@ -269,30 +268,24 @@ class LayerBaseClient : public LayerBase
|
|||||||
public:
|
public:
|
||||||
class Surface;
|
class Surface;
|
||||||
|
|
||||||
LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
const wp<Client> client;
|
||||||
const sp<Client>& client, int32_t i);
|
|
||||||
|
LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
||||||
|
const sp<Client>& client);
|
||||||
virtual ~LayerBaseClient();
|
virtual ~LayerBaseClient();
|
||||||
virtual void onFirstRef();
|
|
||||||
|
|
||||||
const wp<Client> client;
|
|
||||||
|
|
||||||
inline uint32_t getIdentity() const { return mIdentity; }
|
|
||||||
inline int32_t clientIndex() const { return mIndex; }
|
|
||||||
|
|
||||||
sp<Surface> getSurface();
|
sp<Surface> getSurface();
|
||||||
virtual sp<Surface> createSurface() const;
|
virtual sp<Surface> createSurface() const;
|
||||||
virtual ssize_t serverIndex() const;
|
|
||||||
virtual const char* getTypeId() const { return "LayerBaseClient"; }
|
virtual const char* getTypeId() const { return "LayerBaseClient"; }
|
||||||
|
|
||||||
class Surface : public BnSurface
|
uint32_t getIdentity() const { return mIdentity; }
|
||||||
{
|
|
||||||
|
class Surface : public BnSurface {
|
||||||
public:
|
public:
|
||||||
int32_t getToken() const { return mToken; }
|
|
||||||
int32_t getIdentity() const { return mIdentity; }
|
int32_t getIdentity() const { return mIdentity; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Surface(const sp<SurfaceFlinger>& flinger,
|
Surface(const sp<SurfaceFlinger>& flinger, int identity,
|
||||||
SurfaceID id, int identity,
|
|
||||||
const sp<LayerBaseClient>& owner);
|
const sp<LayerBaseClient>& owner);
|
||||||
virtual ~Surface();
|
virtual ~Surface();
|
||||||
virtual status_t onTransact(uint32_t code, const Parcel& data,
|
virtual status_t onTransact(uint32_t code, const Parcel& data,
|
||||||
@@ -313,7 +306,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
friend class LayerBaseClient;
|
friend class LayerBaseClient;
|
||||||
sp<SurfaceFlinger> mFlinger;
|
sp<SurfaceFlinger> mFlinger;
|
||||||
int32_t mToken;
|
|
||||||
int32_t mIdentity;
|
int32_t mIdentity;
|
||||||
wp<LayerBaseClient> mOwner;
|
wp<LayerBaseClient> mOwner;
|
||||||
};
|
};
|
||||||
@@ -324,12 +316,16 @@ 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:
|
||||||
int32_t mIndex;
|
mutable Mutex mLock;
|
||||||
mutable Mutex mLock;
|
mutable wp<Surface> mClientSurface;
|
||||||
mutable wp<Surface> mClientSurface;
|
|
||||||
// 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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ namespace android {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
|
LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client, int32_t i)
|
const sp<Client>& client)
|
||||||
: LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
|
: LayerBaseClient(flinger, display, client), mCacheDirty(true),
|
||||||
mRefreshCache(true), mCacheAge(0), mTextureName(-1U),
|
mRefreshCache(true), mCacheAge(0), mTextureName(-1U),
|
||||||
mWidthScale(1.0f), mHeightScale(1.0f),
|
mWidthScale(1.0f), mHeightScale(1.0f),
|
||||||
mBlurFormat(GGL_PIXEL_FORMAT_RGB_565)
|
mBlurFormat(GGL_PIXEL_FORMAT_RGB_565)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class LayerBlur : public LayerBaseClient
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LayerBlur(SurfaceFlinger* flinger, DisplayID display,
|
LayerBlur(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client, int32_t i);
|
const sp<Client>& client);
|
||||||
virtual ~LayerBlur();
|
virtual ~LayerBlur();
|
||||||
|
|
||||||
virtual void onDraw(const Region& clip) const;
|
virtual void onDraw(const Region& clip) const;
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ gralloc_module_t const* LayerBuffer::sGrallocModule = 0;
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
|
LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client, int32_t i)
|
const sp<Client>& client)
|
||||||
: LayerBaseClient(flinger, display, client, i),
|
: LayerBaseClient(flinger, display, client),
|
||||||
mNeedsBlending(false), mBlitEngine(0)
|
mNeedsBlending(false), mBlitEngine(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -60,8 +60,7 @@ LayerBuffer::~LayerBuffer()
|
|||||||
void LayerBuffer::onFirstRef()
|
void LayerBuffer::onFirstRef()
|
||||||
{
|
{
|
||||||
LayerBaseClient::onFirstRef();
|
LayerBaseClient::onFirstRef();
|
||||||
mSurface = new SurfaceLayerBuffer(mFlinger, clientIndex(),
|
mSurface = new SurfaceLayerBuffer(mFlinger, this);
|
||||||
const_cast<LayerBuffer *>(this));
|
|
||||||
|
|
||||||
hw_module_t const* module = (hw_module_t const*)sGrallocModule;
|
hw_module_t const* module = (hw_module_t const*)sGrallocModule;
|
||||||
if (!module) {
|
if (!module) {
|
||||||
@@ -204,9 +203,9 @@ sp<LayerBuffer::Source> LayerBuffer::clearSource() {
|
|||||||
// LayerBuffer::SurfaceLayerBuffer
|
// LayerBuffer::SurfaceLayerBuffer
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
|
LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer(
|
||||||
SurfaceID id, const sp<LayerBuffer>& owner)
|
const sp<SurfaceFlinger>& flinger, const sp<LayerBuffer>& owner)
|
||||||
: LayerBaseClient::Surface(flinger, id, owner->getIdentity(), owner)
|
: LayerBaseClient::Surface(flinger, owner->getIdentity(), owner)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class LayerBuffer : public LayerBaseClient
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
|
LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client, int32_t i);
|
const sp<Client>& client);
|
||||||
virtual ~LayerBuffer();
|
virtual ~LayerBuffer();
|
||||||
|
|
||||||
virtual void onFirstRef();
|
virtual void onFirstRef();
|
||||||
@@ -189,7 +189,7 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
|
SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
|
||||||
SurfaceID id, const sp<LayerBuffer>& owner);
|
const sp<LayerBuffer>& owner);
|
||||||
virtual ~SurfaceLayerBuffer();
|
virtual ~SurfaceLayerBuffer();
|
||||||
|
|
||||||
virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
|
virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ int32_t LayerDim::sHeight;
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
|
LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client, int32_t i)
|
const sp<Client>& client)
|
||||||
: LayerBaseClient(flinger, display, client, i)
|
: LayerBaseClient(flinger, display, client)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class LayerDim : public LayerBaseClient
|
|||||||
static int32_t sHeight;
|
static int32_t sHeight;
|
||||||
public:
|
public:
|
||||||
LayerDim(SurfaceFlinger* flinger, DisplayID display,
|
LayerDim(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client, int32_t i);
|
const sp<Client>& client);
|
||||||
virtual ~LayerDim();
|
virtual ~LayerDim();
|
||||||
|
|
||||||
virtual void onDraw(const Region& clip) const;
|
virtual void onDraw(const Region& clip) const;
|
||||||
|
|||||||
@@ -227,54 +227,15 @@ sp<IMemoryHeap> SurfaceFlinger::getCblk() const
|
|||||||
|
|
||||||
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
|
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
|
||||||
{
|
{
|
||||||
Mutex::Autolock _l(mStateLock);
|
sp<ISurfaceComposerClient> bclient;
|
||||||
uint32_t token = mTokens.acquire();
|
sp<Client> client(new Client(this));
|
||||||
|
status_t err = client->initCheck();
|
||||||
sp<Client> client = new Client(token, this);
|
if (err == NO_ERROR) {
|
||||||
if (client->ctrlblk == 0) {
|
bclient = client;
|
||||||
mTokens.release(token);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
status_t err = mClientsMap.add(token, client);
|
|
||||||
if (err < 0) {
|
|
||||||
mTokens.release(token);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
sp<BClient> bclient =
|
|
||||||
new BClient(this, token, client->getControlBlockMemory());
|
|
||||||
return bclient;
|
return bclient;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::destroyConnection(ClientID cid)
|
|
||||||
{
|
|
||||||
Mutex::Autolock _l(mStateLock);
|
|
||||||
sp<Client> client = mClientsMap.valueFor(cid);
|
|
||||||
if (client != 0) {
|
|
||||||
// free all the layers this client owns
|
|
||||||
Vector< wp<LayerBaseClient> > layers(client->getLayers());
|
|
||||||
const size_t count = layers.size();
|
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
|
||||||
sp<LayerBaseClient> layer(layers[i].promote());
|
|
||||||
if (layer != 0) {
|
|
||||||
purgatorizeLayer_l(layer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the resources associated with this client will be freed
|
|
||||||
// during the next transaction, after these surfaces have been
|
|
||||||
// properly removed from the screen
|
|
||||||
|
|
||||||
// remove this client from our ClientID->Client mapping.
|
|
||||||
mClientsMap.removeItem(cid);
|
|
||||||
|
|
||||||
// and add it to the list of disconnected clients
|
|
||||||
mDisconnectedClients.add(client);
|
|
||||||
|
|
||||||
// request a transaction
|
|
||||||
setTransactionFlags(eTransactionNeeded);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
@@ -665,10 +626,6 @@ void SurfaceFlinger::handleTransactionLocked(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get rid of all resources we don't need anymore
|
|
||||||
// (layers and clients)
|
|
||||||
free_resources_l();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commitTransaction();
|
commitTransaction();
|
||||||
@@ -1071,6 +1028,27 @@ status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
|
||||||
|
{
|
||||||
|
ssize_t i = mCurrentState.layersSortedByZ.add(
|
||||||
|
layer, &LayerBase::compareCurrentStateZ);
|
||||||
|
return (i < 0) ? status_t(i) : status_t(NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
|
||||||
|
const sp<LayerBaseClient>& lbc)
|
||||||
|
{
|
||||||
|
Mutex::Autolock _l(mStateLock);
|
||||||
|
|
||||||
|
// attach this layer to the client
|
||||||
|
ssize_t name = client->attachLayer(lbc);
|
||||||
|
|
||||||
|
// add this layer to the current state list
|
||||||
|
addLayer_l(lbc);
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
|
status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
|
||||||
{
|
{
|
||||||
Mutex::Autolock _l(mStateLock);
|
Mutex::Autolock _l(mStateLock);
|
||||||
@@ -1080,35 +1058,11 @@ status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
|
|
||||||
{
|
|
||||||
layer->forceVisibilityTransaction();
|
|
||||||
setTransactionFlags(eTraversalNeeded);
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
|
|
||||||
{
|
|
||||||
ssize_t i = mCurrentState.layersSortedByZ.add(
|
|
||||||
layer, &LayerBase::compareCurrentStateZ);
|
|
||||||
return (i < 0) ? status_t(i) : status_t(NO_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t SurfaceFlinger::addClientLayer_l(const sp<LayerBaseClient>& lbc)
|
|
||||||
{
|
|
||||||
ssize_t serverIndex = lbc->serverIndex();
|
|
||||||
return mLayerMap.add(serverIndex, lbc);
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
|
status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
|
||||||
{
|
{
|
||||||
ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
|
ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
mLayersRemoved = true;
|
mLayersRemoved = true;
|
||||||
ssize_t serverIndex = layerBase->serverIndex();
|
|
||||||
if (serverIndex >= 0) {
|
|
||||||
mLayerMap.removeItem(serverIndex);
|
|
||||||
}
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
return status_t(index);
|
return status_t(index);
|
||||||
@@ -1123,22 +1077,16 @@ status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
|
|||||||
|
|
||||||
// it's possible that we don't find a layer, because it might
|
// it's possible that we don't find a layer, because it might
|
||||||
// have been destroyed already -- this is not technically an error
|
// have been destroyed already -- this is not technically an error
|
||||||
// from the user because there is a race between BClient::destroySurface(),
|
// from the user because there is a race between Client::destroySurface(),
|
||||||
// ~BClient() and ~ISurface().
|
// ~Client() and ~ISurface().
|
||||||
return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
|
return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
|
||||||
void SurfaceFlinger::free_resources_l()
|
|
||||||
{
|
{
|
||||||
// free resources associated with disconnected clients
|
layer->forceVisibilityTransaction();
|
||||||
Vector< sp<Client> >& disconnectedClients(mDisconnectedClients);
|
setTransactionFlags(eTraversalNeeded);
|
||||||
const size_t count = disconnectedClients.size();
|
return NO_ERROR;
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
|
||||||
sp<Client> client = disconnectedClients[i];
|
|
||||||
mTokens.release(client->cid);
|
|
||||||
}
|
|
||||||
disconnectedClients.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
|
uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
|
||||||
@@ -1229,7 +1177,7 @@ int SurfaceFlinger::setOrientation(DisplayID dpy,
|
|||||||
return orientation;
|
return orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
|
sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
|
||||||
const String8& name, ISurfaceComposerClient::surface_data_t* params,
|
const String8& name, ISurfaceComposerClient::surface_data_t* params,
|
||||||
DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
|
DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
|
||||||
uint32_t flags)
|
uint32_t flags)
|
||||||
@@ -1243,57 +1191,44 @@ sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
|
|||||||
return surfaceHandle;
|
return surfaceHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex::Autolock _l(mStateLock);
|
|
||||||
sp<Client> client = mClientsMap.valueFor(clientId);
|
|
||||||
if (UNLIKELY(client == 0)) {
|
|
||||||
LOGE("createSurface() failed, client not found (id=%d)", clientId);
|
|
||||||
return surfaceHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
//LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
|
//LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
|
||||||
int32_t id = client->generateId(pid);
|
|
||||||
if (uint32_t(id) >= SharedBufferStack::NUM_LAYERS_MAX) {
|
|
||||||
LOGE("createSurface() failed, generateId = %d", id);
|
|
||||||
return surfaceHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flags & eFXSurfaceMask) {
|
switch (flags & eFXSurfaceMask) {
|
||||||
case eFXSurfaceNormal:
|
case eFXSurfaceNormal:
|
||||||
if (UNLIKELY(flags & ePushBuffers)) {
|
if (UNLIKELY(flags & ePushBuffers)) {
|
||||||
layer = createPushBuffersSurfaceLocked(client, d, id,
|
layer = createPushBuffersSurface(client, d, w, h, flags);
|
||||||
w, h, flags);
|
|
||||||
} else {
|
} else {
|
||||||
layer = createNormalSurfaceLocked(client, d, id,
|
layer = createNormalSurface(client, d, w, h, flags, format);
|
||||||
w, h, flags, format);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case eFXSurfaceBlur:
|
case eFXSurfaceBlur:
|
||||||
layer = createBlurSurfaceLocked(client, d, id, w, h, flags);
|
layer = createBlurSurface(client, d, w, h, flags);
|
||||||
break;
|
break;
|
||||||
case eFXSurfaceDim:
|
case eFXSurfaceDim:
|
||||||
layer = createDimSurfaceLocked(client, d, id, w, h, flags);
|
layer = createDimSurface(client, d, w, h, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer != 0) {
|
if (layer != 0) {
|
||||||
|
layer->initStates(w, h, flags);
|
||||||
layer->setName(name);
|
layer->setName(name);
|
||||||
setTransactionFlags(eTransactionNeeded);
|
ssize_t token = addClientLayer(client, layer);
|
||||||
surfaceHandle = layer->getSurface();
|
surfaceHandle = layer->getSurface();
|
||||||
if (surfaceHandle != 0) {
|
if (surfaceHandle != 0) {
|
||||||
params->token = surfaceHandle->getToken();
|
params->token = token;
|
||||||
params->identity = surfaceHandle->getIdentity();
|
params->identity = surfaceHandle->getIdentity();
|
||||||
params->width = w;
|
params->width = w;
|
||||||
params->height = h;
|
params->height = h;
|
||||||
params->format = format;
|
params->format = format;
|
||||||
}
|
}
|
||||||
|
setTransactionFlags(eTransactionNeeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
return surfaceHandle;
|
return surfaceHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked(
|
sp<LayerBaseClient> SurfaceFlinger::createNormalSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
int32_t id, uint32_t w, uint32_t h, uint32_t flags,
|
uint32_t w, uint32_t h, uint32_t flags,
|
||||||
PixelFormat& format)
|
PixelFormat& format)
|
||||||
{
|
{
|
||||||
// initialize the surfaces
|
// initialize the surfaces
|
||||||
@@ -1307,53 +1242,43 @@ sp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<Layer> layer = new Layer(this, display, client, id);
|
sp<Layer> layer = new Layer(this, display, client);
|
||||||
status_t err = layer->setBuffers(w, h, format, flags);
|
status_t err = layer->setBuffers(w, h, format, flags);
|
||||||
if (LIKELY(err == NO_ERROR)) {
|
if (LIKELY(err != NO_ERROR)) {
|
||||||
layer->initStates(w, h, flags);
|
|
||||||
addLayer_l(layer);
|
|
||||||
addClientLayer_l(layer);
|
|
||||||
} else {
|
|
||||||
LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
|
LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
|
||||||
layer.clear();
|
layer.clear();
|
||||||
}
|
}
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<LayerBaseClient> SurfaceFlinger::createBlurSurfaceLocked(
|
sp<LayerBaseClient> SurfaceFlinger::createBlurSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
int32_t id, uint32_t w, uint32_t h, uint32_t flags)
|
uint32_t w, uint32_t h, uint32_t flags)
|
||||||
{
|
{
|
||||||
sp<LayerBlur> layer = new LayerBlur(this, display, client, id);
|
sp<LayerBlur> layer = new LayerBlur(this, display, client);
|
||||||
layer->initStates(w, h, flags);
|
layer->initStates(w, h, flags);
|
||||||
addLayer_l(layer);
|
|
||||||
addClientLayer_l(layer);
|
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<LayerBaseClient> SurfaceFlinger::createDimSurfaceLocked(
|
sp<LayerBaseClient> SurfaceFlinger::createDimSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
int32_t id, uint32_t w, uint32_t h, uint32_t flags)
|
uint32_t w, uint32_t h, uint32_t flags)
|
||||||
{
|
{
|
||||||
sp<LayerDim> layer = new LayerDim(this, display, client, id);
|
sp<LayerDim> layer = new LayerDim(this, display, client);
|
||||||
layer->initStates(w, h, flags);
|
layer->initStates(w, h, flags);
|
||||||
addLayer_l(layer);
|
|
||||||
addClientLayer_l(layer);
|
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<LayerBaseClient> SurfaceFlinger::createPushBuffersSurfaceLocked(
|
sp<LayerBaseClient> SurfaceFlinger::createPushBuffersSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
int32_t id, uint32_t w, uint32_t h, uint32_t flags)
|
uint32_t w, uint32_t h, uint32_t flags)
|
||||||
{
|
{
|
||||||
sp<LayerBuffer> layer = new LayerBuffer(this, display, client, id);
|
sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
|
||||||
layer->initStates(w, h, flags);
|
layer->initStates(w, h, flags);
|
||||||
addLayer_l(layer);
|
|
||||||
addClientLayer_l(layer);
|
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t SurfaceFlinger::removeSurface(SurfaceID index)
|
status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* called by the window manager, when a surface should be marked for
|
* called by the window manager, when a surface should be marked for
|
||||||
@@ -1366,7 +1291,7 @@ status_t SurfaceFlinger::removeSurface(SurfaceID index)
|
|||||||
|
|
||||||
status_t err = NAME_NOT_FOUND;
|
status_t err = NAME_NOT_FOUND;
|
||||||
Mutex::Autolock _l(mStateLock);
|
Mutex::Autolock _l(mStateLock);
|
||||||
sp<LayerBaseClient> layer = getLayerUser_l(index);
|
sp<LayerBaseClient> layer = client->getLayerUser(sid);
|
||||||
if (layer != 0) {
|
if (layer != 0) {
|
||||||
err = purgatorizeLayer_l(layer);
|
err = purgatorizeLayer_l(layer);
|
||||||
if (err == NO_ERROR) {
|
if (err == NO_ERROR) {
|
||||||
@@ -1411,16 +1336,15 @@ status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t SurfaceFlinger::setClientState(
|
status_t SurfaceFlinger::setClientState(
|
||||||
ClientID cid,
|
const sp<Client>& client,
|
||||||
int32_t count,
|
int32_t count,
|
||||||
const layer_state_t* states)
|
const layer_state_t* states)
|
||||||
{
|
{
|
||||||
Mutex::Autolock _l(mStateLock);
|
Mutex::Autolock _l(mStateLock);
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
cid <<= 16;
|
|
||||||
for (int i=0 ; i<count ; i++) {
|
for (int i=0 ; i<count ; i++) {
|
||||||
const layer_state_t& s = states[i];
|
const layer_state_t& s(states[i]);
|
||||||
sp<LayerBaseClient> layer(getLayerUser_l(s.surface | cid));
|
sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
|
||||||
if (layer != 0) {
|
if (layer != 0) {
|
||||||
const uint32_t what = s.what;
|
const uint32_t what = s.what;
|
||||||
if (what & ePositionChanged) {
|
if (what & ePositionChanged) {
|
||||||
@@ -1466,12 +1390,6 @@ status_t SurfaceFlinger::setClientState(
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<LayerBaseClient> SurfaceFlinger::getLayerUser_l(SurfaceID s) const
|
|
||||||
{
|
|
||||||
sp<LayerBaseClient> layer = mLayerMap.valueFor(s);
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SurfaceFlinger::screenReleased(int dpy)
|
void SurfaceFlinger::screenReleased(int dpy)
|
||||||
{
|
{
|
||||||
// this may be called by a signal handler, we can't do too much in here
|
// this may be called by a signal handler, we can't do too much in here
|
||||||
@@ -1557,8 +1475,6 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
|
|||||||
result.append(buffer);
|
result.append(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buffer, SIZE, " client count: %d\n", mClientsMap.size());
|
|
||||||
result.append(buffer);
|
|
||||||
const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
|
const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
|
||||||
alloc.dump(result);
|
alloc.dump(result);
|
||||||
|
|
||||||
@@ -1655,8 +1571,8 @@ status_t SurfaceFlinger::onTransact(
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
|
Client::Client(const sp<SurfaceFlinger>& flinger)
|
||||||
: ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
|
: ctrlblk(0), mBitmap(0), mFlinger(flinger)
|
||||||
{
|
{
|
||||||
const int pgsize = getpagesize();
|
const int pgsize = getpagesize();
|
||||||
const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
|
const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
|
||||||
@@ -1668,96 +1584,87 @@ Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
|
|||||||
if (ctrlblk) { // construct the shared structure in-place.
|
if (ctrlblk) { // construct the shared structure in-place.
|
||||||
new(ctrlblk) SharedClient;
|
new(ctrlblk) SharedClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::~Client() {
|
Client::~Client()
|
||||||
|
{
|
||||||
if (ctrlblk) {
|
if (ctrlblk) {
|
||||||
ctrlblk->~SharedClient(); // destroy our shared-structure.
|
ctrlblk->~SharedClient(); // destroy our shared-structure.
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int32_t Client::generateId(int pid)
|
const size_t count = mLayers.size();
|
||||||
{
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
const uint32_t i = clz( ~mBitmap );
|
sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
|
||||||
if (i >= SharedBufferStack::NUM_LAYERS_MAX) {
|
if (layer != 0) {
|
||||||
return NO_MEMORY;
|
mFlinger->removeLayer(layer);
|
||||||
}
|
}
|
||||||
mPid = pid;
|
|
||||||
mInUse.add(uint8_t(i));
|
|
||||||
mBitmap |= 1<<(31-i);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t Client::bindLayer(const sp<LayerBaseClient>& layer, int32_t id)
|
|
||||||
{
|
|
||||||
ssize_t idx = mInUse.indexOf(id);
|
|
||||||
if (idx < 0)
|
|
||||||
return NAME_NOT_FOUND;
|
|
||||||
return mLayers.insertAt(layer, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::free(int32_t id)
|
|
||||||
{
|
|
||||||
ssize_t idx = mInUse.remove(uint8_t(id));
|
|
||||||
if (idx >= 0) {
|
|
||||||
mBitmap &= ~(1<<(31-id));
|
|
||||||
mLayers.removeItemsAt(idx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::isValid(int32_t i) const {
|
status_t Client::initCheck() const {
|
||||||
return (uint32_t(i)<SharedBufferStack::NUM_LAYERS_MAX) &&
|
return ctrlblk == 0 ? NO_INIT : NO_ERROR;
|
||||||
(mBitmap & (1<<(31-i)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
|
||||||
|
{
|
||||||
|
// TODO: get rid of this
|
||||||
|
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);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::free(LayerBaseClient const* 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
|
||||||
|
const size_t count = mLayers.size();
|
||||||
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
|
if (mLayers.valueAt(i) == layer) {
|
||||||
|
mLayers.removeItemsAt(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
|
sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
|
||||||
sp<LayerBaseClient> lbc;
|
sp<LayerBaseClient> lbc;
|
||||||
ssize_t idx = mInUse.indexOf(uint8_t(i));
|
const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
|
||||||
if (idx >= 0) {
|
if (layer != 0) {
|
||||||
lbc = mLayers[idx].promote();
|
lbc = layer.promote();
|
||||||
LOGE_IF(lbc==0, "getLayerUser(i=%d), idx=%d is dead", int(i), int(idx));
|
LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
|
||||||
}
|
}
|
||||||
return lbc;
|
return lbc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
sp<IMemoryHeap> Client::getControlBlock() const {
|
||||||
#if 0
|
return mCblkHeap;
|
||||||
#pragma mark -
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemoryHeap>& cblk)
|
|
||||||
: mId(cid), mFlinger(flinger), mCblk(cblk)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
sp<ISurface> Client::createSurface(
|
||||||
BClient::~BClient() {
|
ISurfaceComposerClient::surface_data_t* params,
|
||||||
// destroy all resources attached to this client
|
int pid, const String8& name,
|
||||||
mFlinger->destroyConnection(mId);
|
DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
|
||||||
}
|
|
||||||
|
|
||||||
sp<IMemoryHeap> BClient::getControlBlock() const {
|
|
||||||
return mCblk;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp<ISurface> BClient::createSurface(
|
|
||||||
ISurfaceComposerClient::surface_data_t* params, int pid,
|
|
||||||
const String8& name,
|
|
||||||
DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
|
|
||||||
uint32_t flags)
|
uint32_t flags)
|
||||||
{
|
{
|
||||||
return mFlinger->createSurface(mId, pid, name, params, display, w, h,
|
return mFlinger->createSurface(this, pid, name, params,
|
||||||
format, flags);
|
display, w, h, format, flags);
|
||||||
}
|
}
|
||||||
|
status_t Client::destroySurface(SurfaceID sid) {
|
||||||
status_t BClient::destroySurface(SurfaceID sid)
|
return mFlinger->removeSurface(this, sid);
|
||||||
{
|
|
||||||
sid |= (mId << 16); // add the client-part to id
|
|
||||||
return mFlinger->removeSurface(sid);
|
|
||||||
}
|
}
|
||||||
|
status_t Client::setState(int32_t count, const layer_state_t* states) {
|
||||||
status_t BClient::setState(int32_t count, const layer_state_t* states)
|
return mFlinger->setClientState(this, count, states);
|
||||||
{
|
|
||||||
return mFlinger->setClientState(mId, count, states);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -36,7 +36,6 @@
|
|||||||
|
|
||||||
#include "Barrier.h"
|
#include "Barrier.h"
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
#include "Tokenizer.h"
|
|
||||||
|
|
||||||
#include "MessageQueue.h"
|
#include "MessageQueue.h"
|
||||||
|
|
||||||
@@ -48,54 +47,48 @@ namespace android {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
class BClient;
|
|
||||||
class DisplayHardware;
|
class DisplayHardware;
|
||||||
class FreezeLock;
|
class FreezeLock;
|
||||||
class Layer;
|
class Layer;
|
||||||
class LayerBuffer;
|
class LayerBuffer;
|
||||||
|
|
||||||
typedef int32_t ClientID;
|
|
||||||
|
|
||||||
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
|
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
|
||||||
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
|
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
class Client : public RefBase
|
class Client : public BnSurfaceComposerClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Client(ClientID cid, const sp<SurfaceFlinger>& flinger);
|
|
||||||
~Client();
|
|
||||||
|
|
||||||
int32_t generateId(int pid);
|
|
||||||
void free(int32_t id);
|
|
||||||
status_t bindLayer(const sp<LayerBaseClient>& layer, int32_t id);
|
|
||||||
|
|
||||||
inline bool isValid(int32_t i) const;
|
|
||||||
sp<LayerBaseClient> getLayerUser(int32_t i) const;
|
|
||||||
|
|
||||||
const Vector< wp<LayerBaseClient> >& getLayers() const {
|
|
||||||
return mLayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sp<IMemoryHeap>& getControlBlockMemory() const {
|
|
||||||
return mCblkHeap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pointer to this client's control block
|
// pointer to this client's control block
|
||||||
SharedClient* ctrlblk;
|
SharedClient* ctrlblk;
|
||||||
ClientID cid;
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
Client(const sp<SurfaceFlinger>& flinger);
|
||||||
|
~Client();
|
||||||
|
|
||||||
|
status_t initCheck() const;
|
||||||
|
|
||||||
|
// protected by SurfaceFlinger::mStateLock
|
||||||
|
ssize_t attachLayer(const sp<LayerBaseClient>& layer);
|
||||||
|
sp<LayerBaseClient> getLayerUser(int32_t i) const;
|
||||||
|
void free(LayerBaseClient const* layer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int getClientPid() const { return mPid; }
|
|
||||||
|
|
||||||
int mPid;
|
// ISurfaceComposerClient interface
|
||||||
uint32_t mBitmap;
|
virtual sp<IMemoryHeap> getControlBlock() const;
|
||||||
SortedVector<uint8_t> mInUse;
|
virtual sp<ISurface> createSurface(
|
||||||
Vector< wp<LayerBaseClient> > mLayers;
|
surface_data_t* params, int pid, const String8& name,
|
||||||
sp<IMemoryHeap> mCblkHeap;
|
DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
|
||||||
sp<SurfaceFlinger> mFlinger;
|
uint32_t flags);
|
||||||
|
virtual status_t destroySurface(SurfaceID surfaceId);
|
||||||
|
virtual status_t setState(int32_t count, const layer_state_t* states);
|
||||||
|
|
||||||
|
uint32_t mBitmap;
|
||||||
|
DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers;
|
||||||
|
sp<IMemoryHeap> mCblkHeap;
|
||||||
|
sp<SurfaceFlinger> mFlinger;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -179,7 +172,7 @@ public:
|
|||||||
status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
|
status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BClient;
|
friend class Client;
|
||||||
friend class LayerBase;
|
friend class LayerBase;
|
||||||
friend class LayerBuffer;
|
friend class LayerBuffer;
|
||||||
friend class LayerBaseClient;
|
friend class LayerBaseClient;
|
||||||
@@ -188,31 +181,33 @@ private:
|
|||||||
friend class LayerBlur;
|
friend class LayerBlur;
|
||||||
friend class LayerDim;
|
friend class LayerDim;
|
||||||
|
|
||||||
sp<ISurface> createSurface(ClientID client, int pid, const String8& name,
|
sp<ISurface> createSurface(const sp<Client>& client,
|
||||||
|
int pid, const String8& name,
|
||||||
ISurfaceComposerClient::surface_data_t* params,
|
ISurfaceComposerClient::surface_data_t* params,
|
||||||
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> createNormalSurfaceLocked(
|
sp<LayerBaseClient> createNormalSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
int32_t id, uint32_t w, uint32_t h, uint32_t flags,
|
uint32_t w, uint32_t h, uint32_t flags,
|
||||||
PixelFormat& format);
|
PixelFormat& format);
|
||||||
|
|
||||||
sp<LayerBaseClient> createBlurSurfaceLocked(
|
sp<LayerBaseClient> createBlurSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
int32_t id, uint32_t w, uint32_t h, uint32_t flags);
|
uint32_t w, uint32_t h, uint32_t flags);
|
||||||
|
|
||||||
sp<LayerBaseClient> createDimSurfaceLocked(
|
sp<LayerBaseClient> createDimSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
int32_t id, uint32_t w, uint32_t h, uint32_t flags);
|
uint32_t w, uint32_t h, uint32_t flags);
|
||||||
|
|
||||||
sp<LayerBaseClient> createPushBuffersSurfaceLocked(
|
sp<LayerBaseClient> createPushBuffersSurface(
|
||||||
const sp<Client>& client, DisplayID display,
|
const sp<Client>& client, DisplayID display,
|
||||||
int32_t id, uint32_t w, uint32_t h, uint32_t flags);
|
uint32_t w, uint32_t h, uint32_t flags);
|
||||||
|
|
||||||
status_t removeSurface(SurfaceID surface_id);
|
status_t removeSurface(const sp<Client>& client, SurfaceID sid);
|
||||||
status_t destroySurface(const sp<LayerBaseClient>& layer);
|
status_t destroySurface(const sp<LayerBaseClient>& layer);
|
||||||
status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states);
|
status_t setClientState(const sp<Client>& client,
|
||||||
|
int32_t count, const layer_state_t* states);
|
||||||
|
|
||||||
|
|
||||||
class LayerVector {
|
class LayerVector {
|
||||||
@@ -275,13 +270,11 @@ private:
|
|||||||
void unlockClients();
|
void unlockClients();
|
||||||
|
|
||||||
|
|
||||||
void destroyConnection(ClientID cid);
|
ssize_t addClientLayer(const sp<Client>& client,
|
||||||
sp<LayerBaseClient> getLayerUser_l(SurfaceID index) const;
|
const sp<LayerBaseClient>& lbc);
|
||||||
status_t addLayer_l(const sp<LayerBase>& layer);
|
status_t addLayer_l(const sp<LayerBase>& layer);
|
||||||
status_t addClientLayer_l(const sp<LayerBaseClient>& lbc);
|
|
||||||
status_t removeLayer_l(const sp<LayerBase>& layer);
|
status_t removeLayer_l(const sp<LayerBase>& layer);
|
||||||
status_t purgatorizeLayer_l(const sp<LayerBase>& layer);
|
status_t purgatorizeLayer_l(const sp<LayerBase>& layer);
|
||||||
void free_resources_l();
|
|
||||||
|
|
||||||
uint32_t getTransactionFlags(uint32_t flags);
|
uint32_t getTransactionFlags(uint32_t flags);
|
||||||
uint32_t setTransactionFlags(uint32_t flags);
|
uint32_t setTransactionFlags(uint32_t flags);
|
||||||
@@ -326,12 +319,8 @@ private:
|
|||||||
bool mResizeTransationPending;
|
bool mResizeTransationPending;
|
||||||
|
|
||||||
// protected by mStateLock (but we could use another lock)
|
// protected by mStateLock (but we could use another lock)
|
||||||
Tokenizer mTokens;
|
GraphicPlane mGraphicPlanes[1];
|
||||||
DefaultKeyedVector<ClientID, sp<Client> > mClientsMap;
|
bool mLayersRemoved;
|
||||||
DefaultKeyedVector<SurfaceID, sp<LayerBaseClient> > mLayerMap;
|
|
||||||
GraphicPlane mGraphicPlanes[1];
|
|
||||||
bool mLayersRemoved;
|
|
||||||
Vector< sp<Client> > mDisconnectedClients;
|
|
||||||
|
|
||||||
// constant members (no synchronization needed for access)
|
// constant members (no synchronization needed for access)
|
||||||
sp<IMemoryHeap> mServerHeap;
|
sp<IMemoryHeap> mServerHeap;
|
||||||
@@ -391,32 +380,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class BClient : public BnSurfaceComposerClient
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BClient(SurfaceFlinger *flinger, ClientID cid,
|
|
||||||
const sp<IMemoryHeap>& cblk);
|
|
||||||
~BClient();
|
|
||||||
|
|
||||||
// ISurfaceComposerClient interface
|
|
||||||
virtual sp<IMemoryHeap> getControlBlock() 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);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ClientID mId;
|
|
||||||
SurfaceFlinger* mFlinger;
|
|
||||||
sp<IMemoryHeap> mCblk;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
|
||||||
|
|||||||
@@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "Tokenizer.h"
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace android {
|
|
||||||
|
|
||||||
ANDROID_BASIC_TYPES_TRAITS(Tokenizer::run_t)
|
|
||||||
|
|
||||||
Tokenizer::Tokenizer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Tokenizer::Tokenizer(const Tokenizer& other)
|
|
||||||
: mRanges(other.mRanges)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Tokenizer::~Tokenizer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Tokenizer::acquire()
|
|
||||||
{
|
|
||||||
if (!mRanges.size() || mRanges[0].first) {
|
|
||||||
_insertTokenAt(0,0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// just extend the first run
|
|
||||||
const run_t& run = mRanges[0];
|
|
||||||
uint32_t token = run.first + run.length;
|
|
||||||
_insertTokenAt(token, 1);
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Tokenizer::isAcquired(uint32_t token) const
|
|
||||||
{
|
|
||||||
return (_indexOrderOf(token) >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t Tokenizer::reserve(uint32_t token)
|
|
||||||
{
|
|
||||||
size_t o;
|
|
||||||
const ssize_t i = _indexOrderOf(token, &o);
|
|
||||||
if (i >= 0) {
|
|
||||||
return BAD_VALUE; // this token is already taken
|
|
||||||
}
|
|
||||||
ssize_t err = _insertTokenAt(token, o);
|
|
||||||
return (err<0) ? err : status_t(NO_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t Tokenizer::release(uint32_t token)
|
|
||||||
{
|
|
||||||
const ssize_t i = _indexOrderOf(token);
|
|
||||||
if (i >= 0) {
|
|
||||||
const run_t& run = mRanges[i];
|
|
||||||
if ((token >= run.first) && (token < run.first+run.length)) {
|
|
||||||
// token in this range, we need to split
|
|
||||||
run_t& run = mRanges.editItemAt(i);
|
|
||||||
if ((token == run.first) || (token == run.first+run.length-1)) {
|
|
||||||
if (token == run.first) {
|
|
||||||
run.first += 1;
|
|
||||||
}
|
|
||||||
run.length -= 1;
|
|
||||||
if (run.length == 0) {
|
|
||||||
// XXX: should we systematically remove a run that's empty?
|
|
||||||
mRanges.removeItemsAt(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// split the run
|
|
||||||
run_t new_run;
|
|
||||||
new_run.first = token+1;
|
|
||||||
new_run.length = run.first+run.length - new_run.first;
|
|
||||||
run.length = token - run.first;
|
|
||||||
mRanges.insertAt(new_run, i+1);
|
|
||||||
}
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NAME_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t Tokenizer::_indexOrderOf(uint32_t token, size_t* order) const
|
|
||||||
{
|
|
||||||
// binary search
|
|
||||||
ssize_t err = NAME_NOT_FOUND;
|
|
||||||
ssize_t l = 0;
|
|
||||||
ssize_t h = mRanges.size()-1;
|
|
||||||
ssize_t mid;
|
|
||||||
const run_t* a = mRanges.array();
|
|
||||||
while (l <= h) {
|
|
||||||
mid = l + (h - l)/2;
|
|
||||||
const run_t* const curr = a + mid;
|
|
||||||
int c = 0;
|
|
||||||
if (token < curr->first) c = 1;
|
|
||||||
else if (token >= curr->first+curr->length) c = -1;
|
|
||||||
if (c == 0) {
|
|
||||||
err = l = mid;
|
|
||||||
break;
|
|
||||||
} else if (c < 0) {
|
|
||||||
l = mid + 1;
|
|
||||||
} else {
|
|
||||||
h = mid - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (order) *order = l;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t Tokenizer::_insertTokenAt(uint32_t token, size_t index)
|
|
||||||
{
|
|
||||||
const size_t c = mRanges.size();
|
|
||||||
|
|
||||||
if (index >= 1) {
|
|
||||||
// do we need to merge with the previous run?
|
|
||||||
run_t& p = mRanges.editItemAt(index-1);
|
|
||||||
if (p.first+p.length == token) {
|
|
||||||
p.length += 1;
|
|
||||||
if (index < c) {
|
|
||||||
const run_t& n = mRanges[index];
|
|
||||||
if (token+1 == n.first) {
|
|
||||||
p.length += n.length;
|
|
||||||
mRanges.removeItemsAt(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index < c) {
|
|
||||||
// do we need to merge with the next run?
|
|
||||||
run_t& n = mRanges.editItemAt(index);
|
|
||||||
if (token+1 == n.first) {
|
|
||||||
n.first -= 1;
|
|
||||||
n.length += 1;
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mRanges.insertAt(run_t(token,1), index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Tokenizer::dump() const
|
|
||||||
{
|
|
||||||
const run_t* ranges = mRanges.array();
|
|
||||||
const size_t c = mRanges.size();
|
|
||||||
printf("Tokenizer (%p, size = %d)\n", this, int(c));
|
|
||||||
for (size_t i=0 ; i<c ; i++) {
|
|
||||||
printf("%u: (%u, %u)\n", i,
|
|
||||||
uint32_t(ranges[i].first), uint32_t(ranges[i].length));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // namespace android
|
|
||||||
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ANDROID_TOKENIZER_H
|
|
||||||
#define ANDROID_TOKENIZER_H
|
|
||||||
|
|
||||||
#include <utils/Vector.h>
|
|
||||||
#include <utils/Errors.h>
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace android {
|
|
||||||
|
|
||||||
class Tokenizer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Tokenizer();
|
|
||||||
Tokenizer(const Tokenizer& other);
|
|
||||||
~Tokenizer();
|
|
||||||
|
|
||||||
uint32_t acquire();
|
|
||||||
status_t reserve(uint32_t token);
|
|
||||||
status_t release(uint32_t token);
|
|
||||||
bool isAcquired(uint32_t token) const;
|
|
||||||
|
|
||||||
void dump() const;
|
|
||||||
|
|
||||||
struct run_t {
|
|
||||||
run_t() {};
|
|
||||||
run_t(uint32_t f, uint32_t l) : first(f), length(l) {}
|
|
||||||
uint32_t first;
|
|
||||||
uint32_t length;
|
|
||||||
};
|
|
||||||
private:
|
|
||||||
ssize_t _indexOrderOf(uint32_t token, size_t* order=0) const;
|
|
||||||
ssize_t _insertTokenAt(uint32_t token, size_t index);
|
|
||||||
Vector<run_t> mRanges;
|
|
||||||
};
|
|
||||||
|
|
||||||
}; // namespace android
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#endif // ANDROID_TOKENIZER_H
|
|
||||||
Reference in New Issue
Block a user