summaryrefslogtreecommitdiffstats
path: root/widget/gonk/nativewindow/GonkConsumerBaseLL.h
diff options
context:
space:
mode:
Diffstat (limited to 'widget/gonk/nativewindow/GonkConsumerBaseLL.h')
-rw-r--r--widget/gonk/nativewindow/GonkConsumerBaseLL.h245
1 files changed, 245 insertions, 0 deletions
diff --git a/widget/gonk/nativewindow/GonkConsumerBaseLL.h b/widget/gonk/nativewindow/GonkConsumerBaseLL.h
new file mode 100644
index 000000000..0b2c2d166
--- /dev/null
+++ b/widget/gonk/nativewindow/GonkConsumerBaseLL.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2014 Mozilla Foundation
+ *
+ * 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 NATIVEWINDOW_GONKCONSUMERBASE_LL_H
+#define NATIVEWINDOW_GONKCONSUMERBASE_LL_H
+
+#include <ui/GraphicBuffer.h>
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+#include <gui/IConsumerListener.h>
+
+#include "GonkBufferQueueLL.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class String8;
+
+// GonkConsumerBase is a base class for GonkBufferQueue consumer end-points. It
+// handles common tasks like management of the connection to the GonkBufferQueue
+// and the buffer pool.
+class GonkConsumerBase : public virtual RefBase,
+ protected ConsumerListener {
+public:
+ struct FrameAvailableListener : public virtual RefBase {
+ // onFrameAvailable() is called 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;
+ };
+
+ virtual ~GonkConsumerBase();
+
+ // abandon frees all the buffers and puts the GonkConsumerBase into the
+ // 'abandoned' state. Once put in this state the GonkConsumerBase can never
+ // leave it. When in the 'abandoned' state, all methods of the
+ // IGraphicBufferProducer interface will fail with the NO_INIT error.
+ //
+ // Note that while calling this method causes all the buffers to be freed
+ // from the perspective of the the GonkConsumerBase, if there are additional
+ // references on the buffers (e.g. if a buffer is referenced by a client
+ // or by OpenGL ES as a texture) then those buffer will remain allocated.
+ void abandon();
+
+ // set the name of the GonkConsumerBase that will be used to identify it in
+ // log messages.
+ void setName(const String8& name);
+
+ // dump writes the current state to a string. Child classes should add
+ // their state to the dump by overriding the dumpLocked method, which is
+ // called by these methods after locking the mutex.
+ void dump(String8& result) const;
+ void dump(String8& result, const char* prefix) const;
+
+ // setFrameAvailableListener sets the listener object that will be notified
+ // when a new frame becomes available.
+ void setFrameAvailableListener(const wp<FrameAvailableListener>& listener);
+
+private:
+ GonkConsumerBase(const GonkConsumerBase&);
+ void operator=(const GonkConsumerBase&);
+
+protected:
+ // GonkConsumerBase constructs a new GonkConsumerBase object to consume image
+ // buffers from the given IGonkGraphicBufferConsumer.
+ // The controlledByApp flag indicates that this consumer is under the application's
+ // control.
+ GonkConsumerBase(const sp<IGonkGraphicBufferConsumer>& consumer, bool controlledByApp = false);
+
+ // onLastStrongRef gets called by RefBase just before the dtor of the most
+ // derived class. It is used to clean up the buffers so that GonkConsumerBase
+ // can coordinate the clean-up by calling into virtual methods implemented
+ // by the derived classes. This would not be possible from the
+ // ConsuemrBase dtor because by the time that gets called the derived
+ // classes have already been destructed.
+ //
+ // This methods should not need to be overridden by derived classes, but
+ // if they are overridden the GonkConsumerBase implementation must be called
+ // from the derived class.
+ virtual void onLastStrongRef(const void* id);
+
+ // Implementation of the IConsumerListener interface. These
+ // calls are used to notify the GonkConsumerBase of asynchronous events in the
+ // GonkBufferQueue. The onFrameAvailable and onBuffersReleased methods should
+ // not need to be overridden by derived classes, but if they are overridden
+ // the GonkConsumerBase implementation must be called from the derived class.
+ // The GonkConsumerBase version of onSidebandStreamChanged does nothing and can
+ // be overriden by derived classes if they want the notification.
+#if ANDROID_VERSION == 21
+ virtual void onFrameAvailable();
+#else
+ virtual void onFrameAvailable(const ::android::BufferItem& item);
+ virtual void onFrameReplaced(const ::android::BufferItem& item) {};
+#endif
+ virtual void onBuffersReleased();
+ virtual void onSidebandStreamChanged();
+
+ // freeBufferLocked frees up the given buffer slot. If the slot has been
+ // initialized this will release the reference to the GraphicBuffer in that
+ // slot. Otherwise it has no effect.
+ //
+ // Derived classes should override this method to clean up any state they
+ // keep per slot. If it is overridden, the derived class's implementation
+ // must call GonkConsumerBase::freeBufferLocked.
+ //
+ // This method must be called with mMutex locked.
+ virtual void freeBufferLocked(int slotIndex);
+
+ // abandonLocked puts the GonkBufferQueue into the abandoned state, causing
+ // all future operations on it to fail. This method rather than the public
+ // abandon method should be overridden by child classes to add abandon-
+ // time behavior.
+ //
+ // Derived classes should override this method to clean up any object
+ // state they keep (as opposed to per-slot state). If it is overridden,
+ // the derived class's implementation must call GonkConsumerBase::abandonLocked.
+ //
+ // This method must be called with mMutex locked.
+ virtual void abandonLocked();
+
+ // dumpLocked dumps the current state of the GonkConsumerBase object to the
+ // result string. Each line is prefixed with the string pointed to by the
+ // prefix argument. The buffer argument points to a buffer that may be
+ // used for intermediate formatting data, and the size of that buffer is
+ // indicated by the size argument.
+ //
+ // Derived classes should override this method to dump their internal
+ // state. If this method is overridden the derived class's implementation
+ // should call GonkConsumerBase::dumpLocked.
+ //
+ // This method must be called with mMutex locked.
+ virtual void dumpLocked(String8& result, const char* prefix) const;
+
+ // acquireBufferLocked fetches the next buffer from the GonkBufferQueue and
+ // updates the buffer slot for the buffer returned.
+ //
+ // Derived classes should override this method to perform any
+ // initialization that must take place the first time a buffer is assigned
+ // to a slot. If it is overridden the derived class's implementation must
+ // call GonkConsumerBase::acquireBufferLocked.
+ virtual status_t acquireBufferLocked(IGonkGraphicBufferConsumer::BufferItem *item,
+ nsecs_t presentWhen);
+
+ // releaseBufferLocked relinquishes control over a buffer, returning that
+ // control to the GonkBufferQueue.
+ //
+ // Derived classes should override this method to perform any cleanup that
+ // must take place when a buffer is released back to the GonkBufferQueue. If
+ // it is overridden the derived class's implementation must call
+ // GonkConsumerBase::releaseBufferLocked.
+ virtual status_t releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer);
+
+ // returns true iff the slot still has the graphicBuffer in it.
+ bool stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer);
+
+ // addReleaseFence* adds the sync points associated with a fence to the set
+ // of sync points that must be reached before the buffer in the given slot
+ // may be used after the slot has been released. This should be called by
+ // derived classes each time some asynchronous work is kicked off that
+ // references the buffer.
+ status_t addReleaseFence(int slot,
+ const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence);
+ status_t addReleaseFenceLocked(int slot,
+ const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence);
+
+ // Slot contains the information and object references that
+ // GonkConsumerBase maintains about a GonkBufferQueue buffer slot.
+ struct Slot {
+ // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if
+ // no Gralloc buffer is in the slot.
+ sp<GraphicBuffer> mGraphicBuffer;
+
+ // mFence is a fence which will signal when the buffer associated with
+ // this buffer slot is no longer being used by the consumer and can be
+ // overwritten. The buffer can be dequeued before the fence signals;
+ // the producer is responsible for delaying writes until it signals.
+ sp<Fence> mFence;
+
+ // the frame number of the last acquired frame for this slot
+ uint64_t mFrameNumber;
+ };
+
+ // mSlots stores the buffers that have been allocated by the GonkBufferQueue
+ // for each buffer slot. It is initialized to null pointers, and gets
+ // filled in with the result of GonkBufferQueue::acquire when the
+ // client dequeues a buffer from a
+ // slot that has not yet been used. The buffer allocated to a slot will also
+ // be replaced if the requested buffer usage or geometry differs from that
+ // of the buffer allocated to a slot.
+ Slot mSlots[GonkBufferQueue::NUM_BUFFER_SLOTS];
+
+ // mAbandoned indicates that the GonkBufferQueue will no longer be used to
+ // consume images buffers pushed to it using the IGraphicBufferProducer
+ // interface. It is initialized to false, and set to true in the abandon
+ // method. A GonkBufferQueue that has been abandoned will return the NO_INIT
+ // error from all IConsumerBase methods capable of returning an error.
+ bool mAbandoned;
+
+ // mName is a string used to identify the GonkConsumerBase 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.
+ wp<FrameAvailableListener> mFrameAvailableListener;
+
+ // The GonkConsumerBase has-a GonkBufferQueue and is responsible for creating this object
+ // if none is supplied
+ sp<IGonkGraphicBufferConsumer> mConsumer;
+
+ // mMutex is the mutex used to prevent concurrent access to the member
+ // variables of GonkConsumerBase objects. It must be locked whenever the
+ // member variables are accessed or when any of the *Locked methods are
+ // called.
+ //
+ // This mutex is intended to be locked by derived classes.
+ mutable Mutex mMutex;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // NATIVEWINDOW_GONKCONSUMERBASE_LL_H