diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2012-04-16 17:54:33 -0700 |
---|---|---|
committer | Eino-Ville Talvala <etalvala@google.com> | 2012-05-14 18:04:01 -0700 |
commit | e41b318bc4708e1dee9364e73215ff0d51fb76a1 (patch) | |
tree | 89c3d100e1d08cc687f77221721aac6e3a175e01 /include/gui | |
parent | d58ae6f59483f986d693021f5895d6230af05d99 (diff) | |
download | frameworks_native-e41b318bc4708e1dee9364e73215ff0d51fb76a1.zip frameworks_native-e41b318bc4708e1dee9364e73215ff0d51fb76a1.tar.gz frameworks_native-e41b318bc4708e1dee9364e73215ff0d51fb76a1.tar.bz2 |
Add a BufferQueue CPU consumer.
Aimed for use cases where gralloc buffers need to be consumed by CPU
users, such as camera image data streams.
The CpuConsumer is a synchronous queue, which exposes raw pointers to
the underlying graphics buffers to applications. Multiple buffers may
be acquired at once, up to the limit set at time of construction.
Change-Id: If1d99f12471438e95a69696e40685948778055fd
Diffstat (limited to 'include/gui')
-rw-r--r-- | include/gui/BufferQueue.h | 5 | ||||
-rw-r--r-- | include/gui/CpuConsumer.h | 142 |
2 files changed, 147 insertions, 0 deletions
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h index 1c80d0c..0539a1b 100644 --- a/include/gui/BufferQueue.h +++ b/include/gui/BufferQueue.h @@ -209,6 +209,11 @@ public: // releaseBuffer releases a buffer slot from the consumer back to the // BufferQueue pending a fence sync. // + // 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. status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence); diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h new file mode 100644 index 0000000..a50a1de --- /dev/null +++ b/include/gui/CpuConsumer.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2012 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_CPUCONSUMER_H +#define ANDROID_GUI_CPUCONSUMER_H + +#include <gui/BufferQueue.h> + +#include <ui/GraphicBuffer.h> + +#include <utils/String8.h> +#include <utils/Vector.h> +#include <utils/threads.h> + +#define ANDROID_GRAPHICS_CPUCONSUMER_JNI_ID "mCpuConsumer" + +namespace android { + +/** + * CpuConsumer is a BufferQueue consumer endpoint that allows direct CPU + * access to the underlying gralloc buffers provided by BufferQueue. Multiple + * buffers may be acquired by it at once, to be used concurrently by the + * CpuConsumer owner. Sets gralloc usage flags to be software-read-only. + * This queue is synchronous by default. + */ + +class CpuConsumer: public virtual RefBase, + protected BufferQueue::ConsumerListener +{ + public: + struct FrameAvailableListener : public virtual RefBase { + // onFrameAvailable() is called each time an additional frame becomes + // available for consumption. A new frame queued will always trigger the + // callback, whether the queue is empty or not. + // + // This is called without any lock held and can be called concurrently + // by multiple threads. + virtual void onFrameAvailable() = 0; + }; + + struct LockedBuffer { + uint8_t *data; + uint32_t width; + uint32_t height; + PixelFormat format; + uint32_t stride; + Rect crop; + uint32_t transform; + uint32_t scalingMode; + int64_t timestamp; + uint64_t frameNumber; + }; + + // Create a new CPU consumer. The maxLockedBuffers parameter specifies + // how many buffers can be locked for user access at the same time. + CpuConsumer(uint32_t maxLockedBuffers); + + virtual ~CpuConsumer(); + + // set the name of the CpuConsumer that will be used to identify it in + // log messages. + void setName(const String8& name); + + // Gets the next graphics buffer from the producer and locks it for CPU use, + // filling out the passed-in locked buffer structure with the native pointer + // and metadata. Returns BAD_VALUE if no new buffer is available, and + // INVALID_OPERATION if the maximum number of buffers is already locked. + // + // Only a fixed number of buffers can be locked at a time, determined by the + // construction-time maxLockedBuffers parameter. If INVALID_OPERATION is + // returned by lockNextBuffer, then old buffers must be returned to the queue + // by calling unlockBuffer before more buffers can be acquired. + status_t lockNextBuffer(LockedBuffer *nativeBuffer); + + // Returns a locked buffer to the queue, allowing it to be reused. Since + // only a fixed number of buffers may be locked at a time, old buffers must + // be released by calling unlockBuffer to ensure new buffers can be acquired by + // lockNextBuffer. + status_t unlockBuffer(const LockedBuffer &nativeBuffer); + + // setFrameAvailableListener sets the listener object that will be notified + // when a new frame becomes available. + void setFrameAvailableListener(const sp<FrameAvailableListener>& listener); + + sp<ISurfaceTexture> getProducerInterface() const { return mBufferQueue; } + protected: + + // Implementation of the BufferQueue::ConsumerListener interface. These + // calls are used to notify the CpuConsumer of asynchronous events in the + // BufferQueue. + virtual void onFrameAvailable(); + virtual void onBuffersReleased(); + + private: + // Free local buffer state + status_t freeBufferLocked(int buf); + + // Maximum number of buffers that can be locked at a time + uint32_t mMaxLockedBuffers; + + // mName is a string used to identify the SurfaceTexture in log messages. + // It can be set by the setName method. + String8 mName; + + // mFrameAvailableListener is the listener object that will be called when a + // new frame becomes available. If it is not NULL it will be called from + // queueBuffer. + sp<FrameAvailableListener> mFrameAvailableListener; + + // Underlying buffer queue + sp<BufferQueue> mBufferQueue; + + // Array for caching buffers from the buffer queue + sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS]; + // Array for tracking pointers passed to the consumer, matching the + // mBufferSlot indexing + void *mBufferPointers[BufferQueue::NUM_BUFFER_SLOTS]; + // Count of currently locked buffers + uint32_t mCurrentLockedBuffers; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of CpuConsumer objects. It must be locked whenever the + // member variables are accessed. + mutable Mutex mMutex; +}; + +} // namespace android + +#endif // ANDROID_GUI_CPUCONSUMER_H |