|
1 /* |
|
2 * Copyright (C) 2010 The Android Open Source Project |
|
3 * Copyright (C) 2012 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_GONKNATIVEWINDOW_ICS_H |
|
19 #define NATIVEWINDOW_GONKNATIVEWINDOW_ICS_H |
|
20 |
|
21 #include <stdint.h> |
|
22 #include <sys/types.h> |
|
23 |
|
24 #include <gui/ISurfaceTexture.h> |
|
25 #include <ui/egl/android_natives.h> |
|
26 #include <ui/GraphicBuffer.h> |
|
27 #include <ui/Rect.h> |
|
28 #include <utils/Errors.h> |
|
29 #include <utils/RefBase.h> |
|
30 #include <utils/String8.h> |
|
31 #include <utils/threads.h> |
|
32 |
|
33 #include "CameraCommon.h" |
|
34 #include "GrallocImages.h" |
|
35 #include "mozilla/layers/LayersSurfaces.h" |
|
36 #include "mozilla/layers/TextureClient.h" |
|
37 |
|
38 namespace android { |
|
39 |
|
40 // The user of GonkNativeWindow who wants to receive notification of |
|
41 // new frames should implement this interface. |
|
42 class GonkNativeWindowNewFrameCallback { |
|
43 public: |
|
44 virtual void OnNewFrame() = 0; |
|
45 }; |
|
46 |
|
47 class GonkNativeWindow : public BnSurfaceTexture |
|
48 { |
|
49 friend class GonkNativeWindowClient; |
|
50 |
|
51 typedef mozilla::layers::TextureClient TextureClient; |
|
52 |
|
53 public: |
|
54 enum { MIN_UNDEQUEUED_BUFFERS = 2 }; |
|
55 enum { MIN_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS }; |
|
56 enum { NUM_BUFFER_SLOTS = 32 }; |
|
57 enum { NO_CONNECTED_API = 0 }; |
|
58 enum { NATIVE_WINDOW_SET_BUFFERS_SIZE = 0x10000000 }; |
|
59 |
|
60 GonkNativeWindow(); |
|
61 ~GonkNativeWindow(); // this class cannot be overloaded |
|
62 |
|
63 // Get next frame from the queue and mark it as RENDERING, caller |
|
64 // owns the returned buffer. |
|
65 mozilla::TemporaryRef<TextureClient> getCurrentBuffer(); |
|
66 |
|
67 // Return the buffer to the queue and mark it as FREE. After that |
|
68 // the buffer is useable again for the decoder. |
|
69 void returnBuffer(TextureClient* client); |
|
70 |
|
71 // setBufferCount updates the number of available buffer slots. After |
|
72 // calling this all buffer slots are owned by the GonkNativeWindow object |
|
73 // (i.e. they are not owned by the client). |
|
74 virtual status_t setBufferCount(int bufferCount); |
|
75 |
|
76 // requestBuffer requests a new buffer for the given index. |
|
77 virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf); |
|
78 |
|
79 // dequeueBuffer gets the next buffer slot index for the client to use. If a |
|
80 // buffer slot is available then that slot index is written to the location |
|
81 // pointed to by the buf argument and a status of OK is returned. If no |
|
82 // slot is available then a status of -EBUSY is returned and buf is |
|
83 // unmodified. |
|
84 virtual status_t dequeueBuffer(int *buf, uint32_t width, uint32_t height, |
|
85 uint32_t format, uint32_t usage); |
|
86 |
|
87 // queueBuffer returns a filled buffer to the GonkNativeWindow. In addition, |
|
88 // a timestamp must be provided for the buffer. The timestamp is in |
|
89 // nanoseconds, and must be monotonically increasing. Its other semantics |
|
90 // (zero point, etc) are client-dependent and should be documented by the |
|
91 // client. |
|
92 virtual status_t queueBuffer(int buf, int64_t timestamp, |
|
93 uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform); |
|
94 virtual void cancelBuffer(int buf); |
|
95 virtual status_t setCrop(const Rect& reg); |
|
96 virtual status_t setTransform(uint32_t transform); |
|
97 virtual status_t setScalingMode(int mode); |
|
98 |
|
99 virtual int query(int what, int* value); |
|
100 |
|
101 // Qcom specific function |
|
102 virtual int performQcomOperation(int operation, int arg1, int arg2, int arg3) { |
|
103 return OK; |
|
104 } |
|
105 |
|
106 // GonkNativeWindow do not implement the function and always works in |
|
107 // synchronous mode. |
|
108 virtual status_t setSynchronousMode(bool enabled); |
|
109 |
|
110 // connect attempts to connect a client API to the GonkNativeWindow. |
|
111 // |
|
112 // This method will fail if the connect was previously called on the |
|
113 // GonkNativeWindow and no corresponding disconnect call was made. |
|
114 virtual status_t connect(int api, |
|
115 uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform); |
|
116 |
|
117 // disconnect attempts to disconnect a client API from the GonkNativeWindow. |
|
118 // This method will fail if the the GonkNativeWindow is not currently |
|
119 // connected to the specified client API. |
|
120 virtual status_t disconnect(int api); |
|
121 |
|
122 void setNewFrameCallback(GonkNativeWindowNewFrameCallback* aCallback); |
|
123 |
|
124 // setDefaultBufferSize is used to set the size of buffers returned by |
|
125 // requestBuffers when a with and height of zero is requested. |
|
126 // A call to setDefaultBufferSize() may trigger requestBuffers() to |
|
127 // be called from the client. |
|
128 status_t setDefaultBufferSize(uint32_t width, uint32_t height); |
|
129 |
|
130 // abandon frees all the buffers and puts the GonkNativeWindow into the |
|
131 // 'abandoned' state. Once put in this state the GonkNativeWindow can never |
|
132 // leave it. When in the 'abandoned' state, all methods of the |
|
133 // ISurfaceTexture interface will fail with the NO_INIT error. |
|
134 // |
|
135 // Note that while calling this method causes all the buffers to be freed |
|
136 // from the perspective of the the GonkNativeWindow, if there are additional |
|
137 // references on the buffers (e.g. if a buffer is referenced by a client) |
|
138 // then those buffer will remain allocated. |
|
139 void abandon(); |
|
140 |
|
141 mozilla::TemporaryRef<TextureClient> getTextureClientFromBuffer(ANativeWindowBuffer* buffer); |
|
142 |
|
143 static void RecycleCallback(TextureClient* client, void* closure); |
|
144 |
|
145 protected: |
|
146 |
|
147 // freeAllBuffersLocked frees the resources (both GraphicBuffer and |
|
148 // EGLImage) for all slots by removing them from the slots and appending |
|
149 // then to the freeList. This must be called with mMutex locked. |
|
150 void freeAllBuffersLocked(); |
|
151 |
|
152 // clearRenderingStateBuffersLocked clear the resources in RENDERING state; |
|
153 // But do not destroy the gralloc buffer. It is still in the video stream |
|
154 // awaiting rendering. |
|
155 // this must be called with mMutex locked. |
|
156 void clearRenderingStateBuffersLocked(); |
|
157 |
|
158 private: |
|
159 void init(); |
|
160 |
|
161 int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; |
|
162 |
|
163 int getSlotFromTextureClientLocked(TextureClient* client) const; |
|
164 |
|
165 enum { INVALID_BUFFER_SLOT = -1 }; |
|
166 |
|
167 struct BufferSlot { |
|
168 |
|
169 BufferSlot() |
|
170 : mBufferState(BufferSlot::FREE), |
|
171 mTimestamp(0), |
|
172 mFrameNumber(0){ |
|
173 } |
|
174 |
|
175 // mGraphicBuffer points to the buffer allocated for this slot or is NULL |
|
176 // if no buffer has been allocated. |
|
177 sp<GraphicBuffer> mGraphicBuffer; |
|
178 |
|
179 // mTextureClient is a thin abstraction over remotely allocated GraphicBuffer. |
|
180 mozilla::RefPtr<TextureClient> mTextureClient; |
|
181 |
|
182 // BufferState represents the different states in which a buffer slot |
|
183 // can be. |
|
184 enum BufferState { |
|
185 // FREE indicates that the buffer is not currently being used and |
|
186 // will not be used in the future until it gets dequeued and |
|
187 // subsequently queued by the client. |
|
188 FREE = 0, |
|
189 |
|
190 // DEQUEUED indicates that the buffer has been dequeued by the |
|
191 // client, but has not yet been queued or canceled. The buffer is |
|
192 // considered 'owned' by the client, and the server should not use |
|
193 // it for anything. |
|
194 // |
|
195 // Note that when in synchronous-mode (mSynchronousMode == true), |
|
196 // the buffer that's currently attached to the texture may be |
|
197 // dequeued by the client. That means that the current buffer can |
|
198 // be in either the DEQUEUED or QUEUED state. In asynchronous mode, |
|
199 // however, the current buffer is always in the QUEUED state. |
|
200 DEQUEUED = 1, |
|
201 |
|
202 // QUEUED indicates that the buffer has been queued by the client, |
|
203 // and has not since been made available for the client to dequeue. |
|
204 // Attaching the buffer to the texture does NOT transition the |
|
205 // buffer away from the QUEUED state. However, in Synchronous mode |
|
206 // the current buffer may be dequeued by the client under some |
|
207 // circumstances. See the note about the current buffer in the |
|
208 // documentation for DEQUEUED. |
|
209 QUEUED = 2, |
|
210 |
|
211 // RENDERING indicates that the buffer has been sent to |
|
212 // the compositor, and has not yet available for the |
|
213 // client to dequeue. When the compositor has finished its |
|
214 // job, the buffer will be returned to FREE state. |
|
215 RENDERING = 3, |
|
216 }; |
|
217 |
|
218 // mBufferState is the current state of this buffer slot. |
|
219 BufferState mBufferState; |
|
220 |
|
221 // mRequestBufferCalled is used for validating that the client did |
|
222 // call requestBuffer() when told to do so. Technically this is not |
|
223 // needed but useful for debugging and catching client bugs. |
|
224 bool mRequestBufferCalled; |
|
225 |
|
226 // mTimestamp is the current timestamp for this buffer slot. This gets |
|
227 // to set by queueBuffer each time this slot is queued. |
|
228 int64_t mTimestamp; |
|
229 |
|
230 // mFrameNumber is the number of the queued frame for this slot. |
|
231 uint64_t mFrameNumber; |
|
232 }; |
|
233 |
|
234 // mSlots is the array of buffer slots that must be mirrored on the client |
|
235 // side. This allows buffer ownership to be transferred between the client |
|
236 // and server without sending a GraphicBuffer over binder. The entire array |
|
237 // is initialized to NULL at construction time, and buffers are allocated |
|
238 // for a slot when requestBuffer is called with that slot's index. |
|
239 BufferSlot mSlots[NUM_BUFFER_SLOTS]; |
|
240 |
|
241 // mDequeueCondition condition used for dequeueBuffer in synchronous mode |
|
242 mutable Condition mDequeueCondition; |
|
243 |
|
244 // mAbandoned indicates that the GonkNativeWindow will no longer be used to |
|
245 // consume buffers pushed to it. |
|
246 // It is initialized to false, and set to true in the abandon method. A |
|
247 // GonkNativeWindow that has been abandoned will return the NO_INIT error |
|
248 // from all control methods capable of returning an error. |
|
249 bool mAbandoned; |
|
250 |
|
251 // mTimestamp is the timestamp that will be used for the next buffer queue |
|
252 // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that |
|
253 // a timestamp is auto-generated when queueBuffer is called. |
|
254 int64_t mTimestamp; |
|
255 |
|
256 // mDefaultWidth holds the default width of allocated buffers. It is used |
|
257 // in requestBuffers() if a width and height of zero is specified. |
|
258 uint32_t mDefaultWidth; |
|
259 |
|
260 // mDefaultHeight holds the default height of allocated buffers. It is used |
|
261 // in requestBuffers() if a width and height of zero is specified. |
|
262 uint32_t mDefaultHeight; |
|
263 |
|
264 // mPixelFormat holds the pixel format of allocated buffers. It is used |
|
265 // in requestBuffers() if a format of zero is specified. |
|
266 uint32_t mPixelFormat; |
|
267 |
|
268 // mBufferCount is the number of buffer slots that the client and server |
|
269 // must maintain. It defaults to MIN_BUFFER_SLOTS + 1 and can be changed |
|
270 // by calling setBufferCount or setBufferCountServer |
|
271 int mBufferCount; |
|
272 |
|
273 // mConnectedApi indicates the API that is currently connected to this |
|
274 // GonkNativeWindow. It defaults to NO_CONNECTED_API (= 0), and gets updated |
|
275 // by the connect and disconnect methods. |
|
276 int mConnectedApi; |
|
277 |
|
278 // mQueue is a FIFO of queued buffers used in synchronous mode |
|
279 // GonkNativeWindow always works in synchronous mode |
|
280 typedef Vector<int> Fifo; |
|
281 Fifo mQueue; |
|
282 |
|
283 // mMutex is the mutex used to prevent concurrent access to the member |
|
284 // variables of GonkNativeWindow objects. It must be locked whenever the |
|
285 // member variables are accessed. |
|
286 mutable Mutex mMutex; |
|
287 |
|
288 // mFrameCounter is the free running counter, incremented for every buffer queued |
|
289 uint64_t mFrameCounter; |
|
290 |
|
291 GonkNativeWindowNewFrameCallback* mNewFrameCallback; |
|
292 }; |
|
293 |
|
294 }; // namespace android |
|
295 |
|
296 #endif // NATIVEWINDOW_GONKNATIVEWINDOW_ICS_H |