cleanup. waitForCondition() now uses polymorphsim instead of templtes
the reason for the above change is that waitForCondition() had become large over time, mainly to handle error cases, using inlines to evaluate the condition doesn't buys us much anymore while it increases code size. Change-Id: I2595d850832628954b900ab8bb1796c863447bc7
This commit is contained in:
parent
0a8cd0689a
commit
b296533607
@ -176,60 +176,21 @@ protected:
|
||||
SharedBufferStack& stack;
|
||||
inline ConditionBase(SharedBufferBase* sbc)
|
||||
: stack(*sbc->mSharedStack) { }
|
||||
virtual ~ConditionBase() { };
|
||||
virtual bool operator()() const = 0;
|
||||
virtual const char* name() const = 0;
|
||||
};
|
||||
status_t waitForCondition(const ConditionBase& condition);
|
||||
|
||||
struct UpdateBase {
|
||||
SharedBufferStack& stack;
|
||||
inline UpdateBase(SharedBufferBase* sbb)
|
||||
: stack(*sbb->mSharedStack) { }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
status_t waitForCondition(T condition);
|
||||
|
||||
template <typename T>
|
||||
status_t updateCondition(T update);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
status_t SharedBufferBase::waitForCondition(T condition)
|
||||
{
|
||||
const SharedBufferStack& stack( *mSharedStack );
|
||||
SharedClient& client( *mSharedClient );
|
||||
const nsecs_t TIMEOUT = s2ns(1);
|
||||
Mutex::Autolock _l(client.lock);
|
||||
while ((condition()==false) &&
|
||||
(stack.identity == mIdentity) &&
|
||||
(stack.status == NO_ERROR))
|
||||
{
|
||||
status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
|
||||
|
||||
// handle errors and timeouts
|
||||
if (CC_UNLIKELY(err != NO_ERROR)) {
|
||||
if (err == TIMED_OUT) {
|
||||
if (condition()) {
|
||||
LOGE("waitForCondition(%s) timed out (identity=%d), "
|
||||
"but condition is true! We recovered but it "
|
||||
"shouldn't happen." , T::name(),
|
||||
stack.identity);
|
||||
break;
|
||||
} else {
|
||||
LOGW("waitForCondition(%s) timed out "
|
||||
"(identity=%d, status=%d). "
|
||||
"CPU may be pegged. trying again.", T::name(),
|
||||
stack.identity, stack.status);
|
||||
}
|
||||
} else {
|
||||
LOGE("waitForCondition(%s) error (%s) ",
|
||||
T::name(), strerror(-err));
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
status_t SharedBufferBase::updateCondition(T update) {
|
||||
SharedClient& client( *mSharedClient );
|
||||
@ -275,15 +236,15 @@ private:
|
||||
|
||||
struct DequeueCondition : public ConditionBase {
|
||||
inline DequeueCondition(SharedBufferClient* sbc);
|
||||
inline bool operator()();
|
||||
static inline const char* name() { return "DequeueCondition"; }
|
||||
inline bool operator()() const;
|
||||
inline const char* name() const { return "DequeueCondition"; }
|
||||
};
|
||||
|
||||
struct LockCondition : public ConditionBase {
|
||||
int buf;
|
||||
inline LockCondition(SharedBufferClient* sbc, int buf);
|
||||
inline bool operator()();
|
||||
static inline const char* name() { return "LockCondition"; }
|
||||
inline bool operator()() const;
|
||||
inline const char* name() const { return "LockCondition"; }
|
||||
};
|
||||
|
||||
int32_t tail;
|
||||
@ -334,8 +295,8 @@ private:
|
||||
struct ReallocateCondition : public ConditionBase {
|
||||
int buf;
|
||||
inline ReallocateCondition(SharedBufferBase* sbb, int buf);
|
||||
inline bool operator()();
|
||||
static inline const char* name() { return "ReallocateCondition"; }
|
||||
inline bool operator()() const;
|
||||
inline const char* name() const { return "ReallocateCondition"; }
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -165,38 +165,36 @@ public:
|
||||
// setSwapRectangle() is intended to be used by GL ES clients
|
||||
void setSwapRectangle(const Rect& r);
|
||||
|
||||
|
||||
private:
|
||||
// can't be copied
|
||||
Surface& operator = (Surface& rhs);
|
||||
Surface(const Surface& rhs);
|
||||
|
||||
Surface(const sp<SurfaceControl>& control);
|
||||
void init();
|
||||
~Surface();
|
||||
|
||||
friend class SurfaceComposerClient;
|
||||
friend class SurfaceControl;
|
||||
|
||||
|
||||
/*
|
||||
* Android frameworks friends
|
||||
* (eventually this should go away and be replaced by proper APIs)
|
||||
*/
|
||||
// camera and camcorder need access to the ISurface binder interface for preview
|
||||
friend class Camera;
|
||||
friend class MediaRecorder;
|
||||
// mediaplayer needs access to ISurface for display
|
||||
// MediaPlayer needs access to ISurface for display
|
||||
friend class MediaPlayer;
|
||||
friend class IOMX;
|
||||
// this is just to be able to write some unit tests
|
||||
friend class Test;
|
||||
|
||||
sp<SurfaceComposerClient> getClient() const;
|
||||
sp<ISurface> getISurface() const;
|
||||
private:
|
||||
friend class SurfaceComposerClient;
|
||||
friend class SurfaceControl;
|
||||
|
||||
status_t getBufferLocked(int index, int usage);
|
||||
// can't be copied
|
||||
Surface& operator = (Surface& rhs);
|
||||
Surface(const Surface& rhs);
|
||||
|
||||
status_t validate() const;
|
||||
Surface(const sp<SurfaceControl>& control);
|
||||
~Surface();
|
||||
|
||||
inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
|
||||
inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
|
||||
|
||||
/*
|
||||
* android_native_window_t hooks
|
||||
*/
|
||||
static int setSwapInterval(android_native_window_t* window, int interval);
|
||||
static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
|
||||
static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
|
||||
@ -210,8 +208,6 @@ private:
|
||||
int query(int what, int* value);
|
||||
int perform(int operation, va_list args);
|
||||
|
||||
status_t dequeueBuffer(sp<GraphicBuffer>* buffer);
|
||||
|
||||
void dispatch_setUsage(va_list args);
|
||||
int dispatch_connect(va_list args);
|
||||
int dispatch_disconnect(va_list args);
|
||||
@ -222,6 +218,20 @@ private:
|
||||
int disconnect(int api);
|
||||
int crop(Rect const* rect);
|
||||
|
||||
/*
|
||||
* private stuff...
|
||||
*/
|
||||
void init();
|
||||
status_t validate() const;
|
||||
sp<SurfaceComposerClient> getClient() const;
|
||||
sp<ISurface> getISurface() const;
|
||||
|
||||
inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
|
||||
inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
|
||||
|
||||
status_t getBufferLocked(int index, int usage);
|
||||
int getBufferIndex(const sp<GraphicBuffer>& buffer) const;
|
||||
|
||||
uint32_t getUsage() const;
|
||||
int getConnectedApi() const;
|
||||
|
||||
|
@ -195,6 +195,42 @@ int32_t SharedBufferBase::computeTail() const
|
||||
return (mNumBuffers + stack.head - stack.available + 1) % mNumBuffers;
|
||||
}
|
||||
|
||||
status_t SharedBufferBase::waitForCondition(const ConditionBase& condition)
|
||||
{
|
||||
const SharedBufferStack& stack( *mSharedStack );
|
||||
SharedClient& client( *mSharedClient );
|
||||
const nsecs_t TIMEOUT = s2ns(1);
|
||||
const int identity = mIdentity;
|
||||
|
||||
Mutex::Autolock _l(client.lock);
|
||||
while ((condition()==false) &&
|
||||
(stack.identity == identity) &&
|
||||
(stack.status == NO_ERROR))
|
||||
{
|
||||
status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
|
||||
// handle errors and timeouts
|
||||
if (CC_UNLIKELY(err != NO_ERROR)) {
|
||||
if (err == TIMED_OUT) {
|
||||
if (condition()) {
|
||||
LOGE("waitForCondition(%s) timed out (identity=%d), "
|
||||
"but condition is true! We recovered but it "
|
||||
"shouldn't happen." , condition.name(), stack.identity);
|
||||
break;
|
||||
} else {
|
||||
LOGW("waitForCondition(%s) timed out "
|
||||
"(identity=%d, status=%d). "
|
||||
"CPU may be pegged. trying again.", condition.name(),
|
||||
stack.identity, stack.status);
|
||||
}
|
||||
} else {
|
||||
LOGE("waitForCondition(%s) error (%s) ",
|
||||
condition.name(), strerror(-err));
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
|
||||
}
|
||||
// ============================================================================
|
||||
// conditions and updates
|
||||
// ============================================================================
|
||||
@ -202,14 +238,14 @@ int32_t SharedBufferBase::computeTail() const
|
||||
SharedBufferClient::DequeueCondition::DequeueCondition(
|
||||
SharedBufferClient* sbc) : ConditionBase(sbc) {
|
||||
}
|
||||
bool SharedBufferClient::DequeueCondition::operator()() {
|
||||
bool SharedBufferClient::DequeueCondition::operator()() const {
|
||||
return stack.available > 0;
|
||||
}
|
||||
|
||||
SharedBufferClient::LockCondition::LockCondition(
|
||||
SharedBufferClient* sbc, int buf) : ConditionBase(sbc), buf(buf) {
|
||||
}
|
||||
bool SharedBufferClient::LockCondition::operator()() {
|
||||
bool SharedBufferClient::LockCondition::operator()() const {
|
||||
return (buf != stack.head ||
|
||||
(stack.queued > 0 && stack.inUse != buf));
|
||||
}
|
||||
@ -217,7 +253,7 @@ bool SharedBufferClient::LockCondition::operator()() {
|
||||
SharedBufferServer::ReallocateCondition::ReallocateCondition(
|
||||
SharedBufferBase* sbb, int buf) : ConditionBase(sbb), buf(buf) {
|
||||
}
|
||||
bool SharedBufferServer::ReallocateCondition::operator()() {
|
||||
bool SharedBufferServer::ReallocateCondition::operator()() const {
|
||||
// TODO: we should also check that buf has been dequeued
|
||||
return (buf != stack.head);
|
||||
}
|
||||
|
@ -463,18 +463,6 @@ int Surface::perform(android_native_window_t* window,
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer) {
|
||||
android_native_buffer_t* out;
|
||||
status_t err = dequeueBuffer(&out);
|
||||
if (err == NO_ERROR) {
|
||||
*buffer = GraphicBuffer::getSelf(out);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
int Surface::dequeueBuffer(android_native_buffer_t** buffer)
|
||||
{
|
||||
sp<SurfaceComposerClient> client(getClient());
|
||||
@ -530,7 +518,7 @@ int Surface::lockBuffer(android_native_buffer_t* buffer)
|
||||
if (err != NO_ERROR)
|
||||
return err;
|
||||
|
||||
int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
|
||||
int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
|
||||
err = mSharedBufferClient->lock(bufIdx);
|
||||
LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
|
||||
return err;
|
||||
@ -547,7 +535,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer)
|
||||
mDirtyRegion.set(mSwapRectangle);
|
||||
}
|
||||
|
||||
int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
|
||||
int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
|
||||
mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
|
||||
mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
|
||||
err = mSharedBufferClient->queue(bufIdx);
|
||||
@ -722,13 +710,14 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
|
||||
// we're intending to do software rendering from this point
|
||||
setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
|
||||
|
||||
sp<GraphicBuffer> backBuffer;
|
||||
status_t err = dequeueBuffer(&backBuffer);
|
||||
android_native_buffer_t* out;
|
||||
status_t err = dequeueBuffer(&out);
|
||||
LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
|
||||
if (err == NO_ERROR) {
|
||||
sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
|
||||
err = lockBuffer(backBuffer.get());
|
||||
LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
|
||||
backBuffer->getIndex(), strerror(-err));
|
||||
getBufferIndex(backBuffer), strerror(-err));
|
||||
if (err == NO_ERROR) {
|
||||
const Rect bounds(backBuffer->width, backBuffer->height);
|
||||
const Region boundsRegion(bounds);
|
||||
@ -797,7 +786,7 @@ status_t Surface::unlockAndPost()
|
||||
|
||||
err = queueBuffer(mLockedBuffer.get());
|
||||
LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
|
||||
mLockedBuffer->getIndex(), strerror(-err));
|
||||
getBufferIndex(mLockedBuffer), strerror(-err));
|
||||
|
||||
mPostedBuffer = mLockedBuffer;
|
||||
mLockedBuffer = 0;
|
||||
@ -809,6 +798,11 @@ void Surface::setSwapRectangle(const Rect& r) {
|
||||
mSwapRectangle = r;
|
||||
}
|
||||
|
||||
int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
|
||||
{
|
||||
return buffer->getIndex();
|
||||
}
|
||||
|
||||
status_t Surface::getBufferLocked(int index, int usage)
|
||||
{
|
||||
sp<ISurface> s(mSurface);
|
||||
|
Loading…
Reference in New Issue
Block a user