From 7cdd786fa80cf03551291ae8feca7b77583be1c5 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 18 Jul 2013 22:10:56 -0700 Subject: [PATCH] Make ANW.setSwapInterval(0) work again we can now queue/dequeue a buffer in asynchrnous mode by using the async parameter to these calls. async mode is only specified with those calls (it is not modal anymore). as a consequence it can only be specified when the buffer count is not overidden, as error is returned otherwise. Change-Id: Ic63f4f96f671cb9d65c4cecbcc192615e09a8b6b --- include/gui/BufferQueue.h | 24 ++--- include/gui/IGraphicBufferProducer.h | 17 +++- include/gui/Surface.h | 4 + libs/gui/BufferQueue.cpp | 91 ++++++++++++------- libs/gui/IGraphicBufferProducer.cpp | 9 +- libs/gui/Surface.cpp | 12 +-- libs/gui/tests/BufferQueue_test.cpp | 6 +- libs/gui/tests/SurfaceTextureClient_test.cpp | 6 -- .../DisplayHardware/VirtualDisplaySurface.cpp | 15 +-- .../DisplayHardware/VirtualDisplaySurface.h | 4 +- 10 files changed, 113 insertions(+), 75 deletions(-) diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h index b968287ca..628678f60 100644 --- a/include/gui/BufferQueue.h +++ b/include/gui/BufferQueue.h @@ -167,7 +167,7 @@ public: // // In both cases, the producer will need to call requestBuffer to get a // GraphicBuffer handle for the returned slot. - virtual status_t dequeueBuffer(int *buf, sp* fence, + virtual status_t dequeueBuffer(int *buf, sp* fence, bool async, uint32_t width, uint32_t height, uint32_t format, uint32_t usage); // queueBuffer returns a filled buffer to the BufferQueue. @@ -229,7 +229,7 @@ public: mTimestamp(0), mFrameNumber(0), mBuf(INVALID_BUFFER_SLOT), - mDequeueBufferCannotBlock(false), + mIsDroppable(false), mAcquireCalled(false) { mCrop.makeInvalid(); } @@ -260,12 +260,12 @@ public: // mFence is a fence that will signal when the buffer is idle. sp mFence; - // mDequeueBufferCannotBlock whether this buffer was queued with the + // mIsDroppable whether this buffer was queued with the // property that it can be replaced by a new buffer for the purpose of // making sure dequeueBuffer() won't block. // i.e.: was the BufferQueue in "mDequeueBufferCannotBlock" when this buffer // was queued. - bool mDequeueBufferCannotBlock; + bool mIsDroppable; // Indicates whether this buffer has been seen by a consumer yet bool mAcquireCalled; @@ -379,9 +379,15 @@ private: // The initial default is 2. status_t setDefaultMaxBufferCountLocked(int count); + // getMinUndequeuedBufferCount returns the minimum number of buffers + // that must remain in a state other than DEQUEUED. + // The async parameter tells whether we're in asynchronous mode. + int getMinUndequeuedBufferCount(bool async) const; + // getMinBufferCountLocked returns the minimum number of buffers allowed // given the current BufferQueue state. - int getMinMaxBufferCountLocked() const; + // The async parameter tells whether we're in asynchronous mode. + int getMinMaxBufferCountLocked(bool async) const; // getMaxBufferCountLocked returns the maximum number of buffers that can // be allocated at once. This value depends upon the following member @@ -391,10 +397,11 @@ private: // mMaxAcquiredBufferCount // mDefaultMaxBufferCount // mOverrideMaxBufferCount + // async parameter // // Any time one of these member variables is changed while a producer is // connected, mDequeueCondition must be broadcast. - int getMaxBufferCountLocked() const; + int getMaxBufferCountLocked(bool async) const; // stillTracking returns true iff the buffer item is still being tracked // in one of the slots. @@ -516,11 +523,6 @@ private: // in dequeueBuffer() if a width and height of zero is specified. uint32_t mDefaultHeight; - // mMinUndequeuedBufferCount holds the minimum number of buffers - // that must remain in a state other than DEQUEUED. - // This value cannot change while connected. - int mMinUndequeuedBufferCount; - // mMaxAcquiredBufferCount is the number of buffers that the consumer may // acquire at one time. It defaults to 1 and can be changed by the // consumer via the setMaxAcquiredBufferCount method, but this may only be diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h index af5fcfc79..9677962a5 100644 --- a/include/gui/IGraphicBufferProducer.h +++ b/include/gui/IGraphicBufferProducer.h @@ -84,7 +84,10 @@ public: // 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, + // + // The async parameter sets whether we're in asynchrnous mode for this + // deququeBuffer() call. + virtual status_t dequeueBuffer(int *slot, sp* fence, bool async, uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0; // queueBuffer indicates that the client has finished filling in the @@ -96,6 +99,8 @@ public: // must be monotonically increasing. Its other properties (zero point, etc) // are client-dependent, and should be documented by the client. // + // The async parameter sets whether we're queuing a buffer in asynchronous mode. + // // outWidth, outHeight and outTransform are filled with the default width // and height of the window and current transform applied to buffers, // respectively. @@ -103,17 +108,18 @@ public: struct QueueBufferInput : public Flattenable { inline QueueBufferInput(const Parcel& parcel); inline QueueBufferInput(int64_t timestamp, - const Rect& crop, int scalingMode, uint32_t transform, - sp fence) + const Rect& crop, int scalingMode, uint32_t transform, bool async, + const sp& fence) : timestamp(timestamp), crop(crop), scalingMode(scalingMode), - transform(transform), fence(fence) { } + transform(transform), async(async), fence(fence) { } inline void deflate(int64_t* outTimestamp, Rect* outCrop, - int* outScalingMode, uint32_t* outTransform, + int* outScalingMode, uint32_t* outTransform, bool* outAsync, sp* outFence) const { *outTimestamp = timestamp; *outCrop = crop; *outScalingMode = scalingMode; *outTransform = transform; + *outAsync = bool(async); *outFence = fence; } @@ -130,6 +136,7 @@ public: Rect crop; int scalingMode; uint32_t transform; + int async; sp fence; }; diff --git a/include/gui/Surface.h b/include/gui/Surface.h index 6f12e7711..2f7406e2b 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -235,6 +235,10 @@ private: // by the application bool mProducerControlledByApp; + // mSwapIntervalZero set if we should drop buffers at queue() time to + // achieve an asynchronous swap interval + bool mSwapIntervalZero; + // mConsumerRunningBehind whether the consumer is running more than // one buffer behind the producer. mutable bool mConsumerRunningBehind; diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index f99bd29bd..cf8143135 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -30,6 +30,7 @@ #include #include +#include // Macros for including the BufferQueue name in log messages #define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) @@ -150,21 +151,21 @@ status_t BufferQueue::setBufferCount(int bufferCount) { } // Error out if the user has dequeued buffers - int maxBufferCount = getMaxBufferCountLocked(); - for (int i=0 ; i= 2); @@ -229,15 +230,11 @@ status_t BufferQueue::requestBuffer(int slot, sp* buf) { ST_LOGE("requestBuffer: BufferQueue has been abandoned!"); return NO_INIT; } - int maxBufferCount = getMaxBufferCountLocked(); - if (slot < 0 || maxBufferCount <= slot) { + if (slot < 0 || slot >= NUM_BUFFER_SLOTS) { ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", - maxBufferCount, slot); + NUM_BUFFER_SLOTS, slot); return BAD_VALUE; } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { - // XXX: I vaguely recall there was some reason this can be valid, but - // for the life of me I can't recall under what circumstances that's - // the case. ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)", slot, mSlots[slot].mBufferState); return BAD_VALUE; @@ -247,7 +244,7 @@ status_t BufferQueue::requestBuffer(int slot, sp* buf) { return NO_ERROR; } -status_t BufferQueue::dequeueBuffer(int *outBuf, sp* outFence, +status_t BufferQueue::dequeueBuffer(int *outBuf, sp* outFence, bool async, 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); @@ -279,7 +276,16 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp* outFence, return NO_INIT; } - const int maxBufferCount = getMaxBufferCountLocked(); + const int maxBufferCount = getMaxBufferCountLocked(async); + if (async && mOverrideMaxBufferCount) { + // FIXME: some drivers are manually setting the buffer-count (which they + // shouldn't), so we do this extra test here to handle that case. + // This is TEMPORARY, until we get this fixed. + if (mOverrideMaxBufferCount < maxBufferCount) { + ST_LOGE("dequeueBuffer: async mode is invalid with buffercount override"); + return BAD_VALUE; + } + } // Free up any buffers that are in slots beyond the max buffer // count. @@ -328,7 +334,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp* outFence, // make sure the client is not trying to dequeue more buffers // than allowed. const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1); - const int minUndequeuedCount = mMinUndequeuedBufferCount; + const int minUndequeuedCount = getMinUndequeuedBufferCount(async); if (newUndequeuedCount < minUndequeuedCount) { ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) " "exceeded (dequeued=%d undequeudCount=%d)", @@ -448,9 +454,10 @@ status_t BufferQueue::queueBuffer(int buf, uint32_t transform; int scalingMode; int64_t timestamp; + bool async; sp fence; - input.deflate(×tamp, &crop, &scalingMode, &transform, &fence); + input.deflate(×tamp, &crop, &scalingMode, &transform, &async, &fence); if (fence == NULL) { ST_LOGE("queueBuffer: fence is NULL"); @@ -477,7 +484,17 @@ status_t BufferQueue::queueBuffer(int buf, ST_LOGE("queueBuffer: BufferQueue has been abandoned!"); return NO_INIT; } - int maxBufferCount = getMaxBufferCountLocked(); + + const int maxBufferCount = getMaxBufferCountLocked(async); + if (async && mOverrideMaxBufferCount) { + // FIXME: some drivers are manually setting the buffer-count (which they + // shouldn't), so we do this extra test here to handle that case. + // This is TEMPORARY, until we get this fixed. + if (mOverrideMaxBufferCount < maxBufferCount) { + ST_LOGE("queueBuffer: async mode is invalid with buffercount override"); + return BAD_VALUE; + } + } if (buf < 0 || buf >= maxBufferCount) { ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", maxBufferCount, buf); @@ -523,7 +540,7 @@ status_t BufferQueue::queueBuffer(int buf, item.mFrameNumber = mFrameCounter; item.mBuf = buf; item.mFence = fence; - item.mDequeueBufferCannotBlock = mDequeueBufferCannotBlock; + item.mIsDroppable = mDequeueBufferCannotBlock || async; if (mQueue.empty()) { // when the queue is empty, we can ignore "mDequeueBufferCannotBlock", and @@ -534,7 +551,7 @@ status_t BufferQueue::queueBuffer(int buf, // when the queue is not empty, we need to look at the front buffer // state and see if we need to replace it. Fifo::iterator front(mQueue.begin()); - if (front->mDequeueBufferCannotBlock) { + if (front->mIsDroppable) { // buffer slot currently queued is marked free if still tracked if (stillTracking(front)) { mSlots[front->mBuf].mBufferState = BufferSlot::FREE; @@ -573,10 +590,9 @@ void BufferQueue::cancelBuffer(int buf, const sp& fence) { return; } - int maxBufferCount = getMaxBufferCountLocked(); - if (buf < 0 || buf >= maxBufferCount) { + if (buf < 0 || buf >= NUM_BUFFER_SLOTS) { ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", - maxBufferCount, buf); + NUM_BUFFER_SLOTS, buf); return; } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", @@ -630,8 +646,6 @@ status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBuffer mBufferHasBeenQueued = false; mDequeueBufferCannotBlock = mConsumerControlledByApp && producerControlledByApp; - mMinUndequeuedBufferCount = mDequeueBufferCannotBlock ? - mMaxAcquiredBufferCount+1 : mMaxAcquiredBufferCount; return err; } @@ -704,12 +718,11 @@ void BufferQueue::dump(String8& result, const char* prefix) const { fifoSize++; } - int maxBufferCount = getMaxBufferCountLocked(); result.appendFormat( - "%s-BufferQueue maxBufferCount=%d, mDequeueBufferCannotBlock=%d, default-size=[%dx%d], " + "%s-BufferQueue mMaxAcquiredBufferCount=%d, mDequeueBufferCannotBlock=%d, default-size=[%dx%d], " "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n", - prefix, maxBufferCount, mDequeueBufferCannotBlock, mDefaultWidth, + prefix, mMaxAcquiredBufferCount, mDequeueBufferCannotBlock, mDefaultWidth, mDefaultHeight, mDefaultBufferFormat, mTransformHint, fifoSize, fifo.string()); @@ -725,16 +738,25 @@ void BufferQueue::dump(String8& result, const char* prefix) const { } } stateName; + // just trim the free buffers to not spam the dump + int maxBufferCount = 0; + for (int i=NUM_BUFFER_SLOTS-1 ; i>=0 ; i--) { + const BufferSlot& slot(mSlots[i]); + if ((slot.mBufferState != BufferSlot::FREE) || (slot.mGraphicBuffer != NULL)) { + maxBufferCount = i+1; + break; + } + } + for (int i=0 ; i& buf(slot.mGraphicBuffer); result.appendFormat( "%s%s[%02d:%p] state=%-8s", - prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, - slot.mGraphicBuffer.get(), + prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, buf.get(), stateName(slot.mBufferState) ); - const sp& buf(slot.mGraphicBuffer); if (buf != NULL) { result.appendFormat( ", %p [%4ux%4u:%4u,%3X]", @@ -1018,12 +1040,17 @@ status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { return NO_ERROR; } -int BufferQueue::getMinMaxBufferCountLocked() const { - return mMinUndequeuedBufferCount + 1; +int BufferQueue::getMinUndequeuedBufferCount(bool async) const { + return (mDequeueBufferCannotBlock || async) ? + mMaxAcquiredBufferCount+1 : mMaxAcquiredBufferCount; } -int BufferQueue::getMaxBufferCountLocked() const { - int minMaxBufferCount = getMinMaxBufferCountLocked(); +int BufferQueue::getMinMaxBufferCountLocked(bool async) const { + return getMinUndequeuedBufferCount(async) + 1; +} + +int BufferQueue::getMaxBufferCountLocked(bool async) const { + int minMaxBufferCount = getMinMaxBufferCountLocked(async); int maxBufferCount = mDefaultMaxBufferCount; if (maxBufferCount < minMaxBufferCount) { diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 9f65fc3f2..2e561dfc2 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -80,10 +80,11 @@ public: return result; } - virtual status_t dequeueBuffer(int *buf, sp* fence, + virtual status_t dequeueBuffer(int *buf, sp* fence, bool async, uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); + data.writeInt32(async); data.writeInt32(w); data.writeInt32(h); data.writeInt32(format); @@ -197,13 +198,14 @@ status_t BnGraphicBufferProducer::onTransact( } break; case DEQUEUE_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); + bool async = data.readInt32(); uint32_t w = data.readInt32(); uint32_t h = data.readInt32(); uint32_t format = data.readInt32(); uint32_t usage = data.readInt32(); int buf; sp fence; - int result = dequeueBuffer(&buf, &fence, w, h, format, usage); + int result = dequeueBuffer(&buf, &fence, async, w, h, format, usage); reply->writeInt32(buf); reply->writeInt32(fence != NULL); if (fence != NULL) { @@ -274,6 +276,7 @@ size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const + sizeof(crop) + sizeof(scalingMode) + sizeof(transform) + + sizeof(async) + fence->getFlattenedSize(); } @@ -291,6 +294,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::flatten(void* buffer, size_t 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, &async, sizeof(async)); p += sizeof(async); err = fence->flatten(p, size - (p - (char*)buffer), fds, count); return err; } @@ -304,6 +308,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(void const* buffer, 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(&async, p, sizeof(async)); p += sizeof(async); fence = new Fence(); err = fence->unflatten(p, size - (p - (const char*)buffer), fds, count); return err; diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 0d4449af6..998ea8ac8 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -73,6 +73,7 @@ Surface::Surface( mConsumerRunningBehind = false; mConnectedToCpu = false; mProducerControlledByApp = true; + mSwapIntervalZero = false; } Surface::~Surface() { @@ -162,7 +163,6 @@ int Surface::setSwapInterval(int interval) { // EGL specification states: // interval is silently clamped to minimum and maximum implementation // dependent values before being stored. - // Although we don't have to, we apply the same logic here. if (interval < minSwapInterval) interval = minSwapInterval; @@ -170,11 +170,9 @@ int Surface::setSwapInterval(int interval) { if (interval > maxSwapInterval) interval = maxSwapInterval; - // FIXME: re-implement swap-interval - //status_t res = mGraphicBufferProducer->setSynchronousMode(interval ? true : false); - status_t res = NO_ERROR; + mSwapIntervalZero = (interval == 0); - return res; + return NO_ERROR; } int Surface::dequeueBuffer(android_native_buffer_t** buffer, @@ -186,7 +184,7 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int reqW = mReqWidth ? mReqWidth : mUserWidth; int reqH = mReqHeight ? mReqHeight : mUserHeight; sp fence; - status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, + status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, mSwapIntervalZero, reqW, reqH, mReqFormat, mReqUsage); if (result < 0) { ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d)" @@ -282,7 +280,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { sp fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); IGraphicBufferProducer::QueueBufferOutput output; IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode, - mTransform, fence); + mTransform, mSwapIntervalZero, fence); status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output); if (err != OK) { ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 1f8e7fa0d..b691fc111 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -71,12 +71,12 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { sp fence; sp buf; IGraphicBufferProducer::QueueBufferInput qbi(0, Rect(0, 0, 1, 1), - NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); + NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); BufferQueue::BufferItem item; for (int i = 0; i < 2; i++) { ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mBQ->dequeueBuffer(&slot, &fence, 1, 1, 0, + mBQ->dequeueBuffer(&slot, &fence, false, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN)); ASSERT_EQ(OK, mBQ->requestBuffer(slot, &buf)); ASSERT_EQ(OK, mBQ->queueBuffer(slot, qbi, &qbo)); @@ -84,7 +84,7 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { } ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, - mBQ->dequeueBuffer(&slot, &fence, 1, 1, 0, + mBQ->dequeueBuffer(&slot, &fence, false, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN)); ASSERT_EQ(OK, mBQ->requestBuffer(slot, &buf)); ASSERT_EQ(OK, mBQ->queueBuffer(slot, qbi, &qbo)); diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp index 9908cc9db..158c94b69 100644 --- a/libs/gui/tests/SurfaceTextureClient_test.cpp +++ b/libs/gui/tests/SurfaceTextureClient_test.cpp @@ -361,7 +361,6 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) { TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) { android_native_buffer_t* buf[3]; - ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1)); ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0])); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1])); @@ -382,7 +381,6 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) { TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) { android_native_buffer_t* buf[3]; - ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1)); ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0])); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1])); @@ -403,7 +401,6 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) { TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) { android_native_buffer_t* buf[3]; - ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1)); ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0])); @@ -429,7 +426,6 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) { TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) { android_native_buffer_t* buf[3]; android_native_buffer_t* firstBuf; - ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1)); ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &firstBuf)); ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), firstBuf, -1)); @@ -449,7 +445,6 @@ TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) { android_native_buffer_t* buf[3]; - ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1)); ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3)); // We should be able to dequeue all the buffers before we've queued mANWy. @@ -528,7 +523,6 @@ TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) { }; android_native_buffer_t* buf[3]; - ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1)); ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3)); // dequeue/queue/update so we have a current buffer ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0])); diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index c92b66654..57cb36171 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -126,7 +126,7 @@ status_t VirtualDisplaySurface::advanceFrame() { mQueueBufferOutput.deflate(&mSinkBufferWidth, &mSinkBufferHeight, &transformHint, &numPendingBuffers); int sslot; - result = dequeueBuffer(SOURCE_SINK, 0, &sslot, &outFence); + result = dequeueBuffer(SOURCE_SINK, 0, &sslot, &outFence, false); if (result < 0) return result; mOutputProducerSlot = mapSource2ProducerSlot(SOURCE_SINK, sslot); @@ -196,7 +196,7 @@ void VirtualDisplaySurface::onFrameCommitted() { status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot, QueueBufferInput(systemTime(), Rect(mSinkBufferWidth, mSinkBufferHeight), - NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, outFence), + NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, outFence), &qbo); if (result == NO_ERROR) { updateQueueBufferOutput(qbo); @@ -224,8 +224,8 @@ status_t VirtualDisplaySurface::setBufferCount(int bufferCount) { } status_t VirtualDisplaySurface::dequeueBuffer(Source source, - uint32_t format, int* sslot, sp* fence) { - status_t result = mSource[source]->dequeueBuffer(sslot, fence, + uint32_t format, int* sslot, sp* fence, bool async) { + status_t result = mSource[source]->dequeueBuffer(sslot, fence, async, mSinkBufferWidth, mSinkBufferHeight, format, mProducerUsage); if (result < 0) return result; @@ -257,7 +257,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(Source source, return result; } -status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp* fence, +status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp* fence, bool async, uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED, "Unexpected dequeueBuffer() in %s state", dbgStateStr()); @@ -273,7 +273,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp* fence, } int sslot; - status_t result = dequeueBuffer(source, format, &sslot, fence); + status_t result = dequeueBuffer(source, format, &sslot, fence, async); if (result >= 0) { *pslot = mapSource2ProducerSlot(source, sslot); } @@ -321,8 +321,9 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot, Rect crop; int scalingMode; uint32_t transform; + bool async; input.deflate(×tamp, &crop, &scalingMode, &transform, - &mFbFence); + &async, &mFbFence); mFbProducerSlot = pslot; } diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index 94b24d2e1..dc9655b62 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -95,7 +95,7 @@ private: // virtual status_t requestBuffer(int pslot, sp* outBuf); virtual status_t setBufferCount(int bufferCount); - virtual status_t dequeueBuffer(int* pslot, sp* fence, + virtual status_t dequeueBuffer(int* pslot, sp* fence, bool async, uint32_t w, uint32_t h, uint32_t format, uint32_t usage); virtual status_t queueBuffer(int pslot, const QueueBufferInput& input, QueueBufferOutput* output); @@ -109,7 +109,7 @@ private: // static Source fbSourceForCompositionType(CompositionType type); status_t dequeueBuffer(Source source, uint32_t format, - int* sslot, sp* fence); + int* sslot, sp* fence, bool async); void updateQueueBufferOutput(const QueueBufferOutput& qbo); void resetPerFrameState();