ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
if (err == NO_ERROR) {
sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
- err = lockBuffer(backBuffer.get());
- ALOGE_IF(err, "lockBuffer (handle=%p) failed (%s)",
- backBuffer->handle, strerror(-err));
- if (err == NO_ERROR) {
- const Rect bounds(backBuffer->width, backBuffer->height);
-
- Region newDirtyRegion;
- if (inOutDirtyBounds) {
- newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
- newDirtyRegion.andSelf(bounds);
- } else {
- newDirtyRegion.set(bounds);
- }
+ sp<Fence> fence(new Fence(fenceFd));
- // figure out if we can copy the frontbuffer back
- const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
- const bool canCopyBack = (frontBuffer != 0 &&
- backBuffer->width == frontBuffer->width &&
- backBuffer->height == frontBuffer->height &&
- backBuffer->format == frontBuffer->format);
-
- if (canCopyBack) {
- // copy the area that is invalid and not repainted this round
- const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
- if (!copyback.isEmpty())
- copyBlt(backBuffer, frontBuffer, copyback);
- } else {
- // if we can't copy-back anything, modify the user's dirty
- // region to make sure they redraw the whole buffer
- newDirtyRegion.set(bounds);
- mDirtyRegion.clear();
- Mutex::Autolock lock(mMutex);
- for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
- mSlots[i].dirtyRegion.clear();
- }
- }
+ err = fence->wait(Fence::TIMEOUT_NEVER);
+ if (err != OK) {
+ ALOGE("Fence::wait failed (%s)", strerror(-err));
+ cancelBuffer(out, fenceFd);
+ return err;
+ }
+ const Rect bounds(backBuffer->width, backBuffer->height);
- { // scope for the lock
- Mutex::Autolock lock(mMutex);
- int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
- if (backBufferSlot >= 0) {
- Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
- mDirtyRegion.subtract(dirtyRegion);
- dirtyRegion = newDirtyRegion;
- }
- }
+ Region newDirtyRegion;
+ if (inOutDirtyBounds) {
+ newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
+ newDirtyRegion.andSelf(bounds);
+ } else {
+ newDirtyRegion.set(bounds);
+ }
- mDirtyRegion.orSelf(newDirtyRegion);
- if (inOutDirtyBounds) {
- *inOutDirtyBounds = newDirtyRegion.getBounds();
+ // figure out if we can copy the frontbuffer back
+ const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
+ const bool canCopyBack = (frontBuffer != 0 &&
+ backBuffer->width == frontBuffer->width &&
+ backBuffer->height == frontBuffer->height &&
+ backBuffer->format == frontBuffer->format);
+
+ if (canCopyBack) {
+ // copy the area that is invalid and not repainted this round
+ const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
+ if (!copyback.isEmpty())
+ copyBlt(backBuffer, frontBuffer, copyback);
+ } else {
+ // if we can't copy-back anything, modify the user's dirty
+ // region to make sure they redraw the whole buffer
+ newDirtyRegion.set(bounds);
+ mDirtyRegion.clear();
+ Mutex::Autolock lock(mMutex);
+ for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
+ mSlots[i].dirtyRegion.clear();
}
+ }
+
- void* vaddr;
- status_t res = backBuffer->lock(
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- newDirtyRegion.bounds(), &vaddr);
-
- ALOGW_IF(res, "failed locking buffer (handle = %p)",
- backBuffer->handle);
-
- if (res != 0) {
- err = INVALID_OPERATION;
- } else {
- mLockedBuffer = backBuffer;
- outBuffer->width = backBuffer->width;
- outBuffer->height = backBuffer->height;
- outBuffer->stride = backBuffer->stride;
- outBuffer->format = backBuffer->format;
- outBuffer->bits = vaddr;
+ { // scope for the lock
+ Mutex::Autolock lock(mMutex);
+ int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
+ if (backBufferSlot >= 0) {
+ Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
+ mDirtyRegion.subtract(dirtyRegion);
+ dirtyRegion = newDirtyRegion;
}
}
- mLockedBuffer = backBuffer;
- outBuffer->width = backBuffer->width;
- outBuffer->height = backBuffer->height;
- outBuffer->stride = backBuffer->stride;
- outBuffer->format = backBuffer->format;
- outBuffer->bits = vaddr;
+
+ mDirtyRegion.orSelf(newDirtyRegion);
+ if (inOutDirtyBounds) {
+ *inOutDirtyBounds = newDirtyRegion.getBounds();
+ }
+
+ void* vaddr;
+ status_t res = backBuffer->lock(
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ newDirtyRegion.bounds(), &vaddr);
+
+ ALOGW_IF(res, "failed locking buffer (handle = %p)",
+ backBuffer->handle);
+
++ if (res != 0) {
++ err = INVALID_OPERATION;
++ } else {
++ mLockedBuffer = backBuffer;
++ outBuffer->width = backBuffer->width;
++ outBuffer->height = backBuffer->height;
++ outBuffer->stride = backBuffer->stride;
++ outBuffer->format = backBuffer->format;
++ outBuffer->bits = vaddr;
++ }
}
return err;
}