ConsumerBase.h revision ed059a8d754770c3cf28b78dba30f7a6ba475dbe
1/* 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 // mMutex is the mutex used to prevent concurrent access to the member 193 // variables of ConsumerBase objects. It must be locked whenever the 194 // member variables are accessed. 195 mutable Mutex mMutex; 196}; 197 198// ---------------------------------------------------------------------------- 199}; // namespace android 200 201#endif // ANDROID_GUI_CONSUMERBASE_H 202