Merge changes I50831d4e,I5360aebe

* changes:
  flatland: remove an unneeded #include
  libgui: disallow NULL Fence pointers
This commit is contained in:
Jamie Gennis 2013-02-13 23:22:04 +00:00 committed by Android (Google) Code Review
commit b997f6ef0f
13 changed files with 67 additions and 72 deletions

View File

@ -14,8 +14,6 @@
* limitations under the License.
*/
#include <ui/Fence.h>
#include <ui/DisplayInfo.h>
#include <gui/SurfaceComposerClient.h>

View File

@ -62,7 +62,7 @@ status_t BufferItemConsumer::acquireBuffer(BufferItem *item, bool waitForFence)
return err;
}
if (waitForFence && item->mFence.get()) {
if (waitForFence) {
err = item->mFence->waitForever(1000, "BufferItemConsumer::acquireBuffer");
if (err != OK) {
BI_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",

View File

@ -372,8 +372,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
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;
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].mRequestBufferCalled = false;
mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
mSlots[buf].mFence.clear();
mSlots[buf].mFence = Fence::NO_FENCE;
mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION;
@ -397,7 +395,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
eglFence = mSlots[buf].mEglFence;
outFence = mSlots[buf].mFence;
mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
mSlots[buf].mFence.clear();
mSlots[buf].mFence = Fence::NO_FENCE;
} // end lock scope
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) {
EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
// If something goes wrong, log the error, but return the buffer without
@ -488,6 +485,11 @@ status_t BufferQueue::queueBuffer(int buf,
input.deflate(&timestamp, &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 "
"scale=%s",
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)",
buf, mSlots[buf].mBufferState);
return;
} else if (fence == NULL) {
ST_LOGE("cancelBuffer: fence is NULL");
return;
}
mSlots[buf].mBufferState = BufferSlot::FREE;
mSlots[buf].mFrameNumber = 0;
@ -785,7 +790,7 @@ void BufferQueue::freeBufferLocked(int slot) {
eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
}
mSlots[slot].mFence.clear();
mSlots[slot].mFence = Fence::NO_FENCE;
}
void BufferQueue::freeAllBuffersLocked() {
@ -843,7 +848,7 @@ status_t BufferQueue::acquireBuffer(BufferItem *buffer) {
mSlots[buf].mAcquireCalled = true;
mSlots[buf].mNeedsCleanupOnRelease = false;
mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
mSlots[buf].mFence.clear();
mSlots[buf].mFence = Fence::NO_FENCE;
mQueue.erase(front);
mDequeueCondition.broadcast();
@ -863,8 +868,8 @@ status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
Mutex::Autolock _l(mMutex);
if (buf == INVALID_BUFFER_SLOT) {
return -EINVAL;
if (buf == INVALID_BUFFER_SLOT || fence == NULL) {
return BAD_VALUE;
}
mSlots[buf].mEglDisplay = display;

View File

@ -84,7 +84,7 @@ ConsumerBase::~ConsumerBase() {
void ConsumerBase::freeBufferLocked(int slotIndex) {
CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
mSlots[slotIndex].mGraphicBuffer = 0;
mSlots[slotIndex].mFence = 0;
mSlots[slotIndex].mFence = Fence::NO_FENCE;
}
// Used for refactoring, should not be in final interface
@ -228,7 +228,7 @@ status_t ConsumerBase::releaseBufferLocked(int slot, EGLDisplay display,
freeBufferLocked(slot);
}
mSlots[slot].mFence.clear();
mSlots[slot].mFence = Fence::NO_FENCE;
return err;
}

View File

@ -117,6 +117,7 @@ GLConsumer::GLConsumer(GLuint tex, bool allowSynchronousMode,
GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :
ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue),
mCurrentTransform(0),
mCurrentFence(Fence::NO_FENCE),
mCurrentTimestamp(0),
mFilteringEnabled(true),
mTexName(tex),
@ -823,7 +824,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const {
return INVALID_OPERATION;
}
if (mCurrentFence != NULL) {
if (mCurrentFence->isValid()) {
if (useWaitSync) {
// Create an EGLSyncKHR from the current fence.
int fenceFd = mCurrentFence->dup();

View File

@ -94,9 +94,11 @@ public:
return result;
}
*buf = reply.readInt32();
fence.clear();
bool hasFence = reply.readInt32();
if (hasFence) {
bool fenceWasWritten = reply.readInt32();
if (fenceWasWritten) {
// 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();
reply.read(*fence.get());
}
@ -121,13 +123,9 @@ public:
virtual void cancelBuffer(int buf, sp<Fence> fence) {
Parcel data, reply;
bool hasFence = fence.get() && fence->isValid();
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
data.writeInt32(buf);
data.writeInt32(hasFence);
if (hasFence) {
data.write(*fence.get());
}
data.write(*fence.get());
remote()->transact(CANCEL_BUFFER, data, &reply);
}
@ -218,10 +216,9 @@ status_t BnGraphicBufferProducer::onTransact(
int buf;
sp<Fence> fence;
int result = dequeueBuffer(&buf, fence, w, h, format, usage);
bool hasFence = fence.get() && fence->isValid();
reply->writeInt32(buf);
reply->writeInt32(hasFence);
if (hasFence) {
reply->writeInt32(fence != NULL);
if (fence != NULL) {
reply->write(*fence.get());
}
reply->writeInt32(result);
@ -241,12 +238,8 @@ status_t BnGraphicBufferProducer::onTransact(
case CANCEL_BUFFER: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
int buf = data.readInt32();
sp<Fence> fence;
bool hasFence = data.readInt32();
if (hasFence) {
fence = new Fence();
data.read(*fence.get());
}
sp<Fence> fence = new Fence();
data.read(*fence.get());
cancelBuffer(buf, fence);
return NO_ERROR;
} 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) {
parcel.read(*this);
}
@ -303,29 +292,24 @@ size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const
+ sizeof(crop)
+ sizeof(scalingMode)
+ sizeof(transform)
+ sizeof(bool)
+ (isValid(fence) ? fence->getFlattenedSize() : 0);
+ fence->getFlattenedSize();
}
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,
int fds[], size_t count) const
{
status_t err = NO_ERROR;
bool haveFence = isValid(fence);
char* p = (char*)buffer;
memcpy(p, &timestamp, sizeof(timestamp)); p += sizeof(timestamp);
memcpy(p, &crop, sizeof(crop)); p += sizeof(crop);
memcpy(p, &scalingMode, sizeof(scalingMode)); p += sizeof(scalingMode);
memcpy(p, &transform, sizeof(transform)); p += sizeof(transform);
memcpy(p, &haveFence, sizeof(haveFence)); p += sizeof(haveFence);
if (haveFence) {
err = fence->flatten(p, size - (p - (char*)buffer), fds, count);
}
err = fence->flatten(p, size - (p - (char*)buffer), fds, count);
return err;
}
@ -333,17 +317,13 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(void const* buffer,
size_t size, int fds[], size_t count)
{
status_t err = NO_ERROR;
bool haveFence;
const char* p = (const char*)buffer;
memcpy(&timestamp, p, sizeof(timestamp)); p += sizeof(timestamp);
memcpy(&crop, p, sizeof(crop)); p += sizeof(crop);
memcpy(&scalingMode, p, sizeof(scalingMode)); p += sizeof(scalingMode);
memcpy(&transform, p, sizeof(transform)); p += sizeof(transform);
memcpy(&haveFence, p, sizeof(haveFence)); p += sizeof(haveFence);
if (haveFence) {
fence = new Fence();
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;
}

View File

@ -216,7 +216,7 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer,
}
}
if (fence.get()) {
if (fence->isValid()) {
*fenceFd = fence->dup();
if (*fenceFd == -1) {
ALOGE("dequeueBuffer: error duping fence: %d", errno);
@ -241,7 +241,7 @@ int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer,
if (i < 0) {
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);
return OK;
}
@ -287,7 +287,7 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer, int fence
Rect 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::QueueBufferInput input(timestamp, crop, mScalingMode,
mTransform, fence);

View File

@ -71,7 +71,7 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
sp<Fence> fence;
sp<GraphicBuffer> buf;
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;
for (int i = 0; i < 2; i++) {

View File

@ -202,7 +202,6 @@ protected:
while ((err = glGetError()) != GL_NO_ERROR) {
msg += String8::format(", %#x", err);
}
fprintf(stderr, "pixel check failure: %s\n", msg.string());
return ::testing::AssertionFailure(
::testing::Message(msg.string()));
}
@ -228,7 +227,6 @@ protected:
msg += String8::format("a(%d isn't %d)", pixel[3], a);
}
if (!msg.isEmpty()) {
fprintf(stderr, "pixel check failure: %s\n", msg.string());
return ::testing::AssertionFailure(
::testing::Message(msg.string()));
} else {

View File

@ -29,7 +29,7 @@
namespace android {
const sp<Fence> Fence::NO_FENCE = sp<Fence>();
const sp<Fence> Fence::NO_FENCE = sp<Fence>(new Fence);
Fence::Fence() :
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,
const sp<Fence>& f2) {
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) {
status_t err = -errno;
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 {
if (mFenceFd == -1) {
return -1;
}
return ::dup(mFenceFd);
}
@ -121,22 +130,24 @@ size_t Fence::getFlattenedSize() const {
}
size_t Fence::getFdCount() const {
return 1;
return isValid() ? 1 : 0;
}
status_t Fence::flatten(void* buffer, size_t size, int fds[],
size_t count) const {
if (size != 0 || count != 1) {
if (size != getFlattenedSize() || count != getFdCount()) {
return BAD_VALUE;
}
fds[0] = mFenceFd;
if (isValid()) {
fds[0] = mFenceFd;
}
return NO_ERROR;
}
status_t Fence::unflatten(void const* buffer, size_t size, int fds[],
size_t count) {
if (size != 0 || count != 1) {
if (size != 0 || (count != 0 && count != 1)) {
return BAD_VALUE;
}
if (mFenceFd != -1) {
@ -144,7 +155,10 @@ status_t Fence::unflatten(void const* buffer, size_t size, int fds[],
return INVALID_OPERATION;
}
mFenceFd = fds[0];
if (count == 1) {
mFenceFd = fds[0];
}
return NO_ERROR;
}

View File

@ -539,7 +539,7 @@ status_t HWComposer::setFramebufferTarget(int32_t id,
}
int acquireFenceFd = -1;
if (acquireFence != NULL) {
if (acquireFence->isValid()) {
acquireFenceFd = acquireFence->dup();
}
@ -659,7 +659,7 @@ status_t HWComposer::commit() {
for (size_t i=0 ; i<mNumDisplays ; i++) {
DisplayData& disp(mDisplayData[i]);
disp.lastDisplayFence = disp.lastRetireFence;
disp.lastRetireFence = NULL;
disp.lastRetireFence = Fence::NO_FENCE;
if (disp.list) {
if (disp.list->retireFenceFd != -1) {
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)) {
return setFramebufferTarget(id, acquireFence, buffer);
} else {
if (acquireFence != NULL) {
acquireFence->waitForever(1000, "HWComposer::fbPost");
}
acquireFence->waitForever(1000, "HWComposer::fbPost");
return mFbDev->post(mFbDev, buffer->handle);
}
}

View File

@ -298,7 +298,7 @@ void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
if (layer.getCompositionType() == HWC_OVERLAY) {
sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
if (fence.get()) {
if (fence->isValid()) {
fenceFd = fence->dup();
if (fenceFd == -1) {
ALOGW("failed to dup layer fence, skipping sync: %d", errno);

View File

@ -15,6 +15,7 @@
*/
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
#include "SurfaceFlingerConsumer.h"