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