Merge "cleanup. waitForCondition() now uses polymorphsim instead of templtes" into kraken
This commit is contained in:
committed by
Android (Google) Code Review
commit
daedd81f08
@@ -176,60 +176,21 @@ protected:
|
|||||||
SharedBufferStack& stack;
|
SharedBufferStack& stack;
|
||||||
inline ConditionBase(SharedBufferBase* sbc)
|
inline ConditionBase(SharedBufferBase* sbc)
|
||||||
: stack(*sbc->mSharedStack) { }
|
: stack(*sbc->mSharedStack) { }
|
||||||
|
virtual ~ConditionBase() { };
|
||||||
|
virtual bool operator()() const = 0;
|
||||||
|
virtual const char* name() const = 0;
|
||||||
};
|
};
|
||||||
|
status_t waitForCondition(const ConditionBase& condition);
|
||||||
|
|
||||||
struct UpdateBase {
|
struct UpdateBase {
|
||||||
SharedBufferStack& stack;
|
SharedBufferStack& stack;
|
||||||
inline UpdateBase(SharedBufferBase* sbb)
|
inline UpdateBase(SharedBufferBase* sbb)
|
||||||
: stack(*sbb->mSharedStack) { }
|
: stack(*sbb->mSharedStack) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
status_t waitForCondition(T condition);
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
status_t updateCondition(T update);
|
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>
|
template <typename T>
|
||||||
status_t SharedBufferBase::updateCondition(T update) {
|
status_t SharedBufferBase::updateCondition(T update) {
|
||||||
SharedClient& client( *mSharedClient );
|
SharedClient& client( *mSharedClient );
|
||||||
@@ -275,15 +236,15 @@ private:
|
|||||||
|
|
||||||
struct DequeueCondition : public ConditionBase {
|
struct DequeueCondition : public ConditionBase {
|
||||||
inline DequeueCondition(SharedBufferClient* sbc);
|
inline DequeueCondition(SharedBufferClient* sbc);
|
||||||
inline bool operator()();
|
inline bool operator()() const;
|
||||||
static inline const char* name() { return "DequeueCondition"; }
|
inline const char* name() const { return "DequeueCondition"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LockCondition : public ConditionBase {
|
struct LockCondition : public ConditionBase {
|
||||||
int buf;
|
int buf;
|
||||||
inline LockCondition(SharedBufferClient* sbc, int buf);
|
inline LockCondition(SharedBufferClient* sbc, int buf);
|
||||||
inline bool operator()();
|
inline bool operator()() const;
|
||||||
static inline const char* name() { return "LockCondition"; }
|
inline const char* name() const { return "LockCondition"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t tail;
|
int32_t tail;
|
||||||
@@ -334,8 +295,8 @@ private:
|
|||||||
struct ReallocateCondition : public ConditionBase {
|
struct ReallocateCondition : public ConditionBase {
|
||||||
int buf;
|
int buf;
|
||||||
inline ReallocateCondition(SharedBufferBase* sbb, int buf);
|
inline ReallocateCondition(SharedBufferBase* sbb, int buf);
|
||||||
inline bool operator()();
|
inline bool operator()() const;
|
||||||
static inline const char* name() { return "ReallocateCondition"; }
|
inline const char* name() const { return "ReallocateCondition"; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -165,38 +165,36 @@ public:
|
|||||||
// setSwapRectangle() is intended to be used by GL ES clients
|
// setSwapRectangle() is intended to be used by GL ES clients
|
||||||
void setSwapRectangle(const Rect& r);
|
void setSwapRectangle(const Rect& r);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// can't be copied
|
/*
|
||||||
Surface& operator = (Surface& rhs);
|
* Android frameworks friends
|
||||||
Surface(const Surface& rhs);
|
* (eventually this should go away and be replaced by proper APIs)
|
||||||
|
*/
|
||||||
Surface(const sp<SurfaceControl>& control);
|
|
||||||
void init();
|
|
||||||
~Surface();
|
|
||||||
|
|
||||||
friend class SurfaceComposerClient;
|
|
||||||
friend class SurfaceControl;
|
|
||||||
|
|
||||||
|
|
||||||
// camera and camcorder need access to the ISurface binder interface for preview
|
// camera and camcorder need access to the ISurface binder interface for preview
|
||||||
friend class Camera;
|
friend class Camera;
|
||||||
friend class MediaRecorder;
|
friend class MediaRecorder;
|
||||||
// mediaplayer needs access to ISurface for display
|
// MediaPlayer needs access to ISurface for display
|
||||||
friend class MediaPlayer;
|
friend class MediaPlayer;
|
||||||
friend class IOMX;
|
friend class IOMX;
|
||||||
// this is just to be able to write some unit tests
|
// this is just to be able to write some unit tests
|
||||||
friend class Test;
|
friend class Test;
|
||||||
|
|
||||||
sp<SurfaceComposerClient> getClient() const;
|
private:
|
||||||
sp<ISurface> getISurface() const;
|
friend class SurfaceComposerClient;
|
||||||
|
friend class SurfaceControl;
|
||||||
|
|
||||||
status_t getBufferLocked(int index, int usage);
|
// can't be copied
|
||||||
|
Surface& operator = (Surface& rhs);
|
||||||
status_t validate() const;
|
Surface(const Surface& rhs);
|
||||||
|
|
||||||
inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
|
Surface(const sp<SurfaceControl>& control);
|
||||||
inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
|
~Surface();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* android_native_window_t hooks
|
||||||
|
*/
|
||||||
static int setSwapInterval(android_native_window_t* window, int interval);
|
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 dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
|
||||||
static int lockBuffer(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 query(int what, int* value);
|
||||||
int perform(int operation, va_list args);
|
int perform(int operation, va_list args);
|
||||||
|
|
||||||
status_t dequeueBuffer(sp<GraphicBuffer>* buffer);
|
|
||||||
|
|
||||||
void dispatch_setUsage(va_list args);
|
void dispatch_setUsage(va_list args);
|
||||||
int dispatch_connect(va_list args);
|
int dispatch_connect(va_list args);
|
||||||
int dispatch_disconnect(va_list args);
|
int dispatch_disconnect(va_list args);
|
||||||
@@ -222,6 +218,20 @@ private:
|
|||||||
int disconnect(int api);
|
int disconnect(int api);
|
||||||
int crop(Rect const* rect);
|
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;
|
uint32_t getUsage() const;
|
||||||
int getConnectedApi() const;
|
int getConnectedApi() const;
|
||||||
|
|
||||||
|
|||||||
@@ -195,6 +195,42 @@ int32_t SharedBufferBase::computeTail() const
|
|||||||
return (mNumBuffers + stack.head - stack.available + 1) % mNumBuffers;
|
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
|
// conditions and updates
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -202,14 +238,14 @@ int32_t SharedBufferBase::computeTail() const
|
|||||||
SharedBufferClient::DequeueCondition::DequeueCondition(
|
SharedBufferClient::DequeueCondition::DequeueCondition(
|
||||||
SharedBufferClient* sbc) : ConditionBase(sbc) {
|
SharedBufferClient* sbc) : ConditionBase(sbc) {
|
||||||
}
|
}
|
||||||
bool SharedBufferClient::DequeueCondition::operator()() {
|
bool SharedBufferClient::DequeueCondition::operator()() const {
|
||||||
return stack.available > 0;
|
return stack.available > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedBufferClient::LockCondition::LockCondition(
|
SharedBufferClient::LockCondition::LockCondition(
|
||||||
SharedBufferClient* sbc, int buf) : ConditionBase(sbc), buf(buf) {
|
SharedBufferClient* sbc, int buf) : ConditionBase(sbc), buf(buf) {
|
||||||
}
|
}
|
||||||
bool SharedBufferClient::LockCondition::operator()() {
|
bool SharedBufferClient::LockCondition::operator()() const {
|
||||||
return (buf != stack.head ||
|
return (buf != stack.head ||
|
||||||
(stack.queued > 0 && stack.inUse != buf));
|
(stack.queued > 0 && stack.inUse != buf));
|
||||||
}
|
}
|
||||||
@@ -217,7 +253,7 @@ bool SharedBufferClient::LockCondition::operator()() {
|
|||||||
SharedBufferServer::ReallocateCondition::ReallocateCondition(
|
SharedBufferServer::ReallocateCondition::ReallocateCondition(
|
||||||
SharedBufferBase* sbb, int buf) : ConditionBase(sbb), buf(buf) {
|
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
|
// TODO: we should also check that buf has been dequeued
|
||||||
return (buf != stack.head);
|
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)
|
int Surface::dequeueBuffer(android_native_buffer_t** buffer)
|
||||||
{
|
{
|
||||||
sp<SurfaceComposerClient> client(getClient());
|
sp<SurfaceComposerClient> client(getClient());
|
||||||
@@ -530,7 +518,7 @@ int Surface::lockBuffer(android_native_buffer_t* buffer)
|
|||||||
if (err != NO_ERROR)
|
if (err != NO_ERROR)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
|
int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
|
||||||
err = mSharedBufferClient->lock(bufIdx);
|
err = mSharedBufferClient->lock(bufIdx);
|
||||||
LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
|
LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
|
||||||
return err;
|
return err;
|
||||||
@@ -547,7 +535,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer)
|
|||||||
mDirtyRegion.set(mSwapRectangle);
|
mDirtyRegion.set(mSwapRectangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
|
int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
|
||||||
mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
|
mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
|
||||||
mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
|
mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
|
||||||
err = mSharedBufferClient->queue(bufIdx);
|
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
|
// we're intending to do software rendering from this point
|
||||||
setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
|
setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
|
||||||
|
|
||||||
sp<GraphicBuffer> backBuffer;
|
android_native_buffer_t* out;
|
||||||
status_t err = dequeueBuffer(&backBuffer);
|
status_t err = dequeueBuffer(&out);
|
||||||
LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
|
LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
|
||||||
if (err == NO_ERROR) {
|
if (err == NO_ERROR) {
|
||||||
|
sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
|
||||||
err = lockBuffer(backBuffer.get());
|
err = lockBuffer(backBuffer.get());
|
||||||
LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
|
LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
|
||||||
backBuffer->getIndex(), strerror(-err));
|
getBufferIndex(backBuffer), strerror(-err));
|
||||||
if (err == NO_ERROR) {
|
if (err == NO_ERROR) {
|
||||||
const Rect bounds(backBuffer->width, backBuffer->height);
|
const Rect bounds(backBuffer->width, backBuffer->height);
|
||||||
const Region boundsRegion(bounds);
|
const Region boundsRegion(bounds);
|
||||||
@@ -797,7 +786,7 @@ status_t Surface::unlockAndPost()
|
|||||||
|
|
||||||
err = queueBuffer(mLockedBuffer.get());
|
err = queueBuffer(mLockedBuffer.get());
|
||||||
LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
|
LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
|
||||||
mLockedBuffer->getIndex(), strerror(-err));
|
getBufferIndex(mLockedBuffer), strerror(-err));
|
||||||
|
|
||||||
mPostedBuffer = mLockedBuffer;
|
mPostedBuffer = mLockedBuffer;
|
||||||
mLockedBuffer = 0;
|
mLockedBuffer = 0;
|
||||||
@@ -809,6 +798,11 @@ void Surface::setSwapRectangle(const Rect& r) {
|
|||||||
mSwapRectangle = r;
|
mSwapRectangle = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
|
||||||
|
{
|
||||||
|
return buffer->getIndex();
|
||||||
|
}
|
||||||
|
|
||||||
status_t Surface::getBufferLocked(int index, int usage)
|
status_t Surface::getBufferLocked(int index, int usage)
|
||||||
{
|
{
|
||||||
sp<ISurface> s(mSurface);
|
sp<ISurface> s(mSurface);
|
||||||
|
|||||||
Reference in New Issue
Block a user