blob: d2bf0f649d32124b766285b4950a31dd40ec53bc [file] [log] [blame]
Jamie Gennis1a4d8832012-08-02 20:11:05 -07001/*
2 * Copyright (C) 2010 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_CONSUMERBASE_H
18#define ANDROID_GUI_CONSUMERBASE_H
19
20#include <gui/BufferQueue.h>
21
22#include <ui/GraphicBuffer.h>
23
24#include <utils/String8.h>
25#include <utils/Vector.h>
26#include <utils/threads.h>
27
28namespace android {
29// ----------------------------------------------------------------------------
30
31class String8;
32
33// ConsumerBase is a base class for BufferQueue consumer end-points. It
34// handles common tasks like management of the connection to the BufferQueue
35// and the buffer pool.
36class ConsumerBase : public virtual RefBase,
37 protected BufferQueue::ConsumerListener {
38public:
39 struct FrameAvailableListener : public virtual RefBase {
40 // onFrameAvailable() is called each time an additional frame becomes
41 // available for consumption. This means that frames that are queued
42 // while in asynchronous mode only trigger the callback if no previous
43 // frames are pending. Frames queued while in synchronous mode always
44 // trigger the callback.
45 //
46 // This is called without any lock held and can be called concurrently
47 // by multiple threads.
48 virtual void onFrameAvailable() = 0;
49 };
50
51 virtual ~ConsumerBase();
52
53 // abandon frees all the buffers and puts the ConsumerBase into the
54 // 'abandoned' state. Once put in this state the ConsumerBase can never
55 // leave it. When in the 'abandoned' state, all methods of the
56 // ISurfaceTexture interface will fail with the NO_INIT error.
57 //
58 // Note that while calling this method causes all the buffers to be freed
59 // from the perspective of the the ConsumerBase, if there are additional
60 // references on the buffers (e.g. if a buffer is referenced by a client
61 // or by OpenGL ES as a texture) then those buffer will remain allocated.
62 void abandon();
63
64 // set the name of the ConsumerBase that will be used to identify it in
65 // log messages.
66 void setName(const String8& name);
67
68 // getBufferQueue returns the BufferQueue object to which this
69 // ConsumerBase is connected.
70 sp<BufferQueue> getBufferQueue() const;
71
72 // dump writes the current state to a string. These methods should NOT be
73 // overridden by child classes. Instead they should override the
74 // dumpLocked method, which is called by these methods after locking the
75 // 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 void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
82
83private:
84 ConsumerBase(const ConsumerBase&);
85 void operator=(const ConsumerBase&);
86
87protected:
88
89 // TODO: Fix this comment
90 // ConsumerBase constructs a new ConsumerBase object. tex indicates the
91 // name of the OpenGL ES texture to which images are to be streamed.
92 // allowSynchronousMode specifies whether or not synchronous mode can be
93 // enabled. texTarget specifies the OpenGL ES texture target to which the
94 // texture will be bound in updateTexImage. useFenceSync specifies whether
95 // fences should be used to synchronize access to buffers if that behavior
96 // is enabled at compile-time. A custom bufferQueue can be specified
97 // if behavior for queue/dequeue/connect etc needs to be customized.
98 // Otherwise a default BufferQueue will be created and used.
99 //
100 // For legacy reasons, the ConsumerBase is created in a state where it is
101 // considered attached to an OpenGL ES context for the purposes of the
102 // attachToContext and detachFromContext methods. However, despite being
103 // considered "attached" to a context, the specific OpenGL ES context
104 // doesn't get latched until the first call to updateTexImage. After that
105 // point, all calls to updateTexImage must be made with the same OpenGL ES
106 // context current.
107 //
108 // A ConsumerBase may be detached from one OpenGL ES context and then
109 // attached to a different context using the detachFromContext and
110 // attachToContext methods, respectively. The intention of these methods is
111 // purely to allow a ConsumerBase to be transferred from one consumer
112 // context to another. If such a transfer is not needed there is no
113 // requirement that either of these methods be called.
114 ConsumerBase(const sp<BufferQueue> &bufferQueue);
115
116 // Implementation of the BufferQueue::ConsumerListener interface. These
117 // calls are used to notify the ConsumerBase of asynchronous events in the
118 // BufferQueue.
119 virtual void onFrameAvailable();
120 virtual void onBuffersReleased();
121
122 // freeBufferLocked frees up the given buffer slot. If the slot has been
123 // initialized this will release the reference to the GraphicBuffer in that
124 // slot and destroy the EGLImage in that slot. Otherwise it has no effect.
125 //
126 // This method must be called with mMutex locked.
127 virtual void freeBufferLocked(int slotIndex);
128
129 // abandonLocked puts the BufferQueue into the abandoned state, causing
130 // all future operations on it to fail. This method rather than the public
131 // abandon method should be overridden by child classes to add abandon-
132 // time behavior.
133 //
134 // This method must be called with mMutex locked.
135 virtual void abandonLocked();
136
137 virtual void dumpLocked(String8& result, const char* prefix, char* buffer,
138 size_t SIZE) const;
139
140 // acquireBufferLocked fetches the next buffer from the BufferQueue and
141 // updates the buffer slot for the buffer returned.
142 virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item);
143
144 // releaseBufferLocked relinquishes control over a buffer, returning that
145 // control to the BufferQueue.
146 virtual status_t releaseBufferLocked(int buf, EGLDisplay display,
147 EGLSyncKHR eglFence, const sp<Fence>& fence);
148
149 // Slot contains the information and object references that
150 // ConsumerBase maintains about a BufferQueue buffer slot.
151 struct Slot {
152 // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if
153 // no Gralloc buffer is in the slot.
154 sp<GraphicBuffer> mGraphicBuffer;
155
156 // mFence is a fence which will signal when the buffer associated with
157 // this buffer slot is no longer being used by the consumer and can be
158 // overwritten. The buffer can be dequeued before the fence signals;
159 // the producer is responsible for delaying writes until it signals.
160 sp<Fence> mFence;
161 };
162
163 // mSlots stores the buffers that have been allocated by the BufferQueue
164 // for each buffer slot. It is initialized to null pointers, and gets
165 // filled in with the result of BufferQueue::acquire when the
166 // client dequeues a buffer from a
167 // slot that has not yet been used. The buffer allocated to a slot will also
168 // be replaced if the requested buffer usage or geometry differs from that
169 // of the buffer allocated to a slot.
170 Slot mSlots[BufferQueue::NUM_BUFFER_SLOTS];
171
172 // mAbandoned indicates that the BufferQueue will no longer be used to
173 // consume images buffers pushed to it using the ISurfaceTexture
174 // interface. It is initialized to false, and set to true in the abandon
175 // method. A BufferQueue that has been abandoned will return the NO_INIT
176 // error from all IConsumerBase methods capable of returning an error.
177 bool mAbandoned;
178
179 // mName is a string used to identify the ConsumerBase in log messages.
180 // It can be set by the setName method.
181 String8 mName;
182
183 // mFrameAvailableListener is the listener object that will be called when a
184 // new frame becomes available. If it is not NULL it will be called from
185 // queueBuffer.
186 sp<FrameAvailableListener> mFrameAvailableListener;
187
188 // The ConsumerBase has-a BufferQueue and is responsible for creating this object
189 // if none is supplied
190 sp<BufferQueue> mBufferQueue;
191
192 // mAttached indicates whether the ConsumerBase is currently attached to
193 // an OpenGL ES context. For legacy reasons, this is initialized to true,
194 // indicating that the ConsumerBase is considered to be attached to
195 // whatever context is current at the time of the first updateTexImage call.
196 // It is set to false by detachFromContext, and then set to true again by
197 // attachToContext.
198 bool mAttached;
199
200 // mMutex is the mutex used to prevent concurrent access to the member
201 // variables of ConsumerBase objects. It must be locked whenever the
202 // member variables are accessed.
203 mutable Mutex mMutex;
204};
205
206// ----------------------------------------------------------------------------
207}; // namespace android
208
209#endif // ANDROID_GUI_CONSUMERBASE_H