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 #include <gui/IConsumerListener.h> 28 29 namespace android { 30 // ---------------------------------------------------------------------------- 31 32 class String8; 33 34 // ConsumerBase is a base class for BufferQueue consumer end-points. It 35 // handles common tasks like management of the connection to the BufferQueue 36 // and the buffer pool. 37 class ConsumerBase : public virtual RefBase, 38 protected ConsumerListener { 39 public: 40 struct FrameAvailableListener : public virtual RefBase { 41 // See IConsumerListener::onFrame{Available,Replaced} 42 virtual void onFrameAvailable(const BufferItem& item) = 0; 43 virtual void onFrameReplaced(const BufferItem& /* item */) {} 44 }; 45 46 virtual ~ConsumerBase(); 47 48 // abandon frees all the buffers and puts the ConsumerBase into the 49 // 'abandoned' state. Once put in this state the ConsumerBase can never 50 // leave it. When in the 'abandoned' state, all methods of the 51 // IGraphicBufferProducer interface will fail with the NO_INIT error. 52 // 53 // Note that while calling this method causes all the buffers to be freed 54 // from the perspective of the the ConsumerBase, if there are additional 55 // references on the buffers (e.g. if a buffer is referenced by a client 56 // or by OpenGL ES as a texture) then those buffer will remain allocated. 57 void abandon(); 58 59 // Returns true if the ConsumerBase is in the 'abandoned' state 60 bool isAbandoned(); 61 62 // set the name of the ConsumerBase that will be used to identify it in 63 // log messages. 64 void setName(const String8& name); 65 66 // dump writes the current state to a string. Child classes should add 67 // their state to the dump by overriding the dumpLocked method, which is 68 // called by these methods after locking the mutex. 69 void dump(String8& result) const; 70 void dump(String8& result, const char* prefix) const; 71 72 // setFrameAvailableListener sets the listener object that will be notified 73 // when a new frame becomes available. 74 void setFrameAvailableListener(const wp<FrameAvailableListener>& listener); 75 76 // See IGraphicBufferConsumer::detachBuffer 77 status_t detachBuffer(int slot); 78 79 // See IGraphicBufferConsumer::setDefaultBufferSize 80 status_t setDefaultBufferSize(uint32_t width, uint32_t height); 81 82 // See IGraphicBufferConsumer::setDefaultBufferFormat 83 status_t setDefaultBufferFormat(PixelFormat defaultFormat); 84 85 // See IGraphicBufferConsumer::setDefaultBufferDataSpace 86 status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace); 87 88 private: 89 ConsumerBase(const ConsumerBase&); 90 void operator=(const ConsumerBase&); 91 92 protected: 93 // ConsumerBase constructs a new ConsumerBase object to consume image 94 // buffers from the given IGraphicBufferConsumer. 95 // The controlledByApp flag indicates that this consumer is under the application's 96 // control. 97 ConsumerBase(const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp = false); 98 99 // onLastStrongRef gets called by RefBase just before the dtor of the most 100 // derived class. It is used to clean up the buffers so that ConsumerBase 101 // can coordinate the clean-up by calling into virtual methods implemented 102 // by the derived classes. This would not be possible from the 103 // ConsuemrBase dtor because by the time that gets called the derived 104 // classes have already been destructed. 105 // 106 // This methods should not need to be overridden by derived classes, but 107 // if they are overridden the ConsumerBase implementation must be called 108 // from the derived class. 109 virtual void onLastStrongRef(const void* id); 110 111 // Implementation of the IConsumerListener interface. These 112 // calls are used to notify the ConsumerBase of asynchronous events in the 113 // BufferQueue. The onFrameAvailable, onFrameReplaced, and 114 // onBuffersReleased methods should not need to be overridden by derived 115 // classes, but if they are overridden the ConsumerBase implementation must 116 // be called from the derived class. The ConsumerBase version of 117 // onSidebandStreamChanged does nothing and can be overriden by derived 118 // classes if they want the notification. 119 virtual void onFrameAvailable(const BufferItem& item) override; 120 virtual void onFrameReplaced(const BufferItem& item) override; 121 virtual void onBuffersReleased() override; 122 virtual void onSidebandStreamChanged() override; 123 124 // freeBufferLocked frees up the given buffer slot. If the slot has been 125 // initialized this will release the reference to the GraphicBuffer in that 126 // slot. Otherwise it has no effect. 127 // 128 // Derived classes should override this method to clean up any state they 129 // keep per slot. If it is overridden, the derived class's implementation 130 // must call ConsumerBase::freeBufferLocked. 131 // 132 // This method must be called with mMutex locked. 133 virtual void freeBufferLocked(int slotIndex); 134 135 // abandonLocked puts the BufferQueue into the abandoned state, causing 136 // all future operations on it to fail. This method rather than the public 137 // abandon method should be overridden by child classes to add abandon- 138 // time behavior. 139 // 140 // Derived classes should override this method to clean up any object 141 // state they keep (as opposed to per-slot state). If it is overridden, 142 // the derived class's implementation must call ConsumerBase::abandonLocked. 143 // 144 // This method must be called with mMutex locked. 145 virtual void abandonLocked(); 146 147 // dumpLocked dumps the current state of the ConsumerBase object to the 148 // result string. Each line is prefixed with the string pointed to by the 149 // prefix argument. The buffer argument points to a buffer that may be 150 // used for intermediate formatting data, and the size of that buffer is 151 // indicated by the size argument. 152 // 153 // Derived classes should override this method to dump their internal 154 // state. If this method is overridden the derived class's implementation 155 // should call ConsumerBase::dumpLocked. 156 // 157 // This method must be called with mMutex locked. 158 virtual void dumpLocked(String8& result, const char* prefix) const; 159 160 // acquireBufferLocked fetches the next buffer from the BufferQueue and 161 // updates the buffer slot for the buffer returned. 162 // 163 // Derived classes should override this method to perform any 164 // initialization that must take place the first time a buffer is assigned 165 // to a slot. If it is overridden the derived class's implementation must 166 // call ConsumerBase::acquireBufferLocked. 167 virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, 168 uint64_t maxFrameNumber = 0); 169 170 // releaseBufferLocked relinquishes control over a buffer, returning that 171 // control to the BufferQueue. 172 // 173 // Derived classes should override this method to perform any cleanup that 174 // must take place when a buffer is released back to the BufferQueue. If 175 // it is overridden the derived class's implementation must call 176 // ConsumerBase::releaseBufferLocked.e 177 virtual status_t releaseBufferLocked(int slot, 178 const sp<GraphicBuffer> graphicBuffer, 179 EGLDisplay display, EGLSyncKHR eglFence); 180 181 // returns true iff the slot still has the graphicBuffer in it. 182 bool stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer); 183 184 // addReleaseFence* adds the sync points associated with a fence to the set 185 // of sync points that must be reached before the buffer in the given slot 186 // may be used after the slot has been released. This should be called by 187 // derived classes each time some asynchronous work is kicked off that 188 // references the buffer. 189 status_t addReleaseFence(int slot, 190 const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence); 191 status_t addReleaseFenceLocked(int slot, 192 const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence); 193 194 // Slot contains the information and object references that 195 // ConsumerBase maintains about a BufferQueue buffer slot. 196 struct Slot { 197 // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if 198 // no Gralloc buffer is in the slot. 199 sp<GraphicBuffer> mGraphicBuffer; 200 201 // mFence is a fence which will signal when the buffer associated with 202 // this buffer slot is no longer being used by the consumer and can be 203 // overwritten. The buffer can be dequeued before the fence signals; 204 // the producer is responsible for delaying writes until it signals. 205 sp<Fence> mFence; 206 207 // the frame number of the last acquired frame for this slot 208 uint64_t mFrameNumber; 209 }; 210 211 // mSlots stores the buffers that have been allocated by the BufferQueue 212 // for each buffer slot. It is initialized to null pointers, and gets 213 // filled in with the result of BufferQueue::acquire when the 214 // client dequeues a buffer from a 215 // slot that has not yet been used. The buffer allocated to a slot will also 216 // be replaced if the requested buffer usage or geometry differs from that 217 // of the buffer allocated to a slot. 218 Slot mSlots[BufferQueue::NUM_BUFFER_SLOTS]; 219 220 // mAbandoned indicates that the BufferQueue will no longer be used to 221 // consume images buffers pushed to it using the IGraphicBufferProducer 222 // interface. It is initialized to false, and set to true in the abandon 223 // method. A BufferQueue that has been abandoned will return the NO_INIT 224 // error from all IConsumerBase methods capable of returning an error. 225 bool mAbandoned; 226 227 // mName is a string used to identify the ConsumerBase in log messages. 228 // It can be set by the setName method. 229 String8 mName; 230 231 // mFrameAvailableListener is the listener object that will be called when a 232 // new frame becomes available. If it is not NULL it will be called from 233 // queueBuffer. 234 wp<FrameAvailableListener> mFrameAvailableListener; 235 236 // The ConsumerBase has-a BufferQueue and is responsible for creating this object 237 // if none is supplied 238 sp<IGraphicBufferConsumer> mConsumer; 239 240 // mMutex is the mutex used to prevent concurrent access to the member 241 // variables of ConsumerBase objects. It must be locked whenever the 242 // member variables are accessed or when any of the *Locked methods are 243 // called. 244 // 245 // This mutex is intended to be locked by derived classes. 246 mutable Mutex mMutex; 247 }; 248 249 // ---------------------------------------------------------------------------- 250 }; // namespace android 251 252 #endif // ANDROID_GUI_CONSUMERBASE_H 253