OSDN Git Service

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