libgui: disallow NULL Fence pointers
This change eliminates the uses of a NULL sp<Fence> indicating that no waiting is required. Instead we use a non-NULL but invalid Fence object for which the wait methods will return immediately. Bug: 7892871 Change-Id: I5360aebe3090422ef6920d56c99fc4eedc642e48
This commit is contained in:
parent
351c294173
commit
1df8c34585
|
@ -62,7 +62,7 @@ status_t BufferItemConsumer::acquireBuffer(BufferItem *item, bool waitForFence)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waitForFence && item->mFence.get()) {
|
if (waitForFence) {
|
||||||
err = item->mFence->waitForever(1000, "BufferItemConsumer::acquireBuffer");
|
err = item->mFence->waitForever(1000, "BufferItemConsumer::acquireBuffer");
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
BI_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
|
BI_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
|
||||||
|
|
|
@ -372,8 +372,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
|
||||||
h = mDefaultHeight;
|
h = mDefaultHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// buffer is now in DEQUEUED (but can also be current at the same time,
|
|
||||||
// if we're in synchronous mode)
|
|
||||||
mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
|
mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
|
||||||
|
|
||||||
const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
|
const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
|
||||||
|
@ -387,7 +385,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
|
||||||
mSlots[buf].mGraphicBuffer = NULL;
|
mSlots[buf].mGraphicBuffer = NULL;
|
||||||
mSlots[buf].mRequestBufferCalled = false;
|
mSlots[buf].mRequestBufferCalled = false;
|
||||||
mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
|
mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
|
||||||
mSlots[buf].mFence.clear();
|
mSlots[buf].mFence = Fence::NO_FENCE;
|
||||||
mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
|
mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
|
||||||
|
|
||||||
returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION;
|
returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION;
|
||||||
|
@ -397,7 +395,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
|
||||||
eglFence = mSlots[buf].mEglFence;
|
eglFence = mSlots[buf].mEglFence;
|
||||||
outFence = mSlots[buf].mFence;
|
outFence = mSlots[buf].mFence;
|
||||||
mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
|
mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
|
||||||
mSlots[buf].mFence.clear();
|
mSlots[buf].mFence = Fence::NO_FENCE;
|
||||||
} // end lock scope
|
} // end lock scope
|
||||||
|
|
||||||
if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
|
if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
|
||||||
|
@ -423,7 +421,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (eglFence != EGL_NO_SYNC_KHR) {
|
if (eglFence != EGL_NO_SYNC_KHR) {
|
||||||
EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
|
EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
|
||||||
// If something goes wrong, log the error, but return the buffer without
|
// If something goes wrong, log the error, but return the buffer without
|
||||||
|
@ -488,6 +485,11 @@ status_t BufferQueue::queueBuffer(int buf,
|
||||||
|
|
||||||
input.deflate(×tamp, &crop, &scalingMode, &transform, &fence);
|
input.deflate(×tamp, &crop, &scalingMode, &transform, &fence);
|
||||||
|
|
||||||
|
if (fence == NULL) {
|
||||||
|
ST_LOGE("queueBuffer: fence is NULL");
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x "
|
ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x "
|
||||||
"scale=%s",
|
"scale=%s",
|
||||||
buf, timestamp, crop.left, crop.top, crop.right, crop.bottom,
|
buf, timestamp, crop.left, crop.top, crop.right, crop.bottom,
|
||||||
|
@ -607,6 +609,9 @@ void BufferQueue::cancelBuffer(int buf, sp<Fence> fence) {
|
||||||
ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
|
ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
|
||||||
buf, mSlots[buf].mBufferState);
|
buf, mSlots[buf].mBufferState);
|
||||||
return;
|
return;
|
||||||
|
} else if (fence == NULL) {
|
||||||
|
ST_LOGE("cancelBuffer: fence is NULL");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
mSlots[buf].mBufferState = BufferSlot::FREE;
|
mSlots[buf].mBufferState = BufferSlot::FREE;
|
||||||
mSlots[buf].mFrameNumber = 0;
|
mSlots[buf].mFrameNumber = 0;
|
||||||
|
@ -785,7 +790,7 @@ void BufferQueue::freeBufferLocked(int slot) {
|
||||||
eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
|
eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
|
||||||
mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
|
mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
|
||||||
}
|
}
|
||||||
mSlots[slot].mFence.clear();
|
mSlots[slot].mFence = Fence::NO_FENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferQueue::freeAllBuffersLocked() {
|
void BufferQueue::freeAllBuffersLocked() {
|
||||||
|
@ -843,7 +848,7 @@ status_t BufferQueue::acquireBuffer(BufferItem *buffer) {
|
||||||
mSlots[buf].mAcquireCalled = true;
|
mSlots[buf].mAcquireCalled = true;
|
||||||
mSlots[buf].mNeedsCleanupOnRelease = false;
|
mSlots[buf].mNeedsCleanupOnRelease = false;
|
||||||
mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
|
mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
|
||||||
mSlots[buf].mFence.clear();
|
mSlots[buf].mFence = Fence::NO_FENCE;
|
||||||
|
|
||||||
mQueue.erase(front);
|
mQueue.erase(front);
|
||||||
mDequeueCondition.broadcast();
|
mDequeueCondition.broadcast();
|
||||||
|
@ -863,8 +868,8 @@ status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
|
||||||
|
|
||||||
Mutex::Autolock _l(mMutex);
|
Mutex::Autolock _l(mMutex);
|
||||||
|
|
||||||
if (buf == INVALID_BUFFER_SLOT) {
|
if (buf == INVALID_BUFFER_SLOT || fence == NULL) {
|
||||||
return -EINVAL;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSlots[buf].mEglDisplay = display;
|
mSlots[buf].mEglDisplay = display;
|
||||||
|
|
|
@ -84,7 +84,7 @@ ConsumerBase::~ConsumerBase() {
|
||||||
void ConsumerBase::freeBufferLocked(int slotIndex) {
|
void ConsumerBase::freeBufferLocked(int slotIndex) {
|
||||||
CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
|
CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
|
||||||
mSlots[slotIndex].mGraphicBuffer = 0;
|
mSlots[slotIndex].mGraphicBuffer = 0;
|
||||||
mSlots[slotIndex].mFence = 0;
|
mSlots[slotIndex].mFence = Fence::NO_FENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used for refactoring, should not be in final interface
|
// Used for refactoring, should not be in final interface
|
||||||
|
@ -228,7 +228,7 @@ status_t ConsumerBase::releaseBufferLocked(int slot, EGLDisplay display,
|
||||||
freeBufferLocked(slot);
|
freeBufferLocked(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
mSlots[slot].mFence.clear();
|
mSlots[slot].mFence = Fence::NO_FENCE;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,7 @@ GLConsumer::GLConsumer(GLuint tex, bool allowSynchronousMode,
|
||||||
GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :
|
GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :
|
||||||
ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue),
|
ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue),
|
||||||
mCurrentTransform(0),
|
mCurrentTransform(0),
|
||||||
|
mCurrentFence(Fence::NO_FENCE),
|
||||||
mCurrentTimestamp(0),
|
mCurrentTimestamp(0),
|
||||||
mFilteringEnabled(true),
|
mFilteringEnabled(true),
|
||||||
mTexName(tex),
|
mTexName(tex),
|
||||||
|
@ -823,7 +824,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const {
|
||||||
return INVALID_OPERATION;
|
return INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCurrentFence != NULL) {
|
if (mCurrentFence->isValid()) {
|
||||||
if (useWaitSync) {
|
if (useWaitSync) {
|
||||||
// Create an EGLSyncKHR from the current fence.
|
// Create an EGLSyncKHR from the current fence.
|
||||||
int fenceFd = mCurrentFence->dup();
|
int fenceFd = mCurrentFence->dup();
|
||||||
|
|
|
@ -94,9 +94,11 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
*buf = reply.readInt32();
|
*buf = reply.readInt32();
|
||||||
fence.clear();
|
bool fenceWasWritten = reply.readInt32();
|
||||||
bool hasFence = reply.readInt32();
|
if (fenceWasWritten) {
|
||||||
if (hasFence) {
|
// If the fence was written by the callee, then overwrite the
|
||||||
|
// caller's fence here. If it wasn't written then don't touch the
|
||||||
|
// caller's fence.
|
||||||
fence = new Fence();
|
fence = new Fence();
|
||||||
reply.read(*fence.get());
|
reply.read(*fence.get());
|
||||||
}
|
}
|
||||||
|
@ -121,13 +123,9 @@ public:
|
||||||
|
|
||||||
virtual void cancelBuffer(int buf, sp<Fence> fence) {
|
virtual void cancelBuffer(int buf, sp<Fence> fence) {
|
||||||
Parcel data, reply;
|
Parcel data, reply;
|
||||||
bool hasFence = fence.get() && fence->isValid();
|
|
||||||
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
|
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
|
||||||
data.writeInt32(buf);
|
data.writeInt32(buf);
|
||||||
data.writeInt32(hasFence);
|
data.write(*fence.get());
|
||||||
if (hasFence) {
|
|
||||||
data.write(*fence.get());
|
|
||||||
}
|
|
||||||
remote()->transact(CANCEL_BUFFER, data, &reply);
|
remote()->transact(CANCEL_BUFFER, data, &reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,10 +216,9 @@ status_t BnGraphicBufferProducer::onTransact(
|
||||||
int buf;
|
int buf;
|
||||||
sp<Fence> fence;
|
sp<Fence> fence;
|
||||||
int result = dequeueBuffer(&buf, fence, w, h, format, usage);
|
int result = dequeueBuffer(&buf, fence, w, h, format, usage);
|
||||||
bool hasFence = fence.get() && fence->isValid();
|
|
||||||
reply->writeInt32(buf);
|
reply->writeInt32(buf);
|
||||||
reply->writeInt32(hasFence);
|
reply->writeInt32(fence != NULL);
|
||||||
if (hasFence) {
|
if (fence != NULL) {
|
||||||
reply->write(*fence.get());
|
reply->write(*fence.get());
|
||||||
}
|
}
|
||||||
reply->writeInt32(result);
|
reply->writeInt32(result);
|
||||||
|
@ -241,12 +238,8 @@ status_t BnGraphicBufferProducer::onTransact(
|
||||||
case CANCEL_BUFFER: {
|
case CANCEL_BUFFER: {
|
||||||
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
|
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
|
||||||
int buf = data.readInt32();
|
int buf = data.readInt32();
|
||||||
sp<Fence> fence;
|
sp<Fence> fence = new Fence();
|
||||||
bool hasFence = data.readInt32();
|
data.read(*fence.get());
|
||||||
if (hasFence) {
|
|
||||||
fence = new Fence();
|
|
||||||
data.read(*fence.get());
|
|
||||||
}
|
|
||||||
cancelBuffer(buf, fence);
|
cancelBuffer(buf, fence);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
} break;
|
} break;
|
||||||
|
@ -289,10 +282,6 @@ status_t BnGraphicBufferProducer::onTransact(
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
static bool isValid(const sp<Fence>& fence) {
|
|
||||||
return fence.get() && fence->isValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
|
IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
|
||||||
parcel.read(*this);
|
parcel.read(*this);
|
||||||
}
|
}
|
||||||
|
@ -303,29 +292,24 @@ size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const
|
||||||
+ sizeof(crop)
|
+ sizeof(crop)
|
||||||
+ sizeof(scalingMode)
|
+ sizeof(scalingMode)
|
||||||
+ sizeof(transform)
|
+ sizeof(transform)
|
||||||
+ sizeof(bool)
|
+ fence->getFlattenedSize();
|
||||||
+ (isValid(fence) ? fence->getFlattenedSize() : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const
|
size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const
|
||||||
{
|
{
|
||||||
return isValid(fence) ? fence->getFdCount() : 0;
|
return fence->getFdCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t IGraphicBufferProducer::QueueBufferInput::flatten(void* buffer, size_t size,
|
status_t IGraphicBufferProducer::QueueBufferInput::flatten(void* buffer, size_t size,
|
||||||
int fds[], size_t count) const
|
int fds[], size_t count) const
|
||||||
{
|
{
|
||||||
status_t err = NO_ERROR;
|
status_t err = NO_ERROR;
|
||||||
bool haveFence = isValid(fence);
|
|
||||||
char* p = (char*)buffer;
|
char* p = (char*)buffer;
|
||||||
memcpy(p, ×tamp, sizeof(timestamp)); p += sizeof(timestamp);
|
memcpy(p, ×tamp, sizeof(timestamp)); p += sizeof(timestamp);
|
||||||
memcpy(p, &crop, sizeof(crop)); p += sizeof(crop);
|
memcpy(p, &crop, sizeof(crop)); p += sizeof(crop);
|
||||||
memcpy(p, &scalingMode, sizeof(scalingMode)); p += sizeof(scalingMode);
|
memcpy(p, &scalingMode, sizeof(scalingMode)); p += sizeof(scalingMode);
|
||||||
memcpy(p, &transform, sizeof(transform)); p += sizeof(transform);
|
memcpy(p, &transform, sizeof(transform)); p += sizeof(transform);
|
||||||
memcpy(p, &haveFence, sizeof(haveFence)); p += sizeof(haveFence);
|
err = fence->flatten(p, size - (p - (char*)buffer), fds, count);
|
||||||
if (haveFence) {
|
|
||||||
err = fence->flatten(p, size - (p - (char*)buffer), fds, count);
|
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,17 +317,13 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(void const* buffer,
|
||||||
size_t size, int fds[], size_t count)
|
size_t size, int fds[], size_t count)
|
||||||
{
|
{
|
||||||
status_t err = NO_ERROR;
|
status_t err = NO_ERROR;
|
||||||
bool haveFence;
|
|
||||||
const char* p = (const char*)buffer;
|
const char* p = (const char*)buffer;
|
||||||
memcpy(×tamp, p, sizeof(timestamp)); p += sizeof(timestamp);
|
memcpy(×tamp, p, sizeof(timestamp)); p += sizeof(timestamp);
|
||||||
memcpy(&crop, p, sizeof(crop)); p += sizeof(crop);
|
memcpy(&crop, p, sizeof(crop)); p += sizeof(crop);
|
||||||
memcpy(&scalingMode, p, sizeof(scalingMode)); p += sizeof(scalingMode);
|
memcpy(&scalingMode, p, sizeof(scalingMode)); p += sizeof(scalingMode);
|
||||||
memcpy(&transform, p, sizeof(transform)); p += sizeof(transform);
|
memcpy(&transform, p, sizeof(transform)); p += sizeof(transform);
|
||||||
memcpy(&haveFence, p, sizeof(haveFence)); p += sizeof(haveFence);
|
fence = new Fence();
|
||||||
if (haveFence) {
|
err = fence->unflatten(p, size - (p - (const char*)buffer), fds, count);
|
||||||
fence = new Fence();
|
|
||||||
err = fence->unflatten(p, size - (p - (const char*)buffer), fds, count);
|
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fence.get()) {
|
if (fence->isValid()) {
|
||||||
*fenceFd = fence->dup();
|
*fenceFd = fence->dup();
|
||||||
if (*fenceFd == -1) {
|
if (*fenceFd == -1) {
|
||||||
ALOGE("dequeueBuffer: error duping fence: %d", errno);
|
ALOGE("dequeueBuffer: error duping fence: %d", errno);
|
||||||
|
@ -241,7 +241,7 @@ int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer,
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : NULL);
|
sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
|
||||||
mSurfaceTexture->cancelBuffer(i, fence);
|
mSurfaceTexture->cancelBuffer(i, fence);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer, int fence
|
||||||
Rect crop;
|
Rect crop;
|
||||||
mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
|
mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
|
||||||
|
|
||||||
sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : NULL);
|
sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
|
||||||
IGraphicBufferProducer::QueueBufferOutput output;
|
IGraphicBufferProducer::QueueBufferOutput output;
|
||||||
IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode,
|
IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode,
|
||||||
mTransform, fence);
|
mTransform, fence);
|
||||||
|
|
|
@ -71,7 +71,7 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
|
||||||
sp<Fence> fence;
|
sp<Fence> fence;
|
||||||
sp<GraphicBuffer> buf;
|
sp<GraphicBuffer> buf;
|
||||||
IGraphicBufferProducer::QueueBufferInput qbi(0, Rect(0, 0, 1, 1),
|
IGraphicBufferProducer::QueueBufferInput qbi(0, Rect(0, 0, 1, 1),
|
||||||
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, fence);
|
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
|
||||||
BufferQueue::BufferItem item;
|
BufferQueue::BufferItem item;
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
|
|
|
@ -202,7 +202,6 @@ protected:
|
||||||
while ((err = glGetError()) != GL_NO_ERROR) {
|
while ((err = glGetError()) != GL_NO_ERROR) {
|
||||||
msg += String8::format(", %#x", err);
|
msg += String8::format(", %#x", err);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "pixel check failure: %s\n", msg.string());
|
|
||||||
return ::testing::AssertionFailure(
|
return ::testing::AssertionFailure(
|
||||||
::testing::Message(msg.string()));
|
::testing::Message(msg.string()));
|
||||||
}
|
}
|
||||||
|
@ -228,7 +227,6 @@ protected:
|
||||||
msg += String8::format("a(%d isn't %d)", pixel[3], a);
|
msg += String8::format("a(%d isn't %d)", pixel[3], a);
|
||||||
}
|
}
|
||||||
if (!msg.isEmpty()) {
|
if (!msg.isEmpty()) {
|
||||||
fprintf(stderr, "pixel check failure: %s\n", msg.string());
|
|
||||||
return ::testing::AssertionFailure(
|
return ::testing::AssertionFailure(
|
||||||
::testing::Message(msg.string()));
|
::testing::Message(msg.string()));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
const sp<Fence> Fence::NO_FENCE = sp<Fence>();
|
const sp<Fence> Fence::NO_FENCE = sp<Fence>(new Fence);
|
||||||
|
|
||||||
Fence::Fence() :
|
Fence::Fence() :
|
||||||
mFenceFd(-1) {
|
mFenceFd(-1) {
|
||||||
|
@ -71,7 +71,19 @@ status_t Fence::waitForever(unsigned int warningTimeout, const char* logname) {
|
||||||
sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
|
sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
|
||||||
const sp<Fence>& f2) {
|
const sp<Fence>& f2) {
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
int result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd);
|
int result;
|
||||||
|
// Merge the two fences. In the case where one of the fences is not a
|
||||||
|
// valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so
|
||||||
|
// that a new fence with the given name is created.
|
||||||
|
if (f1->isValid() && f2->isValid()) {
|
||||||
|
result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd);
|
||||||
|
} else if (f1->isValid()) {
|
||||||
|
result = sync_merge(name.string(), f1->mFenceFd, f1->mFenceFd);
|
||||||
|
} else if (f2->isValid()) {
|
||||||
|
result = sync_merge(name.string(), f2->mFenceFd, f2->mFenceFd);
|
||||||
|
} else {
|
||||||
|
return NO_FENCE;
|
||||||
|
}
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
status_t err = -errno;
|
status_t err = -errno;
|
||||||
ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
|
ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
|
||||||
|
@ -83,9 +95,6 @@ sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
|
||||||
}
|
}
|
||||||
|
|
||||||
int Fence::dup() const {
|
int Fence::dup() const {
|
||||||
if (mFenceFd == -1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return ::dup(mFenceFd);
|
return ::dup(mFenceFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,22 +130,24 @@ size_t Fence::getFlattenedSize() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Fence::getFdCount() const {
|
size_t Fence::getFdCount() const {
|
||||||
return 1;
|
return isValid() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t Fence::flatten(void* buffer, size_t size, int fds[],
|
status_t Fence::flatten(void* buffer, size_t size, int fds[],
|
||||||
size_t count) const {
|
size_t count) const {
|
||||||
if (size != 0 || count != 1) {
|
if (size != getFlattenedSize() || count != getFdCount()) {
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fds[0] = mFenceFd;
|
if (isValid()) {
|
||||||
|
fds[0] = mFenceFd;
|
||||||
|
}
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t Fence::unflatten(void const* buffer, size_t size, int fds[],
|
status_t Fence::unflatten(void const* buffer, size_t size, int fds[],
|
||||||
size_t count) {
|
size_t count) {
|
||||||
if (size != 0 || count != 1) {
|
if (size != 0 || (count != 0 && count != 1)) {
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
if (mFenceFd != -1) {
|
if (mFenceFd != -1) {
|
||||||
|
@ -144,7 +155,10 @@ status_t Fence::unflatten(void const* buffer, size_t size, int fds[],
|
||||||
return INVALID_OPERATION;
|
return INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
mFenceFd = fds[0];
|
if (count == 1) {
|
||||||
|
mFenceFd = fds[0];
|
||||||
|
}
|
||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -539,7 +539,7 @@ status_t HWComposer::setFramebufferTarget(int32_t id,
|
||||||
}
|
}
|
||||||
|
|
||||||
int acquireFenceFd = -1;
|
int acquireFenceFd = -1;
|
||||||
if (acquireFence != NULL) {
|
if (acquireFence->isValid()) {
|
||||||
acquireFenceFd = acquireFence->dup();
|
acquireFenceFd = acquireFence->dup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,7 +659,7 @@ status_t HWComposer::commit() {
|
||||||
for (size_t i=0 ; i<mNumDisplays ; i++) {
|
for (size_t i=0 ; i<mNumDisplays ; i++) {
|
||||||
DisplayData& disp(mDisplayData[i]);
|
DisplayData& disp(mDisplayData[i]);
|
||||||
disp.lastDisplayFence = disp.lastRetireFence;
|
disp.lastDisplayFence = disp.lastRetireFence;
|
||||||
disp.lastRetireFence = NULL;
|
disp.lastRetireFence = Fence::NO_FENCE;
|
||||||
if (disp.list) {
|
if (disp.list) {
|
||||||
if (disp.list->retireFenceFd != -1) {
|
if (disp.list->retireFenceFd != -1) {
|
||||||
disp.lastRetireFence = new Fence(disp.list->retireFenceFd);
|
disp.lastRetireFence = new Fence(disp.list->retireFenceFd);
|
||||||
|
@ -725,9 +725,7 @@ int HWComposer::fbPost(int32_t id,
|
||||||
if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
|
if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
|
||||||
return setFramebufferTarget(id, acquireFence, buffer);
|
return setFramebufferTarget(id, acquireFence, buffer);
|
||||||
} else {
|
} else {
|
||||||
if (acquireFence != NULL) {
|
acquireFence->waitForever(1000, "HWComposer::fbPost");
|
||||||
acquireFence->waitForever(1000, "HWComposer::fbPost");
|
|
||||||
}
|
|
||||||
return mFbDev->post(mFbDev, buffer->handle);
|
return mFbDev->post(mFbDev, buffer->handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
|
||||||
|
|
||||||
if (layer.getCompositionType() == HWC_OVERLAY) {
|
if (layer.getCompositionType() == HWC_OVERLAY) {
|
||||||
sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
|
sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
|
||||||
if (fence.get()) {
|
if (fence->isValid()) {
|
||||||
fenceFd = fence->dup();
|
fenceFd = fence->dup();
|
||||||
if (fenceFd == -1) {
|
if (fenceFd == -1) {
|
||||||
ALOGW("failed to dup layer fence, skipping sync: %d", errno);
|
ALOGW("failed to dup layer fence, skipping sync: %d", errno);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
|
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
|
||||||
|
//#define LOG_NDEBUG 0
|
||||||
|
|
||||||
#include "SurfaceFlingerConsumer.h"
|
#include "SurfaceFlingerConsumer.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue