ConsumerBase.h revision 74d211ae26a0257c6075a823812e40b55aa1e653
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 // IGraphicBufferProducer 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. Child classes should add 73 // their state to the dump by overriding the dumpLocked method, which is 74 // called by these methods after locking the mutex. 75 void dump(String8& result) const; 76 void dump(String8& result, const char* prefix) const; 77 78 // setFrameAvailableListener sets the listener object that will be notified 79 // when a new frame becomes available. 80 void setFrameAvailableListener(const wp<FrameAvailableListener>& listener); 81 82private: 83 ConsumerBase(const ConsumerBase&); 84 void operator=(const ConsumerBase&); 85 86protected: 87 88 // ConsumerBase constructs a new ConsumerBase object to consume image 89 // buffers from the given BufferQueue. 90 ConsumerBase(const sp<BufferQueue> &bufferQueue); 91 92 // onLastStrongRef gets called by RefBase just before the dtor of the most 93 // derived class. It is used to clean up the buffers so that ConsumerBase 94 // can coordinate the clean-up by calling into virtual methods implemented 95 // by the derived classes. This would not be possible from the 96 // ConsuemrBase dtor because by the time that gets called the derived 97 // classes have already been destructed. 98 // 99 // This methods should not need to be overridden by derived classes, but 100 // if they are overridden the ConsumerBase implementation must be called 101 // from the derived class. 102 virtual void onLastStrongRef(const void* id); 103 104 // Implementation of the BufferQueue::ConsumerListener interface. These 105 // calls are used to notify the ConsumerBase of asynchronous events in the 106 // BufferQueue. These methods should not need to be overridden by derived 107 // classes, but if they are overridden the ConsumerBase implementation 108 // must be called from the derived class. 109 virtual void onFrameAvailable(); 110 virtual void onBuffersReleased(); 111 112 // freeBufferLocked frees up the given buffer slot. If the slot has been 113 // initialized this will release the reference to the GraphicBuffer in that 114 // slot. Otherwise it has no effect. 115 // 116 // Derived classes should override this method to clean up any state they 117 // keep per slot. If it is overridden, the derived class's implementation 118 // must call ConsumerBase::freeBufferLocked. 119 // 120 // This method must be called with mMutex locked. 121 virtual void freeBufferLocked(int slotIndex); 122 123 // abandonLocked puts the BufferQueue into the abandoned state, causing 124 // all future operations on it to fail. This method rather than the public 125 // abandon method should be overridden by child classes to add abandon- 126 // time behavior. 127 // 128 // Derived classes should override this method to clean up any object 129 // state they keep (as opposed to per-slot state). If it is overridden, 130 // the derived class's implementation must call ConsumerBase::abandonLocked. 131 // 132 // This method must be called with mMutex locked. 133 virtual void abandonLocked(); 134 135 // dumpLocked dumps the current state of the ConsumerBase object to the 136 // result string. Each line is prefixed with the string pointed to by the 137 // prefix argument. The buffer argument points to a buffer that may be 138 // used for intermediate formatting data, and the size of that buffer is 139 // indicated by the size argument. 140 // 141 // Derived classes should override this method to dump their internal 142 // state. If this method is overridden the derived class's implementation 143 // should call ConsumerBase::dumpLocked. 144 // 145 // This method must be called with mMutex locked. 146 virtual void dumpLocked(String8& result, const char* prefix) const; 147 148 // acquireBufferLocked fetches the next buffer from the BufferQueue and 149 // updates the buffer slot for the buffer returned. 150 // 151 // Derived classes should override this method to perform any 152 // initialization that must take place the first time a buffer is assigned 153 // to a slot. If it is overridden the derived class's implementation must 154 // call ConsumerBase::acquireBufferLocked. 155 virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item); 156 157 // releaseBufferLocked relinquishes control over a buffer, returning that 158 // control to the BufferQueue. 159 // 160 // Derived classes should override this method to perform any cleanup that 161 // must take place when a buffer is released back to the BufferQueue. If 162 // it is overridden the derived class's implementation must call 163 // ConsumerBase::releaseBufferLocked. 164 virtual status_t releaseBufferLocked(int buf, EGLDisplay display, 165 EGLSyncKHR eglFence); 166 167 // addReleaseFence* adds the sync points associated with a fence to the set 168 // of sync points that must be reached before the buffer in the given slot 169 // may be used after the slot has been released. This should be called by 170 // derived classes each time some asynchronous work is kicked off that 171 // references the buffer. 172 status_t addReleaseFence(int slot, const sp<Fence>& fence); 173 status_t addReleaseFenceLocked(int slot, const sp<Fence>& fence); 174 175 // Slot contains the information and object references that 176 // ConsumerBase maintains about a BufferQueue buffer slot. 177 struct Slot { 178 // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if 179 // no Gralloc buffer is in the slot. 180 sp<GraphicBuffer> mGraphicBuffer; 181 182 // mFence is a fence which will signal when the buffer associated with 183 // this buffer slot is no longer being used by the consumer and can be 184 // overwritten. The buffer can be dequeued before the fence signals; 185 // the producer is responsible for delaying writes until it signals. 186 sp<Fence> mFence; 187 }; 188 189 // mSlots stores the buffers that have been allocated by the BufferQueue 190 // for each buffer slot. It is initialized to null pointers, and gets 191 // filled in with the result of BufferQueue::acquire when the 192 // client dequeues a buffer from a 193 // slot that has not yet been used. The buffer allocated to a slot will also 194 // be replaced if the requested buffer usage or geometry differs from that 195 // of the buffer allocated to a slot. 196 Slot mSlots[BufferQueue::NUM_BUFFER_SLOTS]; 197 198 // mAbandoned indicates that the BufferQueue will no longer be used to 199 // consume images buffers pushed to it using the IGraphicBufferProducer 200 // interface. It is initialized to false, and set to true in the abandon 201 // method. A BufferQueue that has been abandoned will return the NO_INIT 202 // error from all IConsumerBase methods capable of returning an error. 203 bool mAbandoned; 204 205 // mName is a string used to identify the ConsumerBase in log messages. 206 // It can be set by the setName method. 207 String8 mName; 208 209 // mFrameAvailableListener is the listener object that will be called when a 210 // new frame becomes available. If it is not NULL it will be called from 211 // queueBuffer. 212 wp<FrameAvailableListener> mFrameAvailableListener; 213 214 // The ConsumerBase has-a BufferQueue and is responsible for creating this object 215 // if none is supplied 216 sp<BufferQueue> mBufferQueue; 217 218 // mMutex is the mutex used to prevent concurrent access to the member 219 // variables of ConsumerBase objects. It must be locked whenever the 220 // member variables are accessed or when any of the *Locked methods are 221 // called. 222 // 223 // This mutex is intended to be locked by derived classes. 224 mutable Mutex mMutex; 225}; 226 227// ---------------------------------------------------------------------------- 228}; // namespace android 229 230#endif // ANDROID_GUI_CONSUMERBASE_H 231