Skip to content

Commit 1c90e73

Browse files
Jamie GennisAndroid (Google) Code Review
authored andcommitted
Merge "Refactored ISurfaceTexture calls from SurfaceTexture into BufferQueue."
2 parents 0777d2d + 70e80aa commit 1c90e73

File tree

5 files changed

+1072
-966
lines changed

5 files changed

+1072
-966
lines changed

include/gui/BufferQueue.h

Lines changed: 343 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,343 @@
1+
/*
2+
* Copyright (C) 2012 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef ANDROID_GUI_BUFFERQUEUE_H
18+
#define ANDROID_GUI_BUFFERQUEUE_H
19+
20+
#include <EGL/egl.h>
21+
22+
#include <gui/ISurfaceTexture.h>
23+
24+
#include <surfaceflinger/IGraphicBufferAlloc.h>
25+
#include <ui/GraphicBuffer.h>
26+
27+
#include <utils/String8.h>
28+
#include <utils/Vector.h>
29+
#include <utils/threads.h>
30+
31+
namespace android {
32+
// ----------------------------------------------------------------------------
33+
34+
class BufferQueue : public BnSurfaceTexture {
35+
public:
36+
enum { MIN_UNDEQUEUED_BUFFERS = 2 };
37+
enum {
38+
MIN_ASYNC_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS + 1,
39+
MIN_SYNC_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS
40+
};
41+
enum { NUM_BUFFER_SLOTS = 32 };
42+
enum { NO_CONNECTED_API = 0 };
43+
44+
struct FrameAvailableListener : public virtual RefBase {
45+
// onFrameAvailable() is called from queueBuffer() each time an
46+
// additional frame becomes available for consumption. This means that
47+
// frames that are queued while in asynchronous mode only trigger the
48+
// callback if no previous frames are pending. Frames queued while in
49+
// synchronous mode always trigger the callback.
50+
//
51+
// This is called without any lock held and can be called concurrently
52+
// by multiple threads.
53+
virtual void onFrameAvailable() = 0;
54+
};
55+
56+
// BufferQueue manages a pool of gralloc memory slots to be used
57+
// by producers and consumers.
58+
// allowSynchronousMode specifies whether or not synchronous mode can be
59+
// enabled.
60+
BufferQueue(bool allowSynchronousMode = true);
61+
virtual ~BufferQueue();
62+
63+
// setBufferCount updates the number of available buffer slots. After
64+
// calling this all buffer slots are both unallocated and owned by the
65+
// BufferQueue object (i.e. they are not owned by the client).
66+
virtual status_t setBufferCount(int bufferCount);
67+
68+
virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);
69+
70+
// dequeueBuffer gets the next buffer slot index for the client to use. If a
71+
// buffer slot is available then that slot index is written to the location
72+
// pointed to by the buf argument and a status of OK is returned. If no
73+
// slot is available then a status of -EBUSY is returned and buf is
74+
// unmodified.
75+
// The width and height parameters must be no greater than the minimum of
76+
// GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).
77+
// An error due to invalid dimensions might not be reported until
78+
// updateTexImage() is called.
79+
virtual status_t dequeueBuffer(int *buf, uint32_t width, uint32_t height,
80+
uint32_t format, uint32_t usage);
81+
82+
// queueBuffer returns a filled buffer to the BufferQueue. In addition, a
83+
// timestamp must be provided for the buffer. The timestamp is in
84+
// nanoseconds, and must be monotonically increasing. Its other semantics
85+
// (zero point, etc) are client-dependent and should be documented by the
86+
// client.
87+
virtual status_t queueBuffer(int buf, int64_t timestamp,
88+
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
89+
virtual void cancelBuffer(int buf);
90+
virtual status_t setCrop(const Rect& reg);
91+
virtual status_t setTransform(uint32_t transform);
92+
virtual status_t setScalingMode(int mode);
93+
94+
// setSynchronousMode set whether dequeueBuffer is synchronous or
95+
// asynchronous. In synchronous mode, dequeueBuffer blocks until
96+
// a buffer is available, the currently bound buffer can be dequeued and
97+
// queued buffers will be retired in order.
98+
// The default mode is asynchronous.
99+
virtual status_t setSynchronousMode(bool enabled);
100+
101+
// connect attempts to connect a producer client API to the BufferQueue.
102+
// This must be called before any other ISurfaceTexture methods are called
103+
// except for getAllocator.
104+
//
105+
// This method will fail if the connect was previously called on the
106+
// BufferQueue and no corresponding disconnect call was made.
107+
virtual status_t connect(int api,
108+
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
109+
110+
// disconnect attempts to disconnect a producer client API from the
111+
// BufferQueue. Calling this method will cause any subsequent calls to other
112+
// ISurfaceTexture methods to fail except for getAllocator and connect.
113+
// Successfully calling connect after this will allow the other methods to
114+
// succeed again.
115+
//
116+
// This method will fail if the the BufferQueue is not currently
117+
// connected to the specified client API.
118+
virtual status_t disconnect(int api);
119+
120+
protected:
121+
122+
// freeBufferLocked frees the resources (both GraphicBuffer and EGLImage)
123+
// for the given slot.
124+
void freeBufferLocked(int index);
125+
126+
// freeAllBuffersLocked frees the resources (both GraphicBuffer and
127+
// EGLImage) for all slots.
128+
void freeAllBuffersLocked();
129+
130+
// freeAllBuffersExceptHeadLocked frees the resources (both GraphicBuffer
131+
// and EGLImage) for all slots except the head of mQueue
132+
void freeAllBuffersExceptHeadLocked();
133+
134+
// drainQueueLocked drains the buffer queue if we're in synchronous mode
135+
// returns immediately otherwise. It returns NO_INIT if the BufferQueue
136+
// became abandoned or disconnected during this call.
137+
status_t drainQueueLocked();
138+
139+
// drainQueueAndFreeBuffersLocked drains the buffer queue if we're in
140+
// synchronous mode and free all buffers. In asynchronous mode, all buffers
141+
// are freed except the current buffer.
142+
status_t drainQueueAndFreeBuffersLocked();
143+
144+
status_t setBufferCountServerLocked(int bufferCount);
145+
146+
enum { INVALID_BUFFER_SLOT = -1 };
147+
148+
struct BufferSlot {
149+
150+
BufferSlot()
151+
: mEglImage(EGL_NO_IMAGE_KHR),
152+
mEglDisplay(EGL_NO_DISPLAY),
153+
mBufferState(BufferSlot::FREE),
154+
mRequestBufferCalled(false),
155+
mTransform(0),
156+
mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
157+
mTimestamp(0),
158+
mFrameNumber(0),
159+
mFence(EGL_NO_SYNC_KHR) {
160+
mCrop.makeInvalid();
161+
}
162+
163+
// mGraphicBuffer points to the buffer allocated for this slot or is NULL
164+
// if no buffer has been allocated.
165+
sp<GraphicBuffer> mGraphicBuffer;
166+
167+
// mEglImage is the EGLImage created from mGraphicBuffer.
168+
EGLImageKHR mEglImage;
169+
170+
// mEglDisplay is the EGLDisplay used to create mEglImage.
171+
EGLDisplay mEglDisplay;
172+
173+
// BufferState represents the different states in which a buffer slot
174+
// can be.
175+
enum BufferState {
176+
// FREE indicates that the buffer is not currently being used and
177+
// will not be used in the future until it gets dequeued and
178+
// subsequently queued by the client.
179+
FREE = 0,
180+
181+
// DEQUEUED indicates that the buffer has been dequeued by the
182+
// client, but has not yet been queued or canceled. The buffer is
183+
// considered 'owned' by the client, and the server should not use
184+
// it for anything.
185+
//
186+
// Note that when in synchronous-mode (mSynchronousMode == true),
187+
// the buffer that's currently attached to the texture may be
188+
// dequeued by the client. That means that the current buffer can
189+
// be in either the DEQUEUED or QUEUED state. In asynchronous mode,
190+
// however, the current buffer is always in the QUEUED state.
191+
DEQUEUED = 1,
192+
193+
// QUEUED indicates that the buffer has been queued by the client,
194+
// and has not since been made available for the client to dequeue.
195+
// Attaching the buffer to the texture does NOT transition the
196+
// buffer away from the QUEUED state. However, in Synchronous mode
197+
// the current buffer may be dequeued by the client under some
198+
// circumstances. See the note about the current buffer in the
199+
// documentation for DEQUEUED.
200+
QUEUED = 2,
201+
};
202+
203+
// mBufferState is the current state of this buffer slot.
204+
BufferState mBufferState;
205+
206+
// mRequestBufferCalled is used for validating that the client did
207+
// call requestBuffer() when told to do so. Technically this is not
208+
// needed but useful for debugging and catching client bugs.
209+
bool mRequestBufferCalled;
210+
211+
// mCrop is the current crop rectangle for this buffer slot. This gets
212+
// set to mNextCrop each time queueBuffer gets called for this buffer.
213+
Rect mCrop;
214+
215+
// mTransform is the current transform flags for this buffer slot. This
216+
// gets set to mNextTransform each time queueBuffer gets called for this
217+
// slot.
218+
uint32_t mTransform;
219+
220+
// mScalingMode is the current scaling mode for this buffer slot. This
221+
// gets set to mNextScalingMode each time queueBuffer gets called for
222+
// this slot.
223+
uint32_t mScalingMode;
224+
225+
// mTimestamp is the current timestamp for this buffer slot. This gets
226+
// to set by queueBuffer each time this slot is queued.
227+
int64_t mTimestamp;
228+
229+
// mFrameNumber is the number of the queued frame for this slot.
230+
uint64_t mFrameNumber;
231+
232+
// mFence is the EGL sync object that must signal before the buffer
233+
// associated with this buffer slot may be dequeued. It is initialized
234+
// to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
235+
// on a compile-time option) set to a new sync object in updateTexImage.
236+
EGLSyncKHR mFence;
237+
};
238+
239+
// mSlots is the array of buffer slots that must be mirrored on the client
240+
// side. This allows buffer ownership to be transferred between the client
241+
// and server without sending a GraphicBuffer over binder. The entire array
242+
// is initialized to NULL at construction time, and buffers are allocated
243+
// for a slot when requestBuffer is called with that slot's index.
244+
BufferSlot mSlots[NUM_BUFFER_SLOTS];
245+
246+
247+
// mDefaultWidth holds the default width of allocated buffers. It is used
248+
// in requestBuffers() if a width and height of zero is specified.
249+
uint32_t mDefaultWidth;
250+
251+
// mDefaultHeight holds the default height of allocated buffers. It is used
252+
// in requestBuffers() if a width and height of zero is specified.
253+
uint32_t mDefaultHeight;
254+
255+
// mPixelFormat holds the pixel format of allocated buffers. It is used
256+
// in requestBuffers() if a format of zero is specified.
257+
uint32_t mPixelFormat;
258+
259+
// mBufferCount is the number of buffer slots that the client and server
260+
// must maintain. It defaults to MIN_ASYNC_BUFFER_SLOTS and can be changed
261+
// by calling setBufferCount or setBufferCountServer
262+
int mBufferCount;
263+
264+
// mClientBufferCount is the number of buffer slots requested by the client.
265+
// The default is zero, which means the client doesn't care how many buffers
266+
// there is.
267+
int mClientBufferCount;
268+
269+
// mServerBufferCount buffer count requested by the server-side
270+
int mServerBufferCount;
271+
272+
// mCurrentTexture is the buffer slot index of the buffer that is currently
273+
// bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
274+
// indicating that no buffer slot is currently bound to the texture. Note,
275+
// however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
276+
// that no buffer is bound to the texture. A call to setBufferCount will
277+
// reset mCurrentTexture to INVALID_BUFFER_SLOT.
278+
int mCurrentTexture;
279+
280+
// mNextCrop is the crop rectangle that will be used for the next buffer
281+
// that gets queued. It is set by calling setCrop.
282+
Rect mNextCrop;
283+
284+
// mNextTransform is the transform identifier that will be used for the next
285+
// buffer that gets queued. It is set by calling setTransform.
286+
uint32_t mNextTransform;
287+
288+
// mNextScalingMode is the scaling mode that will be used for the next
289+
// buffers that get queued. It is set by calling setScalingMode.
290+
int mNextScalingMode;
291+
292+
// mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to
293+
// allocate new GraphicBuffer objects.
294+
sp<IGraphicBufferAlloc> mGraphicBufferAlloc;
295+
296+
// mFrameAvailableListener is the listener object that will be called when a
297+
// new frame becomes available. If it is not NULL it will be called from
298+
// queueBuffer.
299+
sp<FrameAvailableListener> mFrameAvailableListener;
300+
301+
// mSynchronousMode whether we're in synchronous mode or not
302+
bool mSynchronousMode;
303+
304+
// mAllowSynchronousMode whether we allow synchronous mode or not
305+
const bool mAllowSynchronousMode;
306+
307+
// mConnectedApi indicates the API that is currently connected to this
308+
// BufferQueue. It defaults to NO_CONNECTED_API (= 0), and gets updated
309+
// by the connect and disconnect methods.
310+
int mConnectedApi;
311+
312+
// mDequeueCondition condition used for dequeueBuffer in synchronous mode
313+
mutable Condition mDequeueCondition;
314+
315+
// mQueue is a FIFO of queued buffers used in synchronous mode
316+
typedef Vector<int> Fifo;
317+
Fifo mQueue;
318+
319+
// mAbandoned indicates that the BufferQueue will no longer be used to
320+
// consume images buffers pushed to it using the ISurfaceTexture interface.
321+
// It is initialized to false, and set to true in the abandon method. A
322+
// BufferQueue that has been abandoned will return the NO_INIT error from
323+
// all ISurfaceTexture methods capable of returning an error.
324+
bool mAbandoned;
325+
326+
// mName is a string used to identify the BufferQueue in log messages.
327+
// It is set by the setName method.
328+
String8 mName;
329+
330+
// mMutex is the mutex used to prevent concurrent access to the member
331+
// variables of BufferQueue objects. It must be locked whenever the
332+
// member variables are accessed.
333+
mutable Mutex mMutex;
334+
335+
// mFrameCounter is the free running counter, incremented for every buffer queued
336+
// with the surface Texture.
337+
uint64_t mFrameCounter;
338+
};
339+
340+
// ----------------------------------------------------------------------------
341+
}; // namespace android
342+
343+
#endif // ANDROID_GUI_BUFFERQUEUE_H

0 commit comments

Comments
 (0)