Merge "Pass fences from BufferQueue to SurfaceTextureClient"

This commit is contained in:
Jesse Hall 2012-06-22 19:58:47 -07:00 committed by Android (Google) Code Review
commit b7c839b110
5 changed files with 45 additions and 23 deletions

View File

@ -116,12 +116,18 @@ public:
// pointed to by the buf argument and a status of OK is returned. If no
// slot is available then a status of -EBUSY is returned and buf is
// unmodified.
//
// The fence parameter will be updated to hold the fence associated with
// the buffer. The contents of the buffer must not be overwritten until the
// fence signals. If the fence is NULL, the buffer may be written
// immediately.
//
// The width and height parameters must be no greater than the minimum of
// GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).
// An error due to invalid dimensions might not be reported until
// updateTexImage() is called.
virtual status_t dequeueBuffer(int *buf, uint32_t width, uint32_t height,
uint32_t format, uint32_t usage);
virtual status_t dequeueBuffer(int *buf, sp<Fence>& fence,
uint32_t width, uint32_t height, uint32_t format, uint32_t usage);
// queueBuffer returns a filled buffer to the BufferQueue. In addition, a
// timestamp must be provided for the buffer. The timestamp is in
@ -220,7 +226,7 @@ public:
// Note that the dependencies on EGL will be removed once we switch to using
// the Android HW Sync HAL.
status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence,
const sp<Fence>& releaseFence = Fence::NO_FENCE);
const sp<Fence>& releaseFence);
// consumerConnect connects a consumer to the BufferQueue. Only one
// consumer may be connected, and when that consumer disconnects the

View File

@ -25,6 +25,7 @@
#include <binder/IInterface.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>
@ -67,8 +68,13 @@ protected:
// in the contents of its associated buffer contents and call queueBuffer.
// If dequeueBuffer return BUFFER_NEEDS_REALLOCATION, the client is
// expected to call requestBuffer immediately.
virtual status_t dequeueBuffer(int *slot, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) = 0;
//
// The fence parameter will be updated to hold the fence associated with
// the buffer. The contents of the buffer must not be overwritten until the
// fence signals. If the fence is NULL, the buffer may be written
// immediately.
virtual status_t dequeueBuffer(int *slot, sp<Fence>& fence,
uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0;
// queueBuffer indicates that the client has finished filling in the
// contents of the buffer associated with slot and transfers ownership of

View File

@ -294,8 +294,8 @@ status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
return NO_ERROR;
}
status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) {
status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
ATRACE_CALL();
ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
@ -307,7 +307,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
status_t returnFlags(OK);
EGLDisplay dpy = EGL_NO_DISPLAY;
EGLSyncKHR fence = EGL_NO_SYNC_KHR;
sp<Fence> releaseFence;
{ // Scope for the lock
Mutex::Autolock lock(mMutex);
@ -490,7 +489,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
dpy = mSlots[buf].mEglDisplay;
fence = mSlots[buf].mFence;
releaseFence = mSlots[buf].mReleaseFence;
outFence = mSlots[buf].mReleaseFence;
mSlots[buf].mFence = EGL_NO_SYNC_KHR;
mSlots[buf].mReleaseFence.clear();
} // end lock scope
@ -508,16 +507,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
eglDestroySyncKHR(dpy, fence);
}
if (releaseFence.get()) {
int err = releaseFence->wait(1000);
if (err == -ETIME) {
ALOGE("dequeueBuffer: timeout waiting for release fence");
} else if (err != NO_ERROR) {
ALOGE("dequeueBuffer: error waiting for sync fence: %d", err);
}
releaseFence.clear();
}
ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);

View File

@ -81,8 +81,8 @@ public:
return result;
}
virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) {
virtual status_t dequeueBuffer(int *buf, sp<Fence>& fence,
uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(w);
@ -94,6 +94,12 @@ public:
return result;
}
*buf = reply.readInt32();
fence.clear();
bool hasFence = reply.readInt32();
if (hasFence) {
fence = new Fence();
reply.read(*fence.get());
}
result = reply.readInt32();
return result;
}
@ -205,8 +211,13 @@ status_t BnSurfaceTexture::onTransact(
uint32_t format = data.readInt32();
uint32_t usage = data.readInt32();
int buf;
int result = dequeueBuffer(&buf, w, h, format, usage);
sp<Fence> fence;
int result = dequeueBuffer(&buf, fence, w, h, format, usage);
reply->writeInt32(buf);
reply->writeInt32(fence.get() != NULL);
if (fence.get() != NULL) {
reply->write(*fence.get());
}
reply->writeInt32(result);
return NO_ERROR;
} break;

View File

@ -198,7 +198,8 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer,
int buf = -1;
int reqW = mReqWidth ? mReqWidth : mUserWidth;
int reqH = mReqHeight ? mReqHeight : mUserHeight;
status_t result = mSurfaceTexture->dequeueBuffer(&buf, reqW, reqH,
sp<Fence> fence;
status_t result = mSurfaceTexture->dequeueBuffer(&buf, fence, reqW, reqH,
mReqFormat, mReqUsage);
if (result < 0) {
ALOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
@ -219,6 +220,15 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer,
return result;
}
}
if (fence.get()) {
status_t err = fence->wait(Fence::TIMEOUT_NEVER);
if (err != OK) {
ALOGE("dequeueBuffer: error waiting for fence: %d", err);
}
fence.clear();
}
*buffer = gbuf.get();
*fenceFd = -1;
return OK;