Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a07dc8d authored by Dan Stoza's avatar Dan Stoza Committed by Android (Google) Code Review
Browse files

Merge "Split BufferQueue into core + producer + consumer"

parents d5bb577d 289ade16
Loading
Loading
Loading
Loading
+103 −0
Original line number Diff line number Diff line
/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_GUI_BUFFERITEM_H
#define ANDROID_GUI_BUFFERITEM_H

#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <gui/IGraphicBufferConsumer.h>

#include <ui/Rect.h>

#include <utils/Flattenable.h>
#include <utils/StrongPointer.h>

namespace android {

class Fence;
class GraphicBuffer;

class BufferItem : public Flattenable<BufferItem> {
    friend class Flattenable<BufferItem>;
    size_t getPodSize() const;
    size_t getFlattenedSize() const;
    size_t getFdCount() const;
    status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
    status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);

    public:
    // The default value of mBuf, used to indicate this doesn't correspond to a slot.
    enum { INVALID_BUFFER_SLOT = -1 };
    BufferItem();
    operator IGraphicBufferConsumer::BufferItem() const;

    static const char* scalingModeName(uint32_t scalingMode);

    // mGraphicBuffer points to the buffer allocated for this slot, or is NULL
    // if the buffer in this slot has been acquired in the past (see
    // BufferSlot.mAcquireCalled).
    sp<GraphicBuffer> mGraphicBuffer;

    // mFence is a fence that will signal when the buffer is idle.
    sp<Fence> mFence;

    // mCrop is the current crop rectangle for this buffer slot.
    Rect mCrop;

    // mTransform is the current transform flags for this buffer slot.
    // refer to NATIVE_WINDOW_TRANSFORM_* in <window.h>
    uint32_t mTransform;

    // mScalingMode is the current scaling mode for this buffer slot.
    // refer to NATIVE_WINDOW_SCALING_* in <window.h>
    uint32_t mScalingMode;

    // mTimestamp is the current timestamp for this buffer slot. This gets
    // to set by queueBuffer each time this slot is queued. This value
    // is guaranteed to be monotonically increasing for each newly
    // acquired buffer.
    int64_t mTimestamp;

    // mIsAutoTimestamp indicates whether mTimestamp was generated
    // automatically when the buffer was queued.
    bool mIsAutoTimestamp;

    // mFrameNumber is the number of the queued frame for this slot.
    uint64_t mFrameNumber;

    // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
    int mSlot;

    // mIsDroppable whether this buffer was queued with the
    // property that it can be replaced by a new buffer for the purpose of
    // making sure dequeueBuffer() won't block.
    // i.e.: was the BufferQueue in "mDequeueBufferCannotBlock" when this buffer
    // was queued.
    bool mIsDroppable;

    // Indicates whether this buffer has been seen by a consumer yet
    bool mAcquireCalled;

    // Indicates this buffer must be transformed by the inverse transform of the screen
    // it is displayed onto. This is applied after mTransform.
    bool mTransformToDisplayInverse;
};

} // namespace android

#endif
+148 −0
Original line number Diff line number Diff line
/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_GUI_BUFFERQUEUECONSUMER_H
#define ANDROID_GUI_BUFFERQUEUECONSUMER_H

#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <gui/BufferQueueCore.h>
#include <gui/IGraphicBufferConsumer.h>

namespace android {

class BufferQueueCore;

class BufferQueueConsumer : public BnGraphicBufferConsumer {

public:
    BufferQueueConsumer(const sp<BufferQueueCore>& core);
    virtual ~BufferQueueConsumer();

    // acquireBuffer attempts to acquire ownership of the next pending buffer in
    // the BufferQueue. If no buffer is pending then it returns
    // NO_BUFFER_AVAILABLE. If a buffer is successfully acquired, the
    // information about the buffer is returned in BufferItem.  If the buffer
    // returned had previously been acquired then the BufferItem::mGraphicBuffer
    // field of buffer is set to NULL and it is assumed that the consumer still
    // holds a reference to the buffer.
    //
    // If expectedPresent is nonzero, it indicates the time when the buffer
    // will be displayed on screen. If the buffer's timestamp is farther in the
    // future, the buffer won't be acquired, and PRESENT_LATER will be
    // returned.  The presentation time is in nanoseconds, and the time base
    // is CLOCK_MONOTONIC.
    virtual status_t acquireBuffer(BufferItem* outBuffer,
            nsecs_t expectedPresent);

    // releaseBuffer releases a buffer slot from the consumer back to the
    // BufferQueue.  This may be done while the buffer's contents are still
    // being accessed.  The fence will signal when the buffer is no longer
    // in use. frameNumber is used to indentify the exact buffer returned.
    //
    // If releaseBuffer returns STALE_BUFFER_SLOT, then the consumer must free
    // any references to the just-released buffer that it might have, as if it
    // had received a onBuffersReleased() call with a mask set for the released
    // buffer.
    //
    // Note that the dependencies on EGL will be removed once we switch to using
    // the Android HW Sync HAL.
    virtual status_t releaseBuffer(int slot, uint64_t frameNumber,
            const sp<Fence>& releaseFence, EGLDisplay display,
            EGLSyncKHR fence);

    // connect connects a consumer to the BufferQueue.  Only one
    // consumer may be connected, and when that consumer disconnects the
    // BufferQueue is placed into the "abandoned" state, causing most
    // interactions with the BufferQueue by the producer to fail.
    // controlledByApp indicates whether the consumer is controlled by
    // the application.
    //
    // consumerListener may not be NULL.
    virtual status_t connect(const sp<IConsumerListener>& consumerListener,
            bool controlledByApp);

    // disconnect disconnects a consumer from the BufferQueue. All
    // buffers will be freed and the BufferQueue is placed in the "abandoned"
    // state, causing most interactions with the BufferQueue by the producer to
    // fail.
    virtual status_t disconnect();

    // getReleasedBuffers sets the value pointed to by outSlotMask to a bit mask
    // indicating which buffer slots have been released by the BufferQueue
    // but have not yet been released by the consumer.
    //
    // This should be called from the onBuffersReleased() callback.
    virtual status_t getReleasedBuffers(uint32_t* outSlotMask);

    // setDefaultBufferSize is used to set the size of buffers returned by
    // dequeueBuffer when a width and height of zero is requested.  Default
    // is 1x1.
    virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height);

    // setDefaultMaxBufferCount sets the default value for the maximum buffer
    // count (the initial default is 2). If the producer has requested a
    // buffer count using setBufferCount, the default buffer count will only
    // take effect if the producer sets the count back to zero.
    //
    // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive.
    virtual status_t setDefaultMaxBufferCount(int bufferCount);

    // disableAsyncBuffer disables the extra buffer used in async mode
    // (when both producer and consumer have set their "isControlledByApp"
    // flag) and has dequeueBuffer() return WOULD_BLOCK instead.
    //
    // This can only be called before connect().
    virtual status_t disableAsyncBuffer();

    // setMaxAcquiredBufferCount sets the maximum number of buffers that can
    // be acquired by the consumer at one time (default 1).  This call will
    // fail if a producer is connected to the BufferQueue.
    virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);

    // setConsumerName sets the name used in logging
    virtual void setConsumerName(const String8& name);

    // setDefaultBufferFormat allows the BufferQueue to create
    // GraphicBuffers of a defaultFormat if no format is specified
    // in dequeueBuffer.  Formats are enumerated in graphics.h; the
    // initial default is HAL_PIXEL_FORMAT_RGBA_8888.
    virtual status_t setDefaultBufferFormat(uint32_t defaultFormat);

    // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer.
    // These are merged with the bits passed to dequeueBuffer.  The values are
    // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0.
    virtual status_t setConsumerUsageBits(uint32_t usage);

    // setTransformHint bakes in rotation to buffers so overlays can be used.
    // The values are enumerated in window.h, e.g.
    // NATIVE_WINDOW_TRANSFORM_ROT_90.  The default is 0 (no transform).
    virtual status_t setTransformHint(uint32_t hint);

    // dump our state in a String
    virtual void dump(String8& result, const char* prefix) const;

private:
    sp<BufferQueueCore> mCore;
    BufferQueueCore::SlotsType& mSlots;
    String8 mConsumerName; // Cached from mCore. Updated on setConsumerName.

}; // class BufferQueueConsumer

} // namespace android

#endif
+120 −0
Original line number Diff line number Diff line
/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_GUI_BUFFERQUEUECORE_H
#define ANDROID_GUI_BUFFERQUEUECORE_H

#include <gui/BufferSlot.h>

#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/StrongPointer.h>
#include <utils/Trace.h>
#include <utils/Vector.h>

#define BQ_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
#define BQ_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
#define BQ_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
#define BQ_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
#define BQ_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)

#define ATRACE_BUFFER_INDEX(index)                                   \
    if (ATRACE_ENABLED()) {                                          \
        char ___traceBuf[1024];                                      \
        snprintf(___traceBuf, 1024, "%s: %d",                        \
                mCore->mConsumerName.string(), (index));             \
        android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);  \
    }

namespace android {

class BufferItem;
class IBinder;
class IConsumerListener;
class IGraphicBufferAlloc;

class BufferQueueCore : public virtual RefBase {

    friend class BufferQueueProducer;
    friend class BufferQueueConsumer;

public:
    // BufferQueue will keep track of at most this value of buffers. Attempts
    // at runtime to increase the number of buffers past this will fail.
    enum { NUM_BUFFER_SLOTS = 32 };

    // Used as a placeholder slot number when the value isn't pointing to an
    // existing buffer.
    enum { INVALID_BUFFER_SLOT = -1 }; // TODO: Extract from IGBC::BufferItem

    // We reserve two slots in order to guarantee that the producer and
    // consumer can run asynchronously.
    enum { MAX_MAX_ACQUIRED_BUFFERS = NUM_BUFFER_SLOTS - 2 };

    // The default API number used to indicate that no producer is connected
    enum { NO_CONNECTED_API = 0 };

    typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];
    typedef Vector<BufferItem> Fifo;

    // BufferQueueCore manages a pool of gralloc memory slots to be used by
    // producers and consumers. allocator is used to allocate all the needed
    // gralloc buffers.
    BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator = NULL);
    virtual ~BufferQueueCore();

private:
    void dump(String8& result, const char* prefix) const;

    int getMinUndequeuedBufferCountLocked(bool async) const;
    int getMinMaxBufferCountLocked(bool async) const;
    int getMaxBufferCountLocked(bool async) const;
    status_t setDefaultMaxBufferCountLocked(int count);
    void freeBufferLocked(int slot);
    void freeAllBuffersLocked();
    bool stillTracking(const BufferItem* item) const;

    const sp<IGraphicBufferAlloc>& mAllocator;
    mutable Mutex mMutex;
    bool mIsAbandoned;
    bool mConsumerControlledByApp;
    String8 mConsumerName;
    sp<IConsumerListener> mConsumerListener;
    uint32_t mConsumerUsageBits;
    int mConnectedApi;
    sp<IBinder> mConnectedProducerToken;
    BufferSlot mSlots[NUM_BUFFER_SLOTS];
    Fifo mQueue;
    int mOverrideMaxBufferCount;
    mutable Condition mDequeueCondition;
    bool mUseAsyncBuffer;
    bool mDequeueBufferCannotBlock;
    uint32_t mDefaultBufferFormat;
    int mDefaultWidth;
    int mDefaultHeight;
    int mDefaultMaxBufferCount;
    int mMaxAcquiredBufferCount;
    bool mBufferHasBeenQueued;
    uint64_t mFrameCounter;
    uint32_t mTransformHint;

}; // class BufferQueueCore

} // namespace android

#endif
+165 −0
Original line number Diff line number Diff line
/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_GUI_BUFFERQUEUEPRODUCER_H
#define ANDROID_GUI_BUFFERQUEUEPRODUCER_H

#include <gui/BufferQueueCore.h>
#include <gui/IGraphicBufferProducer.h>

namespace android {

class BufferSlot;

class BufferQueueProducer : public BnGraphicBufferProducer,
                            private IBinder::DeathRecipient {

public:
    BufferQueueProducer(const sp<BufferQueueCore>& core);
    virtual ~BufferQueueProducer();

    // requestBuffer returns the GraphicBuffer for slot N.
    //
    // In normal operation, this is called the first time slot N is returned
    // by dequeueBuffer.  It must be called again if dequeueBuffer returns
    // flags indicating that previously-returned buffers are no longer valid.
    virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);

    // setBufferCount updates the number of available buffer slots.  If this
    // method succeeds, buffer slots will be both unallocated and owned by
    // the BufferQueue object (i.e. they are not owned by the producer or
    // consumer).
    //
    // This will fail if the producer has dequeued any buffers, or if
    // bufferCount is invalid.  bufferCount must generally be a value
    // between the minimum undequeued buffer count (exclusive) and NUM_BUFFER_SLOTS
    // (inclusive).  It may also be set to zero (the default) to indicate
    // that the producer does not wish to set a value.  The minimum value
    // can be obtained by calling query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
    // ...).
    //
    // This may only be called by the producer.  The consumer will be told
    // to discard buffers through the onBuffersReleased callback.
    virtual status_t setBufferCount(int bufferCount);

    // dequeueBuffer gets the next buffer slot index for the producer to use.
    // If a buffer slot is available then that slot index is written to the
    // location pointed to by the buf argument and a status of OK is returned.
    // If no slot is available then a status of -EBUSY is returned and buf is
    // unmodified.
    //
    // The outFence parameter will be updated to hold the fence associated with
    // the buffer. The contents of the buffer must not be overwritten until the
    // fence signals. If the fence is Fence::NO_FENCE, the buffer may be
    // written immediately.
    //
    // The width and height parameters must be no greater than the minimum of
    // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).
    // An error due to invalid dimensions might not be reported until
    // updateTexImage() is called.  If width and height are both zero, the
    // default values specified by setDefaultBufferSize() are used instead.
    //
    // The pixel formats are enumerated in graphics.h, e.g.
    // HAL_PIXEL_FORMAT_RGBA_8888.  If the format is 0, the default format
    // will be used.
    //
    // The usage argument specifies gralloc buffer usage flags.  The values
    // are enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER.  These
    // will be merged with the usage flags specified by setConsumerUsageBits.
    //
    // The return value may be a negative error value or a non-negative
    // collection of flags.  If the flags are set, the return values are
    // valid, but additional actions must be performed.
    //
    // If IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION is set, the
    // producer must discard cached GraphicBuffer references for the slot
    // returned in buf.
    // If IGraphicBufferProducer::RELEASE_ALL_BUFFERS is set, the producer
    // must discard cached GraphicBuffer references for all slots.
    //
    // In both cases, the producer will need to call requestBuffer to get a
    // GraphicBuffer handle for the returned slot.
    virtual status_t dequeueBuffer(int *outSlot, sp<Fence>* outFence, bool async,
            uint32_t width, uint32_t height, uint32_t format, uint32_t usage);

    // queueBuffer returns a filled buffer to the BufferQueue.
    //
    // Additional data is provided in the QueueBufferInput struct.  Notably,
    // a timestamp must be provided for the buffer. The timestamp is in
    // nanoseconds, and must be monotonically increasing. Its other semantics
    // (zero point, etc) are producer-specific and should be documented by the
    // producer.
    //
    // The caller may provide a fence that signals when all rendering
    // operations have completed.  Alternatively, NO_FENCE may be used,
    // indicating that the buffer is ready immediately.
    //
    // Some values are returned in the output struct: the current settings
    // for default width and height, the current transform hint, and the
    // number of queued buffers.
    virtual status_t queueBuffer(int slot,
            const QueueBufferInput& input, QueueBufferOutput* output);

    // cancelBuffer returns a dequeued buffer to the BufferQueue, but doesn't
    // queue it for use by the consumer.
    //
    // The buffer will not be overwritten until the fence signals.  The fence
    // will usually be the one obtained from dequeueBuffer.
    virtual void cancelBuffer(int slot, const sp<Fence>& fence);

    // Query native window attributes.  The "what" values are enumerated in
    // window.h (e.g. NATIVE_WINDOW_FORMAT).
    virtual int query(int what, int* outValue);

    // connect attempts to connect a producer API to the BufferQueue.  This
    // must be called before any other IGraphicBufferProducer methods are
    // called except for getAllocator.  A consumer must already be connected.
    //
    // This method will fail if connect was previously called on the
    // BufferQueue and no corresponding disconnect call was made (i.e. if
    // it's still connected to a producer).
    //
    // APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU).
    virtual status_t connect(const sp<IBinder>& token,
            int api, bool producerControlledByApp, QueueBufferOutput* output);

    // disconnect attempts to disconnect a producer API from the BufferQueue.
    // Calling this method will cause any subsequent calls to other
    // IGraphicBufferProducer methods to fail except for getAllocator and connect.
    // Successfully calling connect after this will allow the other methods to
    // succeed again.
    //
    // This method will fail if the the BufferQueue is not currently
    // connected to the specified producer API.
    virtual status_t disconnect(int api);

private:
    // This is required by the IBinder::DeathRecipient interface
    virtual void binderDied(const wp<IBinder>& who);

    sp<BufferQueueCore> mCore;
    BufferQueueCore::SlotsType& mSlots;

    // This is a cached copy of the name stored in the BufferQueueCore.
    // It's updated during connect and dequeueBuffer (which should catch
    // most updates).
    String8 mConsumerName;

}; // class BufferQueueProducer

} // namespace android

#endif
+136 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading