diff options
author | Dan Stoza | 2015-04-24 10:48:37 -0500 |
---|---|---|
committer | Gerrit Code Review | 2015-04-24 10:48:38 -0500 |
commit | fb6d43ff44bb2b708494749a7f6037505ccd7bf6 (patch) | |
tree | 0787fd87be87ee92762753f107ebf61b120f61d7 /libs | |
parent | 56f1f16c7b01a53282d483259ae80d035cc6496b (diff) | |
parent | 0de7ea752900b5da29ad19c2799040235477f3c5 (diff) | |
download | frameworks-native-fb6d43ff44bb2b708494749a7f6037505ccd7bf6.tar.gz frameworks-native-fb6d43ff44bb2b708494749a7f6037505ccd7bf6.tar.xz frameworks-native-fb6d43ff44bb2b708494749a7f6037505ccd7bf6.zip |
Merge "libgui: Change BufferQueue to use free lists"
Diffstat (limited to 'libs')
-rw-r--r-- | libs/gui/BufferQueueConsumer.cpp | 28 | ||||
-rw-r--r-- | libs/gui/BufferQueueCore.cpp | 60 | ||||
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 67 |
3 files changed, 116 insertions, 39 deletions
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index 526c3b729..c7d5e0032 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp | |||
@@ -120,6 +120,7 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, | |||
120 | if (mCore->stillTracking(front)) { | 120 | if (mCore->stillTracking(front)) { |
121 | // Front buffer is still in mSlots, so mark the slot as free | 121 | // Front buffer is still in mSlots, so mark the slot as free |
122 | mSlots[front->mSlot].mBufferState = BufferSlot::FREE; | 122 | mSlots[front->mSlot].mBufferState = BufferSlot::FREE; |
123 | mCore->mFreeBuffers.push_back(front->mSlot); | ||
123 | } | 124 | } |
124 | mCore->mQueue.erase(front); | 125 | mCore->mQueue.erase(front); |
125 | front = mCore->mQueue.begin(); | 126 | front = mCore->mQueue.begin(); |
@@ -173,6 +174,8 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, | |||
173 | 174 | ||
174 | ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); | 175 | ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); |
175 | 176 | ||
177 | mCore->validateConsistencyLocked(); | ||
178 | |||
176 | return NO_ERROR; | 179 | return NO_ERROR; |
177 | } | 180 | } |
178 | 181 | ||
@@ -199,6 +202,7 @@ status_t BufferQueueConsumer::detachBuffer(int slot) { | |||
199 | 202 | ||
200 | mCore->freeBufferLocked(slot); | 203 | mCore->freeBufferLocked(slot); |
201 | mCore->mDequeueCondition.broadcast(); | 204 | mCore->mDequeueCondition.broadcast(); |
205 | mCore->validateConsistencyLocked(); | ||
202 | 206 | ||
203 | return NO_ERROR; | 207 | return NO_ERROR; |
204 | } | 208 | } |
@@ -217,18 +221,11 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot, | |||
217 | 221 | ||
218 | Mutex::Autolock lock(mCore->mMutex); | 222 | Mutex::Autolock lock(mCore->mMutex); |
219 | 223 | ||
220 | // Make sure we don't have too many acquired buffers and find a free slot | 224 | // Make sure we don't have too many acquired buffers |
221 | // to put the buffer into (the oldest if there are multiple). | ||
222 | int numAcquiredBuffers = 0; | 225 | int numAcquiredBuffers = 0; |
223 | int found = BufferQueueCore::INVALID_BUFFER_SLOT; | ||
224 | for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { | 226 | for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { |
225 | if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) { | 227 | if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) { |
226 | ++numAcquiredBuffers; | 228 | ++numAcquiredBuffers; |
227 | } else if (mSlots[s].mBufferState == BufferSlot::FREE) { | ||
228 | if (found == BufferQueueCore::INVALID_BUFFER_SLOT || | ||
229 | mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) { | ||
230 | found = s; | ||
231 | } | ||
232 | } | 229 | } |
233 | } | 230 | } |
234 | 231 | ||
@@ -238,6 +235,17 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot, | |||
238 | mCore->mMaxAcquiredBufferCount); | 235 | mCore->mMaxAcquiredBufferCount); |
239 | return INVALID_OPERATION; | 236 | return INVALID_OPERATION; |
240 | } | 237 | } |
238 | |||
239 | // Find a free slot to put the buffer into | ||
240 | int found = BufferQueueCore::INVALID_BUFFER_SLOT; | ||
241 | if (!mCore->mFreeSlots.empty()) { | ||
242 | auto slot = mCore->mFreeSlots.begin(); | ||
243 | found = *slot; | ||
244 | mCore->mFreeSlots.erase(slot); | ||
245 | } else if (!mCore->mFreeBuffers.empty()) { | ||
246 | found = mCore->mFreeBuffers.front(); | ||
247 | mCore->mFreeBuffers.remove(found); | ||
248 | } | ||
241 | if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { | 249 | if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { |
242 | BQ_LOGE("attachBuffer(P): could not find free buffer slot"); | 250 | BQ_LOGE("attachBuffer(P): could not find free buffer slot"); |
243 | return NO_MEMORY; | 251 | return NO_MEMORY; |
@@ -271,6 +279,8 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot, | |||
271 | // for attached buffers. | 279 | // for attached buffers. |
272 | mSlots[*outSlot].mAcquireCalled = false; | 280 | mSlots[*outSlot].mAcquireCalled = false; |
273 | 281 | ||
282 | mCore->validateConsistencyLocked(); | ||
283 | |||
274 | return NO_ERROR; | 284 | return NO_ERROR; |
275 | } | 285 | } |
276 | 286 | ||
@@ -311,6 +321,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, | |||
311 | mSlots[slot].mEglFence = eglFence; | 321 | mSlots[slot].mEglFence = eglFence; |
312 | mSlots[slot].mFence = releaseFence; | 322 | mSlots[slot].mFence = releaseFence; |
313 | mSlots[slot].mBufferState = BufferSlot::FREE; | 323 | mSlots[slot].mBufferState = BufferSlot::FREE; |
324 | mCore->mFreeBuffers.push_back(slot); | ||
314 | listener = mCore->mConnectedProducerListener; | 325 | listener = mCore->mConnectedProducerListener; |
315 | BQ_LOGV("releaseBuffer: releasing slot %d", slot); | 326 | BQ_LOGV("releaseBuffer: releasing slot %d", slot); |
316 | } else if (mSlots[slot].mNeedsCleanupOnRelease) { | 327 | } else if (mSlots[slot].mNeedsCleanupOnRelease) { |
@@ -325,6 +336,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, | |||
325 | } | 336 | } |
326 | 337 | ||
327 | mCore->mDequeueCondition.broadcast(); | 338 | mCore->mDequeueCondition.broadcast(); |
339 | mCore->validateConsistencyLocked(); | ||
328 | } // Autolock scope | 340 | } // Autolock scope |
329 | 341 | ||
330 | // Call back without lock held | 342 | // Call back without lock held |
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp index edebc4553..29415c94c 100644 --- a/libs/gui/BufferQueueCore.cpp +++ b/libs/gui/BufferQueueCore.cpp | |||
@@ -53,6 +53,8 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) : | |||
53 | mConnectedProducerListener(), | 53 | mConnectedProducerListener(), |
54 | mSlots(), | 54 | mSlots(), |
55 | mQueue(), | 55 | mQueue(), |
56 | mFreeSlots(), | ||
57 | mFreeBuffers(), | ||
56 | mOverrideMaxBufferCount(0), | 58 | mOverrideMaxBufferCount(0), |
57 | mDequeueCondition(), | 59 | mDequeueCondition(), |
58 | mUseAsyncBuffer(true), | 60 | mUseAsyncBuffer(true), |
@@ -76,6 +78,9 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) : | |||
76 | BQ_LOGE("createGraphicBufferAlloc failed"); | 78 | BQ_LOGE("createGraphicBufferAlloc failed"); |
77 | } | 79 | } |
78 | } | 80 | } |
81 | for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { | ||
82 | mFreeSlots.insert(slot); | ||
83 | } | ||
79 | } | 84 | } |
80 | 85 | ||
81 | BufferQueueCore::~BufferQueueCore() {} | 86 | BufferQueueCore::~BufferQueueCore() {} |
@@ -190,12 +195,20 @@ status_t BufferQueueCore::setDefaultMaxBufferCountLocked(int count) { | |||
190 | 195 | ||
191 | void BufferQueueCore::freeBufferLocked(int slot) { | 196 | void BufferQueueCore::freeBufferLocked(int slot) { |
192 | BQ_LOGV("freeBufferLocked: slot %d", slot); | 197 | BQ_LOGV("freeBufferLocked: slot %d", slot); |
198 | bool hadBuffer = mSlots[slot].mGraphicBuffer != NULL; | ||
193 | mSlots[slot].mGraphicBuffer.clear(); | 199 | mSlots[slot].mGraphicBuffer.clear(); |
194 | if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { | 200 | if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { |
195 | mSlots[slot].mNeedsCleanupOnRelease = true; | 201 | mSlots[slot].mNeedsCleanupOnRelease = true; |
196 | } | 202 | } |
203 | if (mSlots[slot].mBufferState != BufferSlot::FREE) { | ||
204 | mFreeSlots.insert(slot); | ||
205 | } else if (hadBuffer) { | ||
206 | // If the slot was FREE, but we had a buffer, we need to move this slot | ||
207 | // from the free buffers list to the the free slots list | ||
208 | mFreeBuffers.remove(slot); | ||
209 | mFreeSlots.insert(slot); | ||
210 | } | ||
197 | mSlots[slot].mBufferState = BufferSlot::FREE; | 211 | mSlots[slot].mBufferState = BufferSlot::FREE; |
198 | mSlots[slot].mFrameNumber = UINT32_MAX; | ||
199 | mSlots[slot].mAcquireCalled = false; | 212 | mSlots[slot].mAcquireCalled = false; |
200 | 213 | ||
201 | // Destroy fence as BufferQueue now takes ownership | 214 | // Destroy fence as BufferQueue now takes ownership |
@@ -204,6 +217,7 @@ void BufferQueueCore::freeBufferLocked(int slot) { | |||
204 | mSlots[slot].mEglFence = EGL_NO_SYNC_KHR; | 217 | mSlots[slot].mEglFence = EGL_NO_SYNC_KHR; |
205 | } | 218 | } |
206 | mSlots[slot].mFence = Fence::NO_FENCE; | 219 | mSlots[slot].mFence = Fence::NO_FENCE; |
220 | validateConsistencyLocked(); | ||
207 | } | 221 | } |
208 | 222 | ||
209 | void BufferQueueCore::freeAllBuffersLocked() { | 223 | void BufferQueueCore::freeAllBuffersLocked() { |
@@ -236,4 +250,48 @@ void BufferQueueCore::waitWhileAllocatingLocked() const { | |||
236 | } | 250 | } |
237 | } | 251 | } |
238 | 252 | ||
253 | void BufferQueueCore::validateConsistencyLocked() const { | ||
254 | static const useconds_t PAUSE_TIME = 0; | ||
255 | for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { | ||
256 | bool isInFreeSlots = mFreeSlots.count(slot) != 0; | ||
257 | bool isInFreeBuffers = | ||
258 | std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) != | ||
259 | mFreeBuffers.cend(); | ||
260 | if (mSlots[slot].mBufferState == BufferSlot::FREE) { | ||
261 | if (mSlots[slot].mGraphicBuffer == NULL) { | ||
262 | if (!isInFreeSlots) { | ||
263 | BQ_LOGE("Slot %d is FREE but is not in mFreeSlots", slot); | ||
264 | usleep(PAUSE_TIME); | ||
265 | } | ||
266 | if (isInFreeBuffers) { | ||
267 | BQ_LOGE("Slot %d is in mFreeSlots " | ||
268 | "but is also in mFreeBuffers", slot); | ||
269 | usleep(PAUSE_TIME); | ||
270 | } | ||
271 | } else { | ||
272 | if (!isInFreeBuffers) { | ||
273 | BQ_LOGE("Slot %d is FREE but is not in mFreeBuffers", slot); | ||
274 | usleep(PAUSE_TIME); | ||
275 | } | ||
276 | if (isInFreeSlots) { | ||
277 | BQ_LOGE("Slot %d is in mFreeBuffers " | ||
278 | "but is also in mFreeSlots", slot); | ||
279 | usleep(PAUSE_TIME); | ||
280 | } | ||
281 | } | ||
282 | } else { | ||
283 | if (isInFreeSlots) { | ||
284 | BQ_LOGE("Slot %d is in mFreeSlots but is not FREE (%d)", | ||
285 | slot, mSlots[slot].mBufferState); | ||
286 | usleep(PAUSE_TIME); | ||
287 | } | ||
288 | if (isInFreeBuffers) { | ||
289 | BQ_LOGE("Slot %d is in mFreeBuffers but is not FREE (%d)", | ||
290 | slot, mSlots[slot].mBufferState); | ||
291 | usleep(PAUSE_TIME); | ||
292 | } | ||
293 | } | ||
294 | } | ||
295 | } | ||
296 | |||
239 | } // namespace android | 297 | } // namespace android |
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 6452cddcf..a27d5f033 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp | |||
@@ -161,8 +161,6 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, | |||
161 | } | 161 | } |
162 | } | 162 | } |
163 | 163 | ||
164 | // Look for a free buffer to give to the client | ||
165 | *found = BufferQueueCore::INVALID_BUFFER_SLOT; | ||
166 | int dequeuedCount = 0; | 164 | int dequeuedCount = 0; |
167 | int acquiredCount = 0; | 165 | int acquiredCount = 0; |
168 | for (int s = 0; s < maxBufferCount; ++s) { | 166 | for (int s = 0; s < maxBufferCount; ++s) { |
@@ -173,15 +171,6 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, | |||
173 | case BufferSlot::ACQUIRED: | 171 | case BufferSlot::ACQUIRED: |
174 | ++acquiredCount; | 172 | ++acquiredCount; |
175 | break; | 173 | break; |
176 | case BufferSlot::FREE: | ||
177 | // We return the oldest of the free buffers to avoid | ||
178 | // stalling the producer if possible, since the consumer | ||
179 | // may still have pending reads of in-flight buffers | ||
180 | if (*found == BufferQueueCore::INVALID_BUFFER_SLOT || | ||
181 | mSlots[s].mFrameNumber < mSlots[*found].mFrameNumber) { | ||
182 | *found = s; | ||
183 | } | ||
184 | break; | ||
185 | default: | 174 | default: |
186 | break; | 175 | break; |
187 | } | 176 | } |
@@ -214,6 +203,8 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, | |||
214 | } | 203 | } |
215 | } | 204 | } |
216 | 205 | ||
206 | *found = BufferQueueCore::INVALID_BUFFER_SLOT; | ||
207 | |||
217 | // If we disconnect and reconnect quickly, we can be in a state where | 208 | // If we disconnect and reconnect quickly, we can be in a state where |
218 | // our slots are empty but we have many buffers in the queue. This can | 209 | // our slots are empty but we have many buffers in the queue. This can |
219 | // cause us to run out of memory if we outrun the consumer. Wait here if | 210 | // cause us to run out of memory if we outrun the consumer. Wait here if |
@@ -223,6 +214,19 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, | |||
223 | if (tooManyBuffers) { | 214 | if (tooManyBuffers) { |
224 | BQ_LOGV("%s: queue size is %zu, waiting", caller, | 215 | BQ_LOGV("%s: queue size is %zu, waiting", caller, |
225 | mCore->mQueue.size()); | 216 | mCore->mQueue.size()); |
217 | } else { | ||
218 | if (!mCore->mFreeBuffers.empty()) { | ||
219 | auto slot = mCore->mFreeBuffers.begin(); | ||
220 | *found = *slot; | ||
221 | mCore->mFreeBuffers.erase(slot); | ||
222 | } else if (!mCore->mFreeSlots.empty()) { | ||
223 | auto slot = mCore->mFreeSlots.begin(); | ||
224 | // Only return free slots up to the max buffer count | ||
225 | if (*slot < maxBufferCount) { | ||
226 | *found = *slot; | ||
227 | mCore->mFreeSlots.erase(slot); | ||
228 | } | ||
229 | } | ||
226 | } | 230 | } |
227 | 231 | ||
228 | // If no buffer is found, or if the queue has too many buffers | 232 | // If no buffer is found, or if the queue has too many buffers |
@@ -335,6 +339,8 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, | |||
335 | *outFence = mSlots[found].mFence; | 339 | *outFence = mSlots[found].mFence; |
336 | mSlots[found].mEglFence = EGL_NO_SYNC_KHR; | 340 | mSlots[found].mEglFence = EGL_NO_SYNC_KHR; |
337 | mSlots[found].mFence = Fence::NO_FENCE; | 341 | mSlots[found].mFence = Fence::NO_FENCE; |
342 | |||
343 | mCore->validateConsistencyLocked(); | ||
338 | } // Autolock scope | 344 | } // Autolock scope |
339 | 345 | ||
340 | if (returnFlags & BUFFER_NEEDS_REALLOCATION) { | 346 | if (returnFlags & BUFFER_NEEDS_REALLOCATION) { |
@@ -355,7 +361,6 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, | |||
355 | return NO_INIT; | 361 | return NO_INIT; |
356 | } | 362 | } |
357 | 363 | ||
358 | mSlots[*outSlot].mFrameNumber = UINT32_MAX; | ||
359 | mSlots[*outSlot].mGraphicBuffer = graphicBuffer; | 364 | mSlots[*outSlot].mGraphicBuffer = graphicBuffer; |
360 | } // Autolock scope | 365 | } // Autolock scope |
361 | } | 366 | } |
@@ -414,6 +419,7 @@ status_t BufferQueueProducer::detachBuffer(int slot) { | |||
414 | 419 | ||
415 | mCore->freeBufferLocked(slot); | 420 | mCore->freeBufferLocked(slot); |
416 | mCore->mDequeueCondition.broadcast(); | 421 | mCore->mDequeueCondition.broadcast(); |
422 | mCore->validateConsistencyLocked(); | ||
417 | 423 | ||
418 | return NO_ERROR; | 424 | return NO_ERROR; |
419 | } | 425 | } |
@@ -438,27 +444,19 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, | |||
438 | return NO_INIT; | 444 | return NO_INIT; |
439 | } | 445 | } |
440 | 446 | ||
441 | // Find the oldest valid slot | 447 | if (mCore->mFreeBuffers.empty()) { |
442 | int found = BufferQueueCore::INVALID_BUFFER_SLOT; | ||
443 | for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { | ||
444 | if (mSlots[s].mBufferState == BufferSlot::FREE && | ||
445 | mSlots[s].mGraphicBuffer != NULL) { | ||
446 | if (found == BufferQueueCore::INVALID_BUFFER_SLOT || | ||
447 | mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) { | ||
448 | found = s; | ||
449 | } | ||
450 | } | ||
451 | } | ||
452 | |||
453 | if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { | ||
454 | return NO_MEMORY; | 448 | return NO_MEMORY; |
455 | } | 449 | } |
456 | 450 | ||
451 | int found = mCore->mFreeBuffers.front(); | ||
452 | mCore->mFreeBuffers.remove(found); | ||
453 | |||
457 | BQ_LOGV("detachNextBuffer detached slot %d", found); | 454 | BQ_LOGV("detachNextBuffer detached slot %d", found); |
458 | 455 | ||
459 | *outBuffer = mSlots[found].mGraphicBuffer; | 456 | *outBuffer = mSlots[found].mGraphicBuffer; |
460 | *outFence = mSlots[found].mFence; | 457 | *outFence = mSlots[found].mFence; |
461 | mCore->freeBufferLocked(found); | 458 | mCore->freeBufferLocked(found); |
459 | mCore->validateConsistencyLocked(); | ||
462 | 460 | ||
463 | return NO_ERROR; | 461 | return NO_ERROR; |
464 | } | 462 | } |
@@ -506,6 +504,8 @@ status_t BufferQueueProducer::attachBuffer(int* outSlot, | |||
506 | mSlots[*outSlot].mFence = Fence::NO_FENCE; | 504 | mSlots[*outSlot].mFence = Fence::NO_FENCE; |
507 | mSlots[*outSlot].mRequestBufferCalled = true; | 505 | mSlots[*outSlot].mRequestBufferCalled = true; |
508 | 506 | ||
507 | mCore->validateConsistencyLocked(); | ||
508 | |||
509 | return returnFlags; | 509 | return returnFlags; |
510 | } | 510 | } |
511 | 511 | ||
@@ -640,9 +640,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, | |||
640 | // mark it as freed | 640 | // mark it as freed |
641 | if (mCore->stillTracking(front)) { | 641 | if (mCore->stillTracking(front)) { |
642 | mSlots[front->mSlot].mBufferState = BufferSlot::FREE; | 642 | mSlots[front->mSlot].mBufferState = BufferSlot::FREE; |
643 | // Reset the frame number of the freed buffer so that it is | 643 | mCore->mFreeBuffers.push_front(front->mSlot); |
644 | // the first in line to be dequeued again | ||
645 | mSlots[front->mSlot].mFrameNumber = 0; | ||
646 | } | 644 | } |
647 | // Overwrite the droppable buffer with the incoming one | 645 | // Overwrite the droppable buffer with the incoming one |
648 | *front = item; | 646 | *front = item; |
@@ -664,6 +662,8 @@ status_t BufferQueueProducer::queueBuffer(int slot, | |||
664 | 662 | ||
665 | // Take a ticket for the callback functions | 663 | // Take a ticket for the callback functions |
666 | callbackTicket = mNextCallbackTicket++; | 664 | callbackTicket = mNextCallbackTicket++; |
665 | |||
666 | mCore->validateConsistencyLocked(); | ||
667 | } // Autolock scope | 667 | } // Autolock scope |
668 | 668 | ||
669 | // Wait without lock held | 669 | // Wait without lock held |
@@ -724,10 +724,11 @@ void BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { | |||
724 | return; | 724 | return; |
725 | } | 725 | } |
726 | 726 | ||
727 | mCore->mFreeBuffers.push_front(slot); | ||
727 | mSlots[slot].mBufferState = BufferSlot::FREE; | 728 | mSlots[slot].mBufferState = BufferSlot::FREE; |
728 | mSlots[slot].mFrameNumber = 0; | ||
729 | mSlots[slot].mFence = fence; | 729 | mSlots[slot].mFence = fence; |
730 | mCore->mDequeueCondition.broadcast(); | 730 | mCore->mDequeueCondition.broadcast(); |
731 | mCore->validateConsistencyLocked(); | ||
731 | } | 732 | } |
732 | 733 | ||
733 | int BufferQueueProducer::query(int what, int *outValue) { | 734 | int BufferQueueProducer::query(int what, int *outValue) { |
@@ -1009,13 +1010,19 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width, | |||
1009 | } | 1010 | } |
1010 | mCore->freeBufferLocked(slot); // Clean up the slot first | 1011 | mCore->freeBufferLocked(slot); // Clean up the slot first |
1011 | mSlots[slot].mGraphicBuffer = buffers[i]; | 1012 | mSlots[slot].mGraphicBuffer = buffers[i]; |
1012 | mSlots[slot].mFrameNumber = 0; | ||
1013 | mSlots[slot].mFence = Fence::NO_FENCE; | 1013 | mSlots[slot].mFence = Fence::NO_FENCE; |
1014 | |||
1015 | // freeBufferLocked puts this slot on the free slots list. Since | ||
1016 | // we then attached a buffer, move the slot to free buffer list. | ||
1017 | mCore->mFreeSlots.erase(slot); | ||
1018 | mCore->mFreeBuffers.push_front(slot); | ||
1019 | |||
1014 | BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot); | 1020 | BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot); |
1015 | } | 1021 | } |
1016 | 1022 | ||
1017 | mCore->mIsAllocating = false; | 1023 | mCore->mIsAllocating = false; |
1018 | mCore->mIsAllocatingCondition.broadcast(); | 1024 | mCore->mIsAllocatingCondition.broadcast(); |
1025 | mCore->validateConsistencyLocked(); | ||
1019 | } // Autolock scope | 1026 | } // Autolock scope |
1020 | } | 1027 | } |
1021 | } | 1028 | } |