summaryrefslogtreecommitdiffstats
path: root/include/gui
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2012-04-16 17:54:33 -0700
committerEino-Ville Talvala <etalvala@google.com>2012-05-14 18:04:01 -0700
commite41b318bc4708e1dee9364e73215ff0d51fb76a1 (patch)
tree89c3d100e1d08cc687f77221721aac6e3a175e01 /include/gui
parentd58ae6f59483f986d693021f5895d6230af05d99 (diff)
downloadframeworks_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.h5
-rw-r--r--include/gui/CpuConsumer.h142
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