|
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 */ |
|
17 |
|
18 #ifndef NATIVEWINDOW_GONKCONSUMERBASE_JB_H |
|
19 #define NATIVEWINDOW_GONKCONSUMERBASE_JB_H |
|
20 |
|
21 #include <ui/GraphicBuffer.h> |
|
22 |
|
23 #include <utils/String8.h> |
|
24 #include <utils/Vector.h> |
|
25 #include <utils/threads.h> |
|
26 |
|
27 #include "GonkBufferQueueJB.h" |
|
28 |
|
29 namespace android { |
|
30 // ---------------------------------------------------------------------------- |
|
31 |
|
32 class String8; |
|
33 |
|
34 // GonkConsumerBase is a base class for GonkBufferQueue consumer end-points. It |
|
35 // handles common tasks like management of the connection to the GonkBufferQueue |
|
36 // and the buffer pool. |
|
37 class GonkConsumerBase : public virtual RefBase, |
|
38 protected GonkBufferQueue::ConsumerListener { |
|
39 public: |
|
40 struct FrameAvailableListener : public virtual RefBase { |
|
41 // onFrameAvailable() is called each time an additional frame becomes |
|
42 // available for consumption. This means that frames that are queued |
|
43 // while in asynchronous mode only trigger the callback if no previous |
|
44 // frames are pending. Frames queued while in synchronous mode always |
|
45 // trigger the callback. |
|
46 // |
|
47 // This is called without any lock held and can be called concurrently |
|
48 // by multiple threads. |
|
49 virtual void onFrameAvailable() = 0; |
|
50 }; |
|
51 |
|
52 virtual ~GonkConsumerBase(); |
|
53 |
|
54 // abandon frees all the buffers and puts the GonkConsumerBase into the |
|
55 // 'abandoned' state. Once put in this state the GonkConsumerBase can never |
|
56 // leave it. When in the 'abandoned' state, all methods of the |
|
57 // IGraphicBufferProducer interface will fail with the NO_INIT error. |
|
58 // |
|
59 // Note that while calling this method causes all the buffers to be freed |
|
60 // from the perspective of the the GonkConsumerBase, if there are additional |
|
61 // references on the buffers (e.g. if a buffer is referenced by a client |
|
62 // or by OpenGL ES as a texture) then those buffer will remain allocated. |
|
63 void abandon(); |
|
64 |
|
65 // set the name of the GonkConsumerBase that will be used to identify it in |
|
66 // log messages. |
|
67 void setName(const String8& name); |
|
68 |
|
69 // getBufferQueue returns the GonkBufferQueue object to which this |
|
70 // GonkConsumerBase is connected. |
|
71 sp<GonkBufferQueue> getBufferQueue() const; |
|
72 |
|
73 // dump writes the current state to a string. Child classes should add |
|
74 // their state to the dump by overriding the dumpLocked method, which is |
|
75 // called by these methods after locking the mutex. |
|
76 void dump(String8& result) const; |
|
77 void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const; |
|
78 |
|
79 // setFrameAvailableListener sets the listener object that will be notified |
|
80 // when a new frame becomes available. |
|
81 #if ANDROID_VERSION == 17 |
|
82 void setFrameAvailableListener(const sp<FrameAvailableListener>& listener); |
|
83 #else |
|
84 void setFrameAvailableListener(const wp<FrameAvailableListener>& listener); |
|
85 #endif |
|
86 |
|
87 private: |
|
88 GonkConsumerBase(const GonkConsumerBase&); |
|
89 void operator=(const GonkConsumerBase&); |
|
90 |
|
91 protected: |
|
92 |
|
93 // GonkConsumerBase constructs a new GonkConsumerBase object to consume image |
|
94 // buffers from the given GonkBufferQueue. |
|
95 GonkConsumerBase(const sp<GonkBufferQueue> &bufferQueue); |
|
96 |
|
97 // onLastStrongRef gets called by RefBase just before the dtor of the most |
|
98 // derived class. It is used to clean up the buffers so that GonkConsumerBase |
|
99 // can coordinate the clean-up by calling into virtual methods implemented |
|
100 // by the derived classes. This would not be possible from the |
|
101 // ConsuemrBase dtor because by the time that gets called the derived |
|
102 // classes have already been destructed. |
|
103 // |
|
104 // This methods should not need to be overridden by derived classes, but |
|
105 // if they are overridden the GonkConsumerBase implementation must be called |
|
106 // from the derived class. |
|
107 virtual void onLastStrongRef(const void* id); |
|
108 |
|
109 // Implementation of the GonkBufferQueue::ConsumerListener interface. These |
|
110 // calls are used to notify the GonkConsumerBase of asynchronous events in the |
|
111 // GonkBufferQueue. These methods should not need to be overridden by derived |
|
112 // classes, but if they are overridden the GonkConsumerBase implementation |
|
113 // must be called from the derived class. |
|
114 virtual void onFrameAvailable(); |
|
115 virtual void onBuffersReleased(); |
|
116 |
|
117 // freeBufferLocked frees up the given buffer slot. If the slot has been |
|
118 // initialized this will release the reference to the GraphicBuffer in that |
|
119 // slot. Otherwise it has no effect. |
|
120 // |
|
121 // Derived classes should override this method to clean up any state they |
|
122 // keep per slot. If it is overridden, the derived class's implementation |
|
123 // must call GonkConsumerBase::freeBufferLocked. |
|
124 // |
|
125 // This method must be called with mMutex locked. |
|
126 virtual void freeBufferLocked(int slotIndex); |
|
127 |
|
128 // abandonLocked puts the GonkBufferQueue into the abandoned state, causing |
|
129 // all future operations on it to fail. This method rather than the public |
|
130 // abandon method should be overridden by child classes to add abandon- |
|
131 // time behavior. |
|
132 // |
|
133 // Derived classes should override this method to clean up any object |
|
134 // state they keep (as opposed to per-slot state). If it is overridden, |
|
135 // the derived class's implementation must call GonkConsumerBase::abandonLocked. |
|
136 // |
|
137 // This method must be called with mMutex locked. |
|
138 virtual void abandonLocked(); |
|
139 |
|
140 // dumpLocked dumps the current state of the GonkConsumerBase object to the |
|
141 // result string. Each line is prefixed with the string pointed to by the |
|
142 // prefix argument. The buffer argument points to a buffer that may be |
|
143 // used for intermediate formatting data, and the size of that buffer is |
|
144 // indicated by the size argument. |
|
145 // |
|
146 // Derived classes should override this method to dump their internal |
|
147 // state. If this method is overridden the derived class's implementation |
|
148 // should call GonkConsumerBase::dumpLocked. |
|
149 // |
|
150 // This method must be called with mMutex locked. |
|
151 virtual void dumpLocked(String8& result, const char* prefix, char* buffer, |
|
152 size_t size) const; |
|
153 |
|
154 // acquireBufferLocked fetches the next buffer from the GonkBufferQueue and |
|
155 // updates the buffer slot for the buffer returned. |
|
156 // |
|
157 // Derived classes should override this method to perform any |
|
158 // initialization that must take place the first time a buffer is assigned |
|
159 // to a slot. If it is overridden the derived class's implementation must |
|
160 // call GonkConsumerBase::acquireBufferLocked. |
|
161 virtual status_t acquireBufferLocked(GonkBufferQueue::BufferItem *item); |
|
162 |
|
163 // releaseBufferLocked relinquishes control over a buffer, returning that |
|
164 // control to the GonkBufferQueue. |
|
165 // |
|
166 // Derived classes should override this method to perform any cleanup that |
|
167 // must take place when a buffer is released back to the GonkBufferQueue. If |
|
168 // it is overridden the derived class's implementation must call |
|
169 // GonkConsumerBase::releaseBufferLocked. |
|
170 virtual status_t releaseBufferLocked(int buf); |
|
171 |
|
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, const sp<Fence>& fence); |
|
178 status_t addReleaseFenceLocked(int slot, const sp<Fence>& fence); |
|
179 |
|
180 // Slot contains the information and object references that |
|
181 // GonkConsumerBase maintains about a GonkBufferQueue buffer slot. |
|
182 struct Slot { |
|
183 // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if |
|
184 // no Gralloc buffer is in the slot. |
|
185 sp<GraphicBuffer> mGraphicBuffer; |
|
186 |
|
187 // mFence is a fence which will signal when the buffer associated with |
|
188 // this buffer slot is no longer being used by the consumer and can be |
|
189 // overwritten. The buffer can be dequeued before the fence signals; |
|
190 // the producer is responsible for delaying writes until it signals. |
|
191 sp<Fence> mFence; |
|
192 }; |
|
193 |
|
194 // mSlots stores the buffers that have been allocated by the GonkBufferQueue |
|
195 // for each buffer slot. It is initialized to null pointers, and gets |
|
196 // filled in with the result of GonkBufferQueue::acquire when the |
|
197 // client dequeues a buffer from a |
|
198 // slot that has not yet been used. The buffer allocated to a slot will also |
|
199 // be replaced if the requested buffer usage or geometry differs from that |
|
200 // of the buffer allocated to a slot. |
|
201 Slot mSlots[GonkBufferQueue::NUM_BUFFER_SLOTS]; |
|
202 |
|
203 // mAbandoned indicates that the GonkBufferQueue will no longer be used to |
|
204 // consume images buffers pushed to it using the IGraphicBufferProducer |
|
205 // interface. It is initialized to false, and set to true in the abandon |
|
206 // method. A GonkBufferQueue that has been abandoned will return the NO_INIT |
|
207 // error from all IGonkConsumerBase methods capable of returning an error. |
|
208 bool mAbandoned; |
|
209 |
|
210 // mName is a string used to identify the GonkConsumerBase in log messages. |
|
211 // It can be set by the setName method. |
|
212 String8 mName; |
|
213 |
|
214 // mFrameAvailableListener is the listener object that will be called when a |
|
215 // new frame becomes available. If it is not NULL it will be called from |
|
216 // queueBuffer. |
|
217 #if ANDROID_VERSION == 17 |
|
218 sp<FrameAvailableListener> mFrameAvailableListener; |
|
219 #else |
|
220 wp<FrameAvailableListener> mFrameAvailableListener; |
|
221 #endif |
|
222 |
|
223 // The GonkConsumerBase has-a GonkBufferQueue and is responsible for creating this object |
|
224 // if none is supplied |
|
225 sp<GonkBufferQueue> mBufferQueue; |
|
226 |
|
227 // mMutex is the mutex used to prevent concurrent access to the member |
|
228 // variables of GonkConsumerBase objects. It must be locked whenever the |
|
229 // member variables are accessed or when any of the *Locked methods are |
|
230 // called. |
|
231 // |
|
232 // This mutex is intended to be locked by derived classes. |
|
233 mutable Mutex mMutex; |
|
234 }; |
|
235 |
|
236 // ---------------------------------------------------------------------------- |
|
237 }; // namespace android |
|
238 |
|
239 #endif // NATIVEWINDOW_GONKCONSUMERBASE_H |