OSDN Git Service

Merge "Use a named constant rather than a magic number." into jb-mr1-dev
[android-x86/frameworks-native.git] / libs / gui / BufferQueue.cpp
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define LOG_TAG "BufferQueue"
18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19 //#define LOG_NDEBUG 0
20
21 #define GL_GLEXT_PROTOTYPES
22 #define EGL_EGLEXT_PROTOTYPES
23
24 #include <EGL/egl.h>
25 #include <EGL/eglext.h>
26
27 #include <gui/BufferQueue.h>
28 #include <gui/ISurfaceComposer.h>
29 #include <private/gui/ComposerService.h>
30
31 #include <utils/Log.h>
32 #include <gui/SurfaceTexture.h>
33 #include <utils/Trace.h>
34
35 // This compile option causes SurfaceTexture to return the buffer that is currently
36 // attached to the GL texture from dequeueBuffer when no other buffers are
37 // available.  It requires the drivers (Gralloc, GL, OMX IL, and Camera) to do
38 // implicit cross-process synchronization to prevent the buffer from being
39 // written to before the buffer has (a) been detached from the GL texture and
40 // (b) all GL reads from the buffer have completed.
41
42 // During refactoring, do not support dequeuing the current buffer
43 #undef ALLOW_DEQUEUE_CURRENT_BUFFER
44
45 #ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
46 #define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    true
47 #warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
48 #else
49 #define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    false
50 #endif
51
52 // Macros for including the BufferQueue name in log messages
53 #define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
54 #define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
55 #define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
56 #define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
57 #define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
58
59 #define ATRACE_BUFFER_INDEX(index)                                            \
60     if (ATRACE_ENABLED()) {                                                   \
61         char ___traceBuf[1024];                                               \
62         snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(),         \
63                 (index));                                                     \
64         android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);           \
65     }
66
67 namespace android {
68
69 // Get an ID that's unique within this process.
70 static int32_t createProcessUniqueId() {
71     static volatile int32_t globalCounter = 0;
72     return android_atomic_inc(&globalCounter);
73 }
74
75 static const char* scalingModeName(int scalingMode) {
76     switch (scalingMode) {
77         case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
78         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
79         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
80         default: return "Unknown";
81     }
82 }
83
84 BufferQueue::BufferQueue(bool allowSynchronousMode,
85         const sp<IGraphicBufferAlloc>& allocator) :
86     mDefaultWidth(1),
87     mDefaultHeight(1),
88     mMaxAcquiredBufferCount(1),
89     mDefaultMaxBufferCount(2),
90     mOverrideMaxBufferCount(0),
91     mSynchronousMode(false),
92     mAllowSynchronousMode(allowSynchronousMode),
93     mConnectedApi(NO_CONNECTED_API),
94     mAbandoned(false),
95     mFrameCounter(0),
96     mBufferHasBeenQueued(false),
97     mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
98     mConsumerUsageBits(0),
99     mTransformHint(0)
100 {
101     // Choose a name using the PID and a process-unique ID.
102     mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
103
104     ST_LOGV("BufferQueue");
105     if (allocator == NULL) {
106         sp<ISurfaceComposer> composer(ComposerService::getComposerService());
107         mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
108         if (mGraphicBufferAlloc == 0) {
109             ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");
110         }
111     } else {
112         mGraphicBufferAlloc = allocator;
113     }
114 }
115
116 BufferQueue::~BufferQueue() {
117     ST_LOGV("~BufferQueue");
118 }
119
120 status_t BufferQueue::setDefaultMaxBufferCountLocked(int count) {
121     if (count < 2 || count > NUM_BUFFER_SLOTS)
122         return BAD_VALUE;
123
124     mDefaultMaxBufferCount = count;
125     mDequeueCondition.broadcast();
126
127     return OK;
128 }
129
130 bool BufferQueue::isSynchronousMode() const {
131     Mutex::Autolock lock(mMutex);
132     return mSynchronousMode;
133 }
134
135 void BufferQueue::setConsumerName(const String8& name) {
136     Mutex::Autolock lock(mMutex);
137     mConsumerName = name;
138 }
139
140 status_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) {
141     Mutex::Autolock lock(mMutex);
142     mDefaultBufferFormat = defaultFormat;
143     return OK;
144 }
145
146 status_t BufferQueue::setConsumerUsageBits(uint32_t usage) {
147     Mutex::Autolock lock(mMutex);
148     mConsumerUsageBits = usage;
149     return OK;
150 }
151
152 status_t BufferQueue::setTransformHint(uint32_t hint) {
153     ST_LOGV("setTransformHint: %02x", hint);
154     Mutex::Autolock lock(mMutex);
155     mTransformHint = hint;
156     return OK;
157 }
158
159 status_t BufferQueue::setBufferCount(int bufferCount) {
160     ST_LOGV("setBufferCount: count=%d", bufferCount);
161
162     sp<ConsumerListener> listener;
163     {
164         Mutex::Autolock lock(mMutex);
165
166         if (mAbandoned) {
167             ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!");
168             return NO_INIT;
169         }
170         if (bufferCount > NUM_BUFFER_SLOTS) {
171             ST_LOGE("setBufferCount: bufferCount larger than slots available");
172             return BAD_VALUE;
173         }
174
175         // Error out if the user has dequeued buffers
176         int maxBufferCount = getMaxBufferCountLocked();
177         for (int i=0 ; i<maxBufferCount; i++) {
178             if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
179                 ST_LOGE("setBufferCount: client owns some buffers");
180                 return -EINVAL;
181             }
182         }
183
184         const int minBufferSlots = getMinMaxBufferCountLocked();
185         if (bufferCount == 0) {
186             mOverrideMaxBufferCount = 0;
187             mDequeueCondition.broadcast();
188             return OK;
189         }
190
191         if (bufferCount < minBufferSlots) {
192             ST_LOGE("setBufferCount: requested buffer count (%d) is less than "
193                     "minimum (%d)", bufferCount, minBufferSlots);
194             return BAD_VALUE;
195         }
196
197         // here we're guaranteed that the client doesn't have dequeued buffers
198         // and will release all of its buffer references.
199         //
200         // XXX: Should this use drainQueueAndFreeBuffersLocked instead?
201         freeAllBuffersLocked();
202         mOverrideMaxBufferCount = bufferCount;
203         mBufferHasBeenQueued = false;
204         mDequeueCondition.broadcast();
205         listener = mConsumerListener;
206     } // scope for lock
207
208     if (listener != NULL) {
209         listener->onBuffersReleased();
210     }
211
212     return OK;
213 }
214
215 int BufferQueue::query(int what, int* outValue)
216 {
217     ATRACE_CALL();
218     Mutex::Autolock lock(mMutex);
219
220     if (mAbandoned) {
221         ST_LOGE("query: SurfaceTexture has been abandoned!");
222         return NO_INIT;
223     }
224
225     int value;
226     switch (what) {
227     case NATIVE_WINDOW_WIDTH:
228         value = mDefaultWidth;
229         break;
230     case NATIVE_WINDOW_HEIGHT:
231         value = mDefaultHeight;
232         break;
233     case NATIVE_WINDOW_FORMAT:
234         value = mDefaultBufferFormat;
235         break;
236     case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
237         value = getMinUndequeuedBufferCountLocked();
238         break;
239     case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
240         value = (mQueue.size() >= 2);
241         break;
242     default:
243         return BAD_VALUE;
244     }
245     outValue[0] = value;
246     return NO_ERROR;
247 }
248
249 status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
250     ATRACE_CALL();
251     ST_LOGV("requestBuffer: slot=%d", slot);
252     Mutex::Autolock lock(mMutex);
253     if (mAbandoned) {
254         ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!");
255         return NO_INIT;
256     }
257     int maxBufferCount = getMaxBufferCountLocked();
258     if (slot < 0 || maxBufferCount <= slot) {
259         ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",
260                 maxBufferCount, slot);
261         return BAD_VALUE;
262     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
263         // XXX: I vaguely recall there was some reason this can be valid, but
264         // for the life of me I can't recall under what circumstances that's
265         // the case.
266         ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)",
267                 slot, mSlots[slot].mBufferState);
268         return BAD_VALUE;
269     }
270     mSlots[slot].mRequestBufferCalled = true;
271     *buf = mSlots[slot].mGraphicBuffer;
272     return NO_ERROR;
273 }
274
275 status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
276         uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
277     ATRACE_CALL();
278     ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
279
280     if ((w && !h) || (!w && h)) {
281         ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
282         return BAD_VALUE;
283     }
284
285     status_t returnFlags(OK);
286     EGLDisplay dpy = EGL_NO_DISPLAY;
287     EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
288
289     { // Scope for the lock
290         Mutex::Autolock lock(mMutex);
291
292         if (format == 0) {
293             format = mDefaultBufferFormat;
294         }
295         // turn on usage bits the consumer requested
296         usage |= mConsumerUsageBits;
297
298         int found = -1;
299         int dequeuedCount = 0;
300         bool tryAgain = true;
301         while (tryAgain) {
302             if (mAbandoned) {
303                 ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
304                 return NO_INIT;
305             }
306
307             const int maxBufferCount = getMaxBufferCountLocked();
308
309             // Free up any buffers that are in slots beyond the max buffer
310             // count.
311             for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
312                 assert(mSlots[i].mBufferState == BufferSlot::FREE);
313                 if (mSlots[i].mGraphicBuffer != NULL) {
314                     freeBufferLocked(i);
315                     returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
316                 }
317             }
318
319             // look for a free buffer to give to the client
320             found = INVALID_BUFFER_SLOT;
321             dequeuedCount = 0;
322             for (int i = 0; i < maxBufferCount; i++) {
323                 const int state = mSlots[i].mBufferState;
324                 if (state == BufferSlot::DEQUEUED) {
325                     dequeuedCount++;
326                 }
327
328                 // this logic used to be if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER)
329                 // but dequeuing the current buffer is disabled.
330                 if (false) {
331                     // This functionality has been temporarily removed so
332                     // BufferQueue and SurfaceTexture can be refactored into
333                     // separate objects
334                 } else {
335                     if (state == BufferSlot::FREE) {
336                         /* We return the oldest of the free buffers to avoid
337                          * stalling the producer if possible.  This is because
338                          * the consumer may still have pending reads of the
339                          * buffers in flight.
340                          */
341                         bool isOlder = mSlots[i].mFrameNumber <
342                                 mSlots[found].mFrameNumber;
343                         if (found < 0 || isOlder) {
344                             found = i;
345                         }
346                     }
347                 }
348             }
349
350             // clients are not allowed to dequeue more than one buffer
351             // if they didn't set a buffer count.
352             if (!mOverrideMaxBufferCount && dequeuedCount) {
353                 ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "
354                         "setting the buffer count");
355                 return -EINVAL;
356             }
357
358             // See whether a buffer has been queued since the last
359             // setBufferCount so we know whether to perform the min undequeued
360             // buffers check below.
361             if (mBufferHasBeenQueued) {
362                 // make sure the client is not trying to dequeue more buffers
363                 // than allowed.
364                 const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1);
365                 const int minUndequeuedCount = getMinUndequeuedBufferCountLocked();
366                 if (newUndequeuedCount < minUndequeuedCount) {
367                     ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) "
368                             "exceeded (dequeued=%d undequeudCount=%d)",
369                             minUndequeuedCount, dequeuedCount,
370                             newUndequeuedCount);
371                     return -EBUSY;
372                 }
373             }
374
375             // If no buffer is found, wait for a buffer to be released or for
376             // the max buffer count to change.
377             tryAgain = found == INVALID_BUFFER_SLOT;
378             if (tryAgain) {
379                 mDequeueCondition.wait(mMutex);
380             }
381         }
382
383
384         if (found == INVALID_BUFFER_SLOT) {
385             // This should not happen.
386             ST_LOGE("dequeueBuffer: no available buffer slots");
387             return -EBUSY;
388         }
389
390         const int buf = found;
391         *outBuf = found;
392
393         ATRACE_BUFFER_INDEX(buf);
394
395         const bool useDefaultSize = !w && !h;
396         if (useDefaultSize) {
397             // use the default size
398             w = mDefaultWidth;
399             h = mDefaultHeight;
400         }
401
402         // buffer is now in DEQUEUED (but can also be current at the same time,
403         // if we're in synchronous mode)
404         mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
405
406         const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
407         if ((buffer == NULL) ||
408             (uint32_t(buffer->width)  != w) ||
409             (uint32_t(buffer->height) != h) ||
410             (uint32_t(buffer->format) != format) ||
411             ((uint32_t(buffer->usage) & usage) != usage))
412         {
413             status_t error;
414             sp<GraphicBuffer> graphicBuffer(
415                     mGraphicBufferAlloc->createGraphicBuffer(
416                             w, h, format, usage, &error));
417             if (graphicBuffer == 0) {
418                 ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
419                         "failed");
420                 return error;
421             }
422
423             mSlots[buf].mAcquireCalled = false;
424             mSlots[buf].mGraphicBuffer = graphicBuffer;
425             mSlots[buf].mRequestBufferCalled = false;
426             mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
427             mSlots[buf].mFence.clear();
428             mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
429
430             returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
431         }
432
433         dpy = mSlots[buf].mEglDisplay;
434         eglFence = mSlots[buf].mEglFence;
435         outFence = mSlots[buf].mFence;
436         mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
437         mSlots[buf].mFence.clear();
438     }  // end lock scope
439
440     if (eglFence != EGL_NO_SYNC_KHR) {
441         EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
442         // If something goes wrong, log the error, but return the buffer without
443         // synchronizing access to it.  It's too late at this point to abort the
444         // dequeue operation.
445         if (result == EGL_FALSE) {
446             ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());
447         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
448             ST_LOGE("dequeueBuffer: timeout waiting for fence");
449         }
450         eglDestroySyncKHR(dpy, eglFence);
451     }
452
453     ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
454             mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);
455
456     return returnFlags;
457 }
458
459 status_t BufferQueue::setSynchronousMode(bool enabled) {
460     ATRACE_CALL();
461     ST_LOGV("setSynchronousMode: enabled=%d", enabled);
462     Mutex::Autolock lock(mMutex);
463
464     if (mAbandoned) {
465         ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
466         return NO_INIT;
467     }
468
469     status_t err = OK;
470     if (!mAllowSynchronousMode && enabled)
471         return err;
472
473     if (!enabled) {
474         // going to asynchronous mode, drain the queue
475         err = drainQueueLocked();
476         if (err != NO_ERROR)
477             return err;
478     }
479
480     if (mSynchronousMode != enabled) {
481         // - if we're going to asynchronous mode, the queue is guaranteed to be
482         // empty here
483         // - if the client set the number of buffers, we're guaranteed that
484         // we have at least 3 (because we don't allow less)
485         mSynchronousMode = enabled;
486         mDequeueCondition.broadcast();
487     }
488     return err;
489 }
490
491 status_t BufferQueue::queueBuffer(int buf,
492         const QueueBufferInput& input, QueueBufferOutput* output) {
493     ATRACE_CALL();
494     ATRACE_BUFFER_INDEX(buf);
495
496     Rect crop;
497     uint32_t transform;
498     int scalingMode;
499     int64_t timestamp;
500     sp<Fence> fence;
501
502     input.deflate(&timestamp, &crop, &scalingMode, &transform, &fence);
503
504     ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x "
505             "scale=%s",
506             buf, timestamp, crop.left, crop.top, crop.right, crop.bottom,
507             transform, scalingModeName(scalingMode));
508
509     sp<ConsumerListener> listener;
510
511     { // scope for the lock
512         Mutex::Autolock lock(mMutex);
513         if (mAbandoned) {
514             ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!");
515             return NO_INIT;
516         }
517         int maxBufferCount = getMaxBufferCountLocked();
518         if (buf < 0 || buf >= maxBufferCount) {
519             ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
520                     maxBufferCount, buf);
521             return -EINVAL;
522         } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
523             ST_LOGE("queueBuffer: slot %d is not owned by the client "
524                     "(state=%d)", buf, mSlots[buf].mBufferState);
525             return -EINVAL;
526         } else if (!mSlots[buf].mRequestBufferCalled) {
527             ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
528                     "buffer", buf);
529             return -EINVAL;
530         }
531
532         const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer);
533         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
534         Rect croppedCrop;
535         crop.intersect(bufferRect, &croppedCrop);
536         if (croppedCrop != crop) {
537             ST_LOGE("queueBuffer: crop rect is not contained within the "
538                     "buffer in slot %d", buf);
539             return -EINVAL;
540         }
541
542         if (mSynchronousMode) {
543             // In synchronous mode we queue all buffers in a FIFO.
544             mQueue.push_back(buf);
545
546             // Synchronous mode always signals that an additional frame should
547             // be consumed.
548             listener = mConsumerListener;
549         } else {
550             // In asynchronous mode we only keep the most recent buffer.
551             if (mQueue.empty()) {
552                 mQueue.push_back(buf);
553
554                 // Asynchronous mode only signals that a frame should be
555                 // consumed if no previous frame was pending. If a frame were
556                 // pending then the consumer would have already been notified.
557                 listener = mConsumerListener;
558             } else {
559                 Fifo::iterator front(mQueue.begin());
560                 // buffer currently queued is freed
561                 mSlots[*front].mBufferState = BufferSlot::FREE;
562                 // and we record the new buffer index in the queued list
563                 *front = buf;
564             }
565         }
566
567         mSlots[buf].mTimestamp = timestamp;
568         mSlots[buf].mCrop = crop;
569         mSlots[buf].mTransform = transform;
570         mSlots[buf].mFence = fence;
571
572         switch (scalingMode) {
573             case NATIVE_WINDOW_SCALING_MODE_FREEZE:
574             case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
575             case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
576                 break;
577             default:
578                 ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode);
579                 scalingMode = mSlots[buf].mScalingMode;
580                 break;
581         }
582
583         mSlots[buf].mBufferState = BufferSlot::QUEUED;
584         mSlots[buf].mScalingMode = scalingMode;
585         mFrameCounter++;
586         mSlots[buf].mFrameNumber = mFrameCounter;
587
588         mBufferHasBeenQueued = true;
589         mDequeueCondition.broadcast();
590
591         output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
592                 mQueue.size());
593
594         ATRACE_INT(mConsumerName.string(), mQueue.size());
595     } // scope for the lock
596
597     // call back without lock held
598     if (listener != 0) {
599         listener->onFrameAvailable();
600     }
601     return OK;
602 }
603
604 void BufferQueue::cancelBuffer(int buf, sp<Fence> fence) {
605     ATRACE_CALL();
606     ST_LOGV("cancelBuffer: slot=%d", buf);
607     Mutex::Autolock lock(mMutex);
608
609     if (mAbandoned) {
610         ST_LOGW("cancelBuffer: BufferQueue has been abandoned!");
611         return;
612     }
613
614     int maxBufferCount = getMaxBufferCountLocked();
615     if (buf < 0 || buf >= maxBufferCount) {
616         ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
617                 maxBufferCount, buf);
618         return;
619     } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
620         ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
621                 buf, mSlots[buf].mBufferState);
622         return;
623     }
624     mSlots[buf].mBufferState = BufferSlot::FREE;
625     mSlots[buf].mFrameNumber = 0;
626     mSlots[buf].mFence = fence;
627     mDequeueCondition.broadcast();
628 }
629
630 status_t BufferQueue::connect(int api, QueueBufferOutput* output) {
631     ATRACE_CALL();
632     ST_LOGV("connect: api=%d", api);
633     Mutex::Autolock lock(mMutex);
634
635     if (mAbandoned) {
636         ST_LOGE("connect: BufferQueue has been abandoned!");
637         return NO_INIT;
638     }
639
640     if (mConsumerListener == NULL) {
641         ST_LOGE("connect: BufferQueue has no consumer!");
642         return NO_INIT;
643     }
644
645     int err = NO_ERROR;
646     switch (api) {
647         case NATIVE_WINDOW_API_EGL:
648         case NATIVE_WINDOW_API_CPU:
649         case NATIVE_WINDOW_API_MEDIA:
650         case NATIVE_WINDOW_API_CAMERA:
651             if (mConnectedApi != NO_CONNECTED_API) {
652                 ST_LOGE("connect: already connected (cur=%d, req=%d)",
653                         mConnectedApi, api);
654                 err = -EINVAL;
655             } else {
656                 mConnectedApi = api;
657                 output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
658                         mQueue.size());
659             }
660             break;
661         default:
662             err = -EINVAL;
663             break;
664     }
665
666     mBufferHasBeenQueued = false;
667
668     return err;
669 }
670
671 status_t BufferQueue::disconnect(int api) {
672     ATRACE_CALL();
673     ST_LOGV("disconnect: api=%d", api);
674
675     int err = NO_ERROR;
676     sp<ConsumerListener> listener;
677
678     { // Scope for the lock
679         Mutex::Autolock lock(mMutex);
680
681         if (mAbandoned) {
682             // it is not really an error to disconnect after the surface
683             // has been abandoned, it should just be a no-op.
684             return NO_ERROR;
685         }
686
687         switch (api) {
688             case NATIVE_WINDOW_API_EGL:
689             case NATIVE_WINDOW_API_CPU:
690             case NATIVE_WINDOW_API_MEDIA:
691             case NATIVE_WINDOW_API_CAMERA:
692                 if (mConnectedApi == api) {
693                     drainQueueAndFreeBuffersLocked();
694                     mConnectedApi = NO_CONNECTED_API;
695                     mDequeueCondition.broadcast();
696                     listener = mConsumerListener;
697                 } else {
698                     ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
699                             mConnectedApi, api);
700                     err = -EINVAL;
701                 }
702                 break;
703             default:
704                 ST_LOGE("disconnect: unknown API %d", api);
705                 err = -EINVAL;
706                 break;
707         }
708     }
709
710     if (listener != NULL) {
711         listener->onBuffersReleased();
712     }
713
714     return err;
715 }
716
717 void BufferQueue::dump(String8& result) const
718 {
719     char buffer[1024];
720     BufferQueue::dump(result, "", buffer, 1024);
721 }
722
723 void BufferQueue::dump(String8& result, const char* prefix,
724         char* buffer, size_t SIZE) const
725 {
726     Mutex::Autolock _l(mMutex);
727
728     String8 fifo;
729     int fifoSize = 0;
730     Fifo::const_iterator i(mQueue.begin());
731     while (i != mQueue.end()) {
732        snprintf(buffer, SIZE, "%02d ", *i++);
733        fifoSize++;
734        fifo.append(buffer);
735     }
736
737     int maxBufferCount = getMaxBufferCountLocked();
738
739     snprintf(buffer, SIZE,
740             "%s-BufferQueue maxBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
741             "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n",
742             prefix, maxBufferCount, mSynchronousMode, mDefaultWidth,
743             mDefaultHeight, mDefaultBufferFormat, mTransformHint,
744             fifoSize, fifo.string());
745     result.append(buffer);
746
747
748     struct {
749         const char * operator()(int state) const {
750             switch (state) {
751                 case BufferSlot::DEQUEUED: return "DEQUEUED";
752                 case BufferSlot::QUEUED: return "QUEUED";
753                 case BufferSlot::FREE: return "FREE";
754                 case BufferSlot::ACQUIRED: return "ACQUIRED";
755                 default: return "Unknown";
756             }
757         }
758     } stateName;
759
760     for (int i=0 ; i<maxBufferCount ; i++) {
761         const BufferSlot& slot(mSlots[i]);
762         snprintf(buffer, SIZE,
763                 "%s%s[%02d] "
764                 "state=%-8s, crop=[%d,%d,%d,%d], "
765                 "xform=0x%02x, time=%#llx, scale=%s",
766                 prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i,
767                 stateName(slot.mBufferState),
768                 slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
769                 slot.mCrop.bottom, slot.mTransform, slot.mTimestamp,
770                 scalingModeName(slot.mScalingMode)
771         );
772         result.append(buffer);
773
774         const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
775         if (buf != NULL) {
776             snprintf(buffer, SIZE,
777                     ", %p [%4ux%4u:%4u,%3X]",
778                     buf->handle, buf->width, buf->height, buf->stride,
779                     buf->format);
780             result.append(buffer);
781         }
782         result.append("\n");
783     }
784 }
785
786 void BufferQueue::freeBufferLocked(int slot) {
787     ST_LOGV("freeBufferLocked: slot=%d", slot);
788     mSlots[slot].mGraphicBuffer = 0;
789     if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
790         mSlots[slot].mNeedsCleanupOnRelease = true;
791     }
792     mSlots[slot].mBufferState = BufferSlot::FREE;
793     mSlots[slot].mFrameNumber = 0;
794     mSlots[slot].mAcquireCalled = false;
795
796     // destroy fence as BufferQueue now takes ownership
797     if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
798         eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
799         mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
800     }
801     mSlots[slot].mFence.clear();
802 }
803
804 void BufferQueue::freeAllBuffersLocked() {
805     ALOGW_IF(!mQueue.isEmpty(),
806             "freeAllBuffersLocked called but mQueue is not empty");
807     mQueue.clear();
808     mBufferHasBeenQueued = false;
809     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
810         freeBufferLocked(i);
811     }
812 }
813
814 status_t BufferQueue::acquireBuffer(BufferItem *buffer) {
815     ATRACE_CALL();
816     Mutex::Autolock _l(mMutex);
817
818     // Check that the consumer doesn't currently have the maximum number of
819     // buffers acquired.  We allow the max buffer count to be exceeded by one
820     // buffer, so that the consumer can successfully set up the newly acquired
821     // buffer before releasing the old one.
822     int numAcquiredBuffers = 0;
823     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
824         if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) {
825             numAcquiredBuffers++;
826         }
827     }
828     if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) {
829         ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)",
830                 numAcquiredBuffers, mMaxAcquiredBufferCount);
831         return INVALID_OPERATION;
832     }
833
834     // check if queue is empty
835     // In asynchronous mode the list is guaranteed to be one buffer
836     // deep, while in synchronous mode we use the oldest buffer.
837     if (!mQueue.empty()) {
838         Fifo::iterator front(mQueue.begin());
839         int buf = *front;
840
841         ATRACE_BUFFER_INDEX(buf);
842
843         if (mSlots[buf].mAcquireCalled) {
844             buffer->mGraphicBuffer = NULL;
845         } else {
846             buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer;
847         }
848         buffer->mCrop = mSlots[buf].mCrop;
849         buffer->mTransform = mSlots[buf].mTransform;
850         buffer->mScalingMode = mSlots[buf].mScalingMode;
851         buffer->mFrameNumber = mSlots[buf].mFrameNumber;
852         buffer->mTimestamp = mSlots[buf].mTimestamp;
853         buffer->mBuf = buf;
854         buffer->mFence = mSlots[buf].mFence;
855
856         mSlots[buf].mAcquireCalled = true;
857         mSlots[buf].mNeedsCleanupOnRelease = false;
858         mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
859         mSlots[buf].mFence.clear();
860
861         mQueue.erase(front);
862         mDequeueCondition.broadcast();
863
864         ATRACE_INT(mConsumerName.string(), mQueue.size());
865     } else {
866         return NO_BUFFER_AVAILABLE;
867     }
868
869     return OK;
870 }
871
872 status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
873         EGLSyncKHR eglFence, const sp<Fence>& fence) {
874     ATRACE_CALL();
875     ATRACE_BUFFER_INDEX(buf);
876
877     Mutex::Autolock _l(mMutex);
878
879     if (buf == INVALID_BUFFER_SLOT) {
880         return -EINVAL;
881     }
882
883     mSlots[buf].mEglDisplay = display;
884     mSlots[buf].mEglFence = eglFence;
885     mSlots[buf].mFence = fence;
886
887     // The buffer can now only be released if its in the acquired state
888     if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
889         mSlots[buf].mBufferState = BufferSlot::FREE;
890     } else if (mSlots[buf].mNeedsCleanupOnRelease) {
891         ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState);
892         mSlots[buf].mNeedsCleanupOnRelease = false;
893         return STALE_BUFFER_SLOT;
894     } else {
895         ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState);
896         return -EINVAL;
897     }
898
899     mDequeueCondition.broadcast();
900     return OK;
901 }
902
903 status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) {
904     ST_LOGV("consumerConnect");
905     Mutex::Autolock lock(mMutex);
906
907     if (mAbandoned) {
908         ST_LOGE("consumerConnect: BufferQueue has been abandoned!");
909         return NO_INIT;
910     }
911
912     mConsumerListener = consumerListener;
913
914     return OK;
915 }
916
917 status_t BufferQueue::consumerDisconnect() {
918     ST_LOGV("consumerDisconnect");
919     Mutex::Autolock lock(mMutex);
920
921     if (mConsumerListener == NULL) {
922         ST_LOGE("consumerDisconnect: No consumer is connected!");
923         return -EINVAL;
924     }
925
926     mAbandoned = true;
927     mConsumerListener = NULL;
928     mQueue.clear();
929     freeAllBuffersLocked();
930     mDequeueCondition.broadcast();
931     return OK;
932 }
933
934 status_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) {
935     ST_LOGV("getReleasedBuffers");
936     Mutex::Autolock lock(mMutex);
937
938     if (mAbandoned) {
939         ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!");
940         return NO_INIT;
941     }
942
943     uint32_t mask = 0;
944     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
945         if (!mSlots[i].mAcquireCalled) {
946             mask |= 1 << i;
947         }
948     }
949     *slotMask = mask;
950
951     ST_LOGV("getReleasedBuffers: returning mask %#x", mask);
952     return NO_ERROR;
953 }
954
955 status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h)
956 {
957     ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
958     if (!w || !h) {
959         ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
960                 w, h);
961         return BAD_VALUE;
962     }
963
964     Mutex::Autolock lock(mMutex);
965     mDefaultWidth = w;
966     mDefaultHeight = h;
967     return OK;
968 }
969
970 status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) {
971     ATRACE_CALL();
972     Mutex::Autolock lock(mMutex);
973     return setDefaultMaxBufferCountLocked(bufferCount);
974 }
975
976 status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
977     ATRACE_CALL();
978     Mutex::Autolock lock(mMutex);
979     if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) {
980         ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d",
981                 maxAcquiredBuffers);
982         return BAD_VALUE;
983     }
984     if (mConnectedApi != NO_CONNECTED_API) {
985         return INVALID_OPERATION;
986     }
987     mMaxAcquiredBufferCount = maxAcquiredBuffers;
988     return OK;
989 }
990
991 void BufferQueue::freeAllBuffersExceptHeadLocked() {
992     int head = -1;
993     if (!mQueue.empty()) {
994         Fifo::iterator front(mQueue.begin());
995         head = *front;
996     }
997     mBufferHasBeenQueued = false;
998     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
999         if (i != head) {
1000             freeBufferLocked(i);
1001         }
1002     }
1003 }
1004
1005 status_t BufferQueue::drainQueueLocked() {
1006     while (mSynchronousMode && !mQueue.isEmpty()) {
1007         mDequeueCondition.wait(mMutex);
1008         if (mAbandoned) {
1009             ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!");
1010             return NO_INIT;
1011         }
1012         if (mConnectedApi == NO_CONNECTED_API) {
1013             ST_LOGE("drainQueueLocked: BufferQueue is not connected!");
1014             return NO_INIT;
1015         }
1016     }
1017     return NO_ERROR;
1018 }
1019
1020 status_t BufferQueue::drainQueueAndFreeBuffersLocked() {
1021     status_t err = drainQueueLocked();
1022     if (err == NO_ERROR) {
1023         if (mSynchronousMode) {
1024             freeAllBuffersLocked();
1025         } else {
1026             freeAllBuffersExceptHeadLocked();
1027         }
1028     }
1029     return err;
1030 }
1031
1032 int BufferQueue::getMinMaxBufferCountLocked() const {
1033     return getMinUndequeuedBufferCountLocked() + 1;
1034 }
1035
1036 int BufferQueue::getMinUndequeuedBufferCountLocked() const {
1037     return mSynchronousMode ? mMaxAcquiredBufferCount :
1038             mMaxAcquiredBufferCount + 1;
1039 }
1040
1041 int BufferQueue::getMaxBufferCountLocked() const {
1042     int minMaxBufferCount = getMinMaxBufferCountLocked();
1043
1044     int maxBufferCount = mDefaultMaxBufferCount;
1045     if (maxBufferCount < minMaxBufferCount) {
1046         maxBufferCount = minMaxBufferCount;
1047     }
1048     if (mOverrideMaxBufferCount != 0) {
1049         assert(mOverrideMaxBufferCount >= minMaxBufferCount);
1050         maxBufferCount = mOverrideMaxBufferCount;
1051     }
1052
1053     // Any buffers that are dequeued by the producer or sitting in the queue
1054     // waiting to be consumed need to have their slots preserved.  Such
1055     // buffers will temporarily keep the max buffer count up until the slots
1056     // no longer need to be preserved.
1057     for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
1058         BufferSlot::BufferState state = mSlots[i].mBufferState;
1059         if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) {
1060             maxBufferCount = i + 1;
1061         }
1062     }
1063
1064     return maxBufferCount;
1065 }
1066
1067 BufferQueue::ProxyConsumerListener::ProxyConsumerListener(
1068         const wp<BufferQueue::ConsumerListener>& consumerListener):
1069         mConsumerListener(consumerListener) {}
1070
1071 BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
1072
1073 void BufferQueue::ProxyConsumerListener::onFrameAvailable() {
1074     sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
1075     if (listener != NULL) {
1076         listener->onFrameAvailable();
1077     }
1078 }
1079
1080 void BufferQueue::ProxyConsumerListener::onBuffersReleased() {
1081     sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
1082     if (listener != NULL) {
1083         listener->onBuffersReleased();
1084     }
1085 }
1086
1087 }; // namespace android