diff options
author | Mathias Agopian <mathias@google.com> | 2013-07-31 20:09:53 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2013-08-01 17:20:08 -0700 |
commit | a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0b (patch) | |
tree | 2ea2866fb6b49eabdc207bb42715665df2c94799 /include | |
parent | ba93b3f8e403636b614a4a379f9421bc70dca84f (diff) | |
download | frameworks_native-a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0b.zip frameworks_native-a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0b.tar.gz frameworks_native-a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0b.tar.bz2 |
Binderize the consumer side of BufferQueue
While currently untested, this should allow to move the
BuffereQueue in the consumer process and have everything
work as usual.
Bug: 9265647
Change-Id: I9ca8f099f7c65b9a27b7e7a3643b46d1b58eacfc
Diffstat (limited to 'include')
-rw-r--r-- | include/gui/BufferQueue.h | 137 | ||||
-rw-r--r-- | include/gui/ConsumerBase.h | 3 | ||||
-rw-r--r-- | include/gui/IConsumerListener.h | 83 | ||||
-rw-r--r-- | include/gui/IGraphicBufferConsumer.h | 209 |
4 files changed, 328 insertions, 104 deletions
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h index cfce40d..1fbfc2b 100644 --- a/include/gui/BufferQueue.h +++ b/include/gui/BufferQueue.h @@ -20,8 +20,10 @@ #include <EGL/egl.h> #include <EGL/eglext.h> +#include <gui/IConsumerListener.h> #include <gui/IGraphicBufferAlloc.h> #include <gui/IGraphicBufferProducer.h> +#include <gui/IGraphicBufferConsumer.h> #include <ui/Fence.h> #include <ui/GraphicBuffer.h> @@ -33,7 +35,7 @@ namespace android { // ---------------------------------------------------------------------------- -class BufferQueue : public BnGraphicBufferProducer { +class BufferQueue : public BnGraphicBufferProducer, public BnGraphicBufferConsumer { public: enum { MIN_UNDEQUEUED_BUFFERS = 2 }; enum { NUM_BUFFER_SLOTS = 32 }; @@ -45,31 +47,8 @@ public: // producer and consumer can run asynchronously. enum { MAX_MAX_ACQUIRED_BUFFERS = NUM_BUFFER_SLOTS - 2 }; - // ConsumerListener is the interface through which the BufferQueue notifies - // the consumer of events that the consumer may wish to react to. Because - // the consumer will generally have a mutex that is locked during calls from - // the consumer to the BufferQueue, these calls from the BufferQueue to the - // consumer *MUST* be called only when the BufferQueue mutex is NOT locked. - struct ConsumerListener : public virtual RefBase { - // onFrameAvailable is called from queueBuffer each time an additional - // frame becomes available for consumption. This means that frames that - // are queued while in asynchronous mode only trigger the callback if no - // previous frames are pending. Frames queued while in synchronous mode - // always trigger the callback. - // - // This is called without any lock held and can be called concurrently - // by multiple threads. - virtual void onFrameAvailable() = 0; - - // onBuffersReleased is called to notify the buffer consumer that the - // BufferQueue has released its references to one or more GraphicBuffers - // contained in its slots. The buffer consumer should then call - // BufferQueue::getReleasedBuffers to retrieve the list of buffers - // - // This is called without any lock held and can be called concurrently - // by multiple threads. - virtual void onBuffersReleased() = 0; - }; + // for backward source compatibility + typedef ::android::ConsumerListener ConsumerListener; // ProxyConsumerListener is a ConsumerListener implementation that keeps a weak // reference to the actual consumer object. It forwards all calls to that @@ -80,19 +59,16 @@ public: // reference in the BufferQueue class is because we're planning to expose the // consumer side of a BufferQueue as a binder interface, which doesn't support // weak references. - class ProxyConsumerListener : public BufferQueue::ConsumerListener { + class ProxyConsumerListener : public BnConsumerListener { public: - - ProxyConsumerListener(const wp<BufferQueue::ConsumerListener>& consumerListener); + ProxyConsumerListener(const wp<ConsumerListener>& consumerListener); virtual ~ProxyConsumerListener(); virtual void onFrameAvailable(); virtual void onBuffersReleased(); - private: - - // mConsumerListener is a weak reference to the ConsumerListener. This is + // mConsumerListener is a weak reference to the IConsumerListener. This is // the raison d'etre of ProxyConsumerListener. - wp<BufferQueue::ConsumerListener> mConsumerListener; + wp<ConsumerListener> mConsumerListener; }; @@ -102,6 +78,14 @@ public: BufferQueue(const sp<IGraphicBufferAlloc>& allocator = NULL); virtual ~BufferQueue(); + // dump our state in a String + virtual void dump(String8& result) const; + virtual void dump(String8& result, const char* prefix) const; + + /* + * IGraphicBufferProducer interface + */ + // Query native window attributes. The "what" values are enumerated in // window.h (e.g. NATIVE_WINDOW_FORMAT). virtual int query(int what, int* value); @@ -216,62 +200,9 @@ public: // connected to the specified producer API. virtual status_t disconnect(int api); - // dump our state in a String - virtual void dump(String8& result) const; - virtual void dump(String8& result, const char* prefix) const; - - // public facing structure for BufferSlot - struct BufferItem { - - BufferItem() : - mTransform(0), - mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), - mTimestamp(0), - mFrameNumber(0), - mBuf(INVALID_BUFFER_SLOT), - mIsDroppable(false), - mAcquireCalled(false) { - mCrop.makeInvalid(); - } - // 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; - - // mCrop is the current crop rectangle for this buffer slot. - Rect mCrop; - - // mTransform is the current transform flags for this buffer slot. - uint32_t mTransform; - - // mScalingMode is the current scaling mode for this buffer slot. - uint32_t mScalingMode; - - // mTimestamp is the current timestamp for this buffer slot. This gets - // to set by queueBuffer each time this slot is queued. - int64_t mTimestamp; - - // mFrameNumber is the number of the queued frame for this slot. - uint64_t mFrameNumber; - - // mBuf is the slot index of this buffer - int mBuf; - - // mFence is a fence that will signal when the buffer is idle. - sp<Fence> mFence; - - // 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; - }; - - // The following public functions are the consumer-facing interface + /* + * IGraphicBufferConsumer interface + */ // acquireBuffer attempts to acquire ownership of the next pending buffer in // the BufferQueue. If no buffer is pending then it returns -EINVAL. If a @@ -286,7 +217,7 @@ public: // 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. - status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen); + virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen); // releaseBuffer releases a buffer slot from the consumer back to the // BufferQueue. This may be done while the buffer's contents are still @@ -300,7 +231,7 @@ public: // // Note that the dependencies on EGL will be removed once we switch to using // the Android HW Sync HAL. - status_t releaseBuffer(int buf, uint64_t frameNumber, + virtual status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, EGLSyncKHR fence, const sp<Fence>& releaseFence); @@ -312,25 +243,25 @@ public: // the application. // // consumer may not be NULL. - status_t consumerConnect(const sp<ConsumerListener>& consumer, bool controlledByApp); + virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp); // consumerDisconnect 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. - status_t consumerDisconnect(); + virtual status_t consumerDisconnect(); // getReleasedBuffers sets the value pointed to by slotMask 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. - status_t getReleasedBuffers(uint32_t* slotMask); + virtual status_t getReleasedBuffers(uint32_t* slotMask); // setDefaultBufferSize is used to set the size of buffers returned by // dequeueBuffer when a width and height of zero is requested. Default // is 1x1. - status_t setDefaultBufferSize(uint32_t w, uint32_t h); + virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h); // setDefaultMaxBufferCount sets the default value for the maximum buffer // count (the initial default is 2). If the producer has requested a @@ -338,38 +269,38 @@ public: // take effect if the producer sets the count back to zero. // // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. - status_t setDefaultMaxBufferCount(int bufferCount); + 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 consumerConnect(). - status_t disableAsyncBuffer(); + 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. - status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers); + virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers); // setConsumerName sets the name used in logging - void setConsumerName(const String8& name); + 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. - status_t setDefaultBufferFormat(uint32_t defaultFormat); + 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. - status_t setConsumerUsageBits(uint32_t usage); + 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). - status_t setTransformHint(uint32_t hint); + virtual status_t setTransformHint(uint32_t hint); private: @@ -560,7 +491,7 @@ private: // mConsumerListener is used to notify the connected consumer of // asynchronous events that it may wish to react to. It is initially set // to NULL and is written by consumerConnect and consumerDisconnect. - sp<ConsumerListener> mConsumerListener; + sp<IConsumerListener> mConsumerListener; // mConsumerControlledByApp whether the connected consumer is controlled by the // application. diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h index 7b58bc5..daad757 100644 --- a/include/gui/ConsumerBase.h +++ b/include/gui/ConsumerBase.h @@ -24,6 +24,7 @@ #include <utils/String8.h> #include <utils/Vector.h> #include <utils/threads.h> +#include <gui/IConsumerListener.h> namespace android { // ---------------------------------------------------------------------------- @@ -34,7 +35,7 @@ class String8; // handles common tasks like management of the connection to the BufferQueue // and the buffer pool. class ConsumerBase : public virtual RefBase, - protected BufferQueue::ConsumerListener { + protected ConsumerListener { public: struct FrameAvailableListener : public virtual RefBase { // onFrameAvailable() is called each time an additional frame becomes diff --git a/include/gui/IConsumerListener.h b/include/gui/IConsumerListener.h new file mode 100644 index 0000000..ac2f9bb --- /dev/null +++ b/include/gui/IConsumerListener.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2013 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_ICONSUMERLISTENER_H +#define ANDROID_GUI_ICONSUMERLISTENER_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/RefBase.h> + +#include <binder/IInterface.h> + +namespace android { +// ---------------------------------------------------------------------------- + +// ConsumerListener is the interface through which the BufferQueue notifies +// the consumer of events that the consumer may wish to react to. Because +// the consumer will generally have a mutex that is locked during calls from +// the consumer to the BufferQueue, these calls from the BufferQueue to the +// consumer *MUST* be called only when the BufferQueue mutex is NOT locked. + +class ConsumerListener : public virtual RefBase { +public: + ConsumerListener() { } + virtual ~ConsumerListener() { } + + // onFrameAvailable is called from queueBuffer each time an additional + // frame becomes available for consumption. This means that frames that + // are queued while in asynchronous mode only trigger the callback if no + // previous frames are pending. Frames queued while in synchronous mode + // always trigger the callback. + // + // This is called without any lock held and can be called concurrently + // by multiple threads. + virtual void onFrameAvailable() = 0; /* Asynchronous */ + + // onBuffersReleased is called to notify the buffer consumer that the + // BufferQueue has released its references to one or more GraphicBuffers + // contained in its slots. The buffer consumer should then call + // BufferQueue::getReleasedBuffers to retrieve the list of buffers + // + // This is called without any lock held and can be called concurrently + // by multiple threads. + virtual void onBuffersReleased() = 0; /* Asynchronous */ +}; + + +class IConsumerListener : public ConsumerListener, public IInterface +{ +public: + DECLARE_META_INTERFACE(ConsumerListener); +}; + +// ---------------------------------------------------------------------------- + +class BnConsumerListener : public BnInterface<IConsumerListener> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_ICONSUMERLISTENER_H diff --git a/include/gui/IGraphicBufferConsumer.h b/include/gui/IGraphicBufferConsumer.h new file mode 100644 index 0000000..82b50c8 --- /dev/null +++ b/include/gui/IGraphicBufferConsumer.h @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2013 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_IGRAPHICBUFFERCONSUMER_H +#define ANDROID_GUI_IGRAPHICBUFFERCONSUMER_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/RefBase.h> +#include <utils/Timers.h> + +#include <binder/IInterface.h> +#include <ui/Rect.h> + +namespace android { +// ---------------------------------------------------------------------------- + +class IConsumerListener; +class GraphicBuffer; +class Fence; + +class IGraphicBufferConsumer : public IInterface { + +public: + + // public facing structure for BufferSlot + 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: + enum { INVALID_BUFFER_SLOT = -1 }; + BufferItem(); + + // 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. + uint32_t mTransform; + + // mScalingMode is the current scaling mode for this buffer slot. + uint32_t mScalingMode; + + // mTimestamp is the current timestamp for this buffer slot. This gets + // to set by queueBuffer each time this slot is queued. + int64_t mTimestamp; + + // mFrameNumber is the number of the queued frame for this slot. + uint64_t mFrameNumber; + + // mBuf is the slot index of this buffer + int mBuf; + + // 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; + }; + + + // acquireBuffer attempts to acquire ownership of the next pending buffer in + // the BufferQueue. If no buffer is pending then it returns -EINVAL. 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 presentWhen 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 *buffer, nsecs_t presentWhen) = 0; + + // 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 buf, uint64_t frameNumber, + EGLDisplay display, EGLSyncKHR fence, + const sp<Fence>& releaseFence) = 0; + + // consumerConnect 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. + // + // consumer may not be NULL. + virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) = 0; + + // consumerDisconnect 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 consumerDisconnect() = 0; + + // getReleasedBuffers sets the value pointed to by slotMask 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* slotMask) = 0; + + // 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 w, uint32_t h) = 0; + + // 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) = 0; + + // 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 consumerConnect(). + virtual status_t disableAsyncBuffer() = 0; + + // 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) = 0; + + // setConsumerName sets the name used in logging + virtual void setConsumerName(const String8& name) = 0; + + // 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) = 0; + + // 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) = 0; + + // 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) = 0; + +public: + DECLARE_META_INTERFACE(GraphicBufferConsumer); +}; + +// ---------------------------------------------------------------------------- + +class BnGraphicBufferConsumer : public BnInterface<IGraphicBufferConsumer> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_IGRAPHICBUFFERCONSUMER_H |