Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2013 Mozilla Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
18 #ifndef NATIVEWINDOW_GONKCONSUMERBASE_KK_H
19 #define NATIVEWINDOW_GONKCONSUMERBASE_KK_H
21 #include <ui/GraphicBuffer.h>
23 #include <utils/String8.h>
24 #include <utils/Vector.h>
25 #include <utils/threads.h>
26 #include <gui/IConsumerListener.h>
28 #include "GonkBufferQueueKK.h"
30 namespace android {
31 // ----------------------------------------------------------------------------
33 class String8;
35 // GonkConsumerBase is a base class for GonkBufferQueue consumer end-points. It
36 // handles common tasks like management of the connection to the GonkBufferQueue
37 // and the buffer pool.
38 class GonkConsumerBase : public virtual RefBase,
39 protected ConsumerListener {
40 public:
41 struct FrameAvailableListener : public virtual RefBase {
42 // onFrameAvailable() is called each time an additional frame becomes
43 // available for consumption. This means that frames that are queued
44 // while in asynchronous mode only trigger the callback if no previous
45 // frames are pending. Frames queued while in synchronous mode always
46 // trigger the callback.
47 //
48 // This is called without any lock held and can be called concurrently
49 // by multiple threads.
50 virtual void onFrameAvailable() = 0;
51 };
53 virtual ~GonkConsumerBase();
55 // abandon frees all the buffers and puts the GonkConsumerBase into the
56 // 'abandoned' state. Once put in this state the GonkConsumerBase can never
57 // leave it. When in the 'abandoned' state, all methods of the
58 // IGraphicBufferProducer interface will fail with the NO_INIT error.
59 //
60 // Note that while calling this method causes all the buffers to be freed
61 // from the perspective of the the GonkConsumerBase, if there are additional
62 // references on the buffers (e.g. if a buffer is referenced by a client
63 // or by OpenGL ES as a texture) then those buffer will remain allocated.
64 void abandon();
66 // set the name of the GonkConsumerBase that will be used to identify it in
67 // log messages.
68 void setName(const String8& name);
70 // getBufferQueue returns the GonkBufferQueue object to which this
71 // GonkConsumerBase is connected.
72 sp<GonkBufferQueue> getBufferQueue() const;
74 // dump writes the current state to a string. Child classes should add
75 // their state to the dump by overriding the dumpLocked method, which is
76 // called by these methods after locking the mutex.
77 void dump(String8& result) const;
78 void dump(String8& result, const char* prefix) const;
80 // setFrameAvailableListener sets the listener object that will be notified
81 // when a new frame becomes available.
82 void setFrameAvailableListener(const wp<FrameAvailableListener>& listener);
84 private:
85 GonkConsumerBase(const GonkConsumerBase&);
86 void operator=(const GonkConsumerBase&);
88 protected:
90 // GonkConsumerBase constructs a new GonkConsumerBase object to consume image
91 // buffers from the given GonkBufferQueue.
92 GonkConsumerBase(const sp<GonkBufferQueue>& bufferQueue, bool controlledByApp = false);
94 // onLastStrongRef gets called by RefBase just before the dtor of the most
95 // derived class. It is used to clean up the buffers so that GonkConsumerBase
96 // can coordinate the clean-up by calling into virtual methods implemented
97 // by the derived classes. This would not be possible from the
98 // ConsuemrBase dtor because by the time that gets called the derived
99 // classes have already been destructed.
100 //
101 // This methods should not need to be overridden by derived classes, but
102 // if they are overridden the GonkConsumerBase implementation must be called
103 // from the derived class.
104 virtual void onLastStrongRef(const void* id);
106 // Implementation of the GonkBufferQueue::ConsumerListener interface. These
107 // calls are used to notify the GonkConsumerBase of asynchronous events in the
108 // GonkBufferQueue. These methods should not need to be overridden by derived
109 // classes, but if they are overridden the GonkConsumerBase implementation
110 // must be called from the derived class.
111 virtual void onFrameAvailable();
112 virtual void onBuffersReleased();
114 // freeBufferLocked frees up the given buffer slot. If the slot has been
115 // initialized this will release the reference to the GraphicBuffer in that
116 // slot. Otherwise it has no effect.
117 //
118 // Derived classes should override this method to clean up any state they
119 // keep per slot. If it is overridden, the derived class's implementation
120 // must call GonkConsumerBase::freeBufferLocked.
121 //
122 // This method must be called with mMutex locked.
123 virtual void freeBufferLocked(int slotIndex);
125 // abandonLocked puts the GonkBufferQueue into the abandoned state, causing
126 // all future operations on it to fail. This method rather than the public
127 // abandon method should be overridden by child classes to add abandon-
128 // time behavior.
129 //
130 // Derived classes should override this method to clean up any object
131 // state they keep (as opposed to per-slot state). If it is overridden,
132 // the derived class's implementation must call GonkConsumerBase::abandonLocked.
133 //
134 // This method must be called with mMutex locked.
135 virtual void abandonLocked();
137 // dumpLocked dumps the current state of the GonkConsumerBase object to the
138 // result string. Each line is prefixed with the string pointed to by the
139 // prefix argument. The buffer argument points to a buffer that may be
140 // used for intermediate formatting data, and the size of that buffer is
141 // indicated by the size argument.
142 //
143 // Derived classes should override this method to dump their internal
144 // state. If this method is overridden the derived class's implementation
145 // should call GonkConsumerBase::dumpLocked.
146 //
147 // This method must be called with mMutex locked.
148 virtual void dumpLocked(String8& result, const char* prefix) const;
150 // acquireBufferLocked fetches the next buffer from the GonkBufferQueue and
151 // updates the buffer slot for the buffer returned.
152 //
153 // Derived classes should override this method to perform any
154 // initialization that must take place the first time a buffer is assigned
155 // to a slot. If it is overridden the derived class's implementation must
156 // call GonkConsumerBase::acquireBufferLocked.
157 virtual status_t acquireBufferLocked(IGonkGraphicBufferConsumer::BufferItem *item,
158 nsecs_t presentWhen);
160 // releaseBufferLocked relinquishes control over a buffer, returning that
161 // control to the GonkBufferQueue.
162 //
163 // Derived classes should override this method to perform any cleanup that
164 // must take place when a buffer is released back to the GonkBufferQueue. If
165 // it is overridden the derived class's implementation must call
166 // GonkConsumerBase::releaseBufferLocked.
167 virtual status_t releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer);
169 // returns true iff the slot still has the graphicBuffer in it.
170 bool stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer);
172 // addReleaseFence* adds the sync points associated with a fence to the set
173 // of sync points that must be reached before the buffer in the given slot
174 // may be used after the slot has been released. This should be called by
175 // derived classes each time some asynchronous work is kicked off that
176 // references the buffer.
177 status_t addReleaseFence(int slot,
178 const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence);
179 status_t addReleaseFenceLocked(int slot,
180 const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence);
182 // Slot contains the information and object references that
183 // GonkConsumerBase maintains about a GonkBufferQueue buffer slot.
184 struct Slot {
185 // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if
186 // no Gralloc buffer is in the slot.
187 sp<GraphicBuffer> mGraphicBuffer;
189 // mFence is a fence which will signal when the buffer associated with
190 // this buffer slot is no longer being used by the consumer and can be
191 // overwritten. The buffer can be dequeued before the fence signals;
192 // the producer is responsible for delaying writes until it signals.
193 sp<Fence> mFence;
195 // the frame number of the last acquired frame for this slot
196 uint64_t mFrameNumber;
197 };
199 // mSlots stores the buffers that have been allocated by the GonkBufferQueue
200 // for each buffer slot. It is initialized to null pointers, and gets
201 // filled in with the result of GonkBufferQueue::acquire when the
202 // client dequeues a buffer from a
203 // slot that has not yet been used. The buffer allocated to a slot will also
204 // be replaced if the requested buffer usage or geometry differs from that
205 // of the buffer allocated to a slot.
206 Slot mSlots[GonkBufferQueue::NUM_BUFFER_SLOTS];
208 // mAbandoned indicates that the GonkBufferQueue will no longer be used to
209 // consume images buffers pushed to it using the IGraphicBufferProducer
210 // interface. It is initialized to false, and set to true in the abandon
211 // method. A GonkBufferQueue that has been abandoned will return the NO_INIT
212 // error from all IGonkConsumerBase methods capable of returning an error.
213 bool mAbandoned;
215 // mName is a string used to identify the GonkConsumerBase in log messages.
216 // It can be set by the setName method.
217 String8 mName;
219 // mFrameAvailableListener is the listener object that will be called when a
220 // new frame becomes available. If it is not NULL it will be called from
221 // queueBuffer.
222 wp<FrameAvailableListener> mFrameAvailableListener;
224 // The GonkConsumerBase has-a GonkBufferQueue and is responsible for creating this object
225 // if none is supplied
226 sp<GonkBufferQueue> mConsumer;
228 // mMutex is the mutex used to prevent concurrent access to the member
229 // variables of GonkConsumerBase objects. It must be locked whenever the
230 // member variables are accessed or when any of the *Locked methods are
231 // called.
232 //
233 // This mutex is intended to be locked by derived classes.
234 mutable Mutex mMutex;
235 };
237 // ----------------------------------------------------------------------------
238 }; // namespace android
240 #endif // NATIVEWINDOW_GONKCONSUMERBASE_H