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 <com_android_graphics_libgui_flags.h> 21 #include <gui/BufferQueueDefs.h> 22 #include <gui/IConsumerListener.h> 23 #include <gui/IGraphicBufferConsumer.h> 24 #include <gui/IGraphicBufferProducer.h> 25 #include <gui/OccupancyTracker.h> 26 #include <ui/PixelFormat.h> 27 #include <utils/String8.h> 28 #include <utils/Vector.h> 29 #include <utils/threads.h> 30 31 namespace android { 32 // ---------------------------------------------------------------------------- 33 34 class String8; 35 class GraphicBuffer; 36 37 // ConsumerBase is a base class for BufferQueue consumer end-points. It 38 // handles common tasks like management of the connection to the BufferQueue 39 // and the buffer pool. 40 class ConsumerBase : public virtual RefBase, 41 protected ConsumerListener { 42 public: 43 struct FrameAvailableListener : public virtual RefBase { 44 // See IConsumerListener::onFrame{Available,Replaced} 45 virtual void onFrameAvailable(const BufferItem& item) = 0; onFrameReplacedFrameAvailableListener46 virtual void onFrameReplaced(const BufferItem& /* item */) {} onFrameDequeuedFrameAvailableListener47 virtual void onFrameDequeued(const uint64_t){}; onFrameCancelledFrameAvailableListener48 virtual void onFrameCancelled(const uint64_t){}; onFrameDetachedFrameAvailableListener49 virtual void onFrameDetached(const uint64_t){}; 50 }; 51 52 ~ConsumerBase() override; 53 54 // abandon frees all the buffers and puts the ConsumerBase into the 55 // 'abandoned' state. Once put in this state the ConsumerBase can never 56 // leave it. When in the 'abandoned' state, all methods of the 57 // IGraphicBufferProducer interface will fail with the NO_INIT error. 58 // 59 // Note that while calling this method causes all the buffers to be freed 60 // from the perspective of the the ConsumerBase, if there are additional 61 // references on the buffers (e.g. if a buffer is referenced by a client 62 // or by OpenGL ES as a texture) then those buffer will remain allocated. 63 void abandon(); 64 65 // Returns true if the ConsumerBase is in the 'abandoned' state 66 bool isAbandoned(); 67 68 // set the name of the ConsumerBase that will be used to identify it in 69 // log messages. 70 void setName(const String8& name); 71 72 // dumpState 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 dumpState(String8& result) const; 76 void dumpState(String8& result, const char* prefix) const; 77 78 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 79 // Returns a Surface that can be used as the producer for this consumer. 80 sp<Surface> getSurface() const; 81 82 // DEPRECATED, DO NOT USE. Returns the underlying IGraphicBufferConsumer 83 // that backs this ConsumerBase. 84 sp<IGraphicBufferConsumer> getIGraphicBufferConsumer() const 85 __attribute((deprecated("DO NOT USE: Temporary hack for refactoring"))); 86 #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 87 88 // setFrameAvailableListener sets the listener object that will be notified 89 // when a new frame becomes available. 90 void setFrameAvailableListener(const wp<FrameAvailableListener>& listener); 91 92 // See IGraphicBufferConsumer::detachBuffer 93 status_t detachBuffer(int slot) __attribute(( 94 deprecated("Please use the GraphicBuffer variant--slots are deprecated."))); 95 96 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) 97 // See IGraphicBufferConsumer::detachBuffer 98 status_t detachBuffer(const sp<GraphicBuffer>& buffer); 99 #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) 100 101 status_t addReleaseFence(const sp<GraphicBuffer> buffer, const sp<Fence>& fence); 102 103 // See IGraphicBufferConsumer::setDefaultBufferSize 104 status_t setDefaultBufferSize(uint32_t width, uint32_t height); 105 106 // See IGraphicBufferConsumer::setDefaultBufferFormat 107 status_t setDefaultBufferFormat(PixelFormat defaultFormat); 108 109 // See IGraphicBufferConsumer::setDefaultBufferDataSpace 110 status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace); 111 112 // See IGraphicBufferConsumer::setConsumerUsageBits 113 status_t setConsumerUsageBits(uint64_t usage); 114 115 // See IGraphicBufferConsumer::setTransformHint 116 status_t setTransformHint(uint32_t hint); 117 118 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 119 // See IGraphicBufferConsumer::setMaxBufferCount 120 status_t setMaxBufferCount(int bufferCount); 121 #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 122 123 // See IGraphicBufferConsumer::setMaxAcquiredBufferCount 124 status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers); 125 126 status_t setConsumerIsProtected(bool isProtected); 127 128 // See IGraphicBufferConsumer::getSidebandStream 129 sp<NativeHandle> getSidebandStream() const; 130 131 // See IGraphicBufferConsumer::getOccupancyHistory 132 status_t getOccupancyHistory(bool forceFlush, 133 std::vector<OccupancyTracker::Segment>* outHistory); 134 135 // See IGraphicBufferConsumer::discardFreeBuffers 136 status_t discardFreeBuffers(); 137 138 private: 139 ConsumerBase(const ConsumerBase&); 140 void operator=(const ConsumerBase&); 141 142 void initialize(bool controlledByApp); 143 144 protected: 145 // ConsumerBase constructs a new ConsumerBase object to consume image 146 // buffers from the given IGraphicBufferConsumer. 147 // The controlledByApp flag indicates that this consumer is under the application's 148 // control. 149 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 150 explicit ConsumerBase(bool controlledByApp = false, bool consumerIsSurfaceFlinger = false); 151 explicit ConsumerBase(const sp<IGraphicBufferProducer>& producer, 152 const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp = false); 153 154 explicit ConsumerBase(const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp = false) 155 __attribute((deprecated("ConsumerBase should own its own producer, and constructing it " 156 "without one is fragile! This method is going away soon."))); 157 #else 158 explicit ConsumerBase(const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp = false); 159 #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 160 161 // onLastStrongRef gets called by RefBase just before the dtor of the most 162 // derived class. It is used to clean up the buffers so that ConsumerBase 163 // can coordinate the clean-up by calling into virtual methods implemented 164 // by the derived classes. This would not be possible from the 165 // ConsuemrBase dtor because by the time that gets called the derived 166 // classes have already been destructed. 167 // 168 // This methods should not need to be overridden by derived classes, but 169 // if they are overridden the ConsumerBase implementation must be called 170 // from the derived class. 171 virtual void onLastStrongRef(const void* id); 172 173 // Implementation of the IConsumerListener interface. These 174 // calls are used to notify the ConsumerBase of asynchronous events in the 175 // BufferQueue. The onFrameAvailable, onFrameReplaced, and 176 // onBuffersReleased methods should not need to be overridden by derived 177 // classes, but if they are overridden the ConsumerBase implementation must 178 // be called from the derived class. The ConsumerBase version of 179 // onSidebandStreamChanged does nothing and can be overriden by derived 180 // classes if they want the notification. 181 virtual void onFrameAvailable(const BufferItem& item) override; 182 virtual void onFrameReplaced(const BufferItem& item) override; 183 virtual void onFrameDequeued(const uint64_t bufferId) override; 184 virtual void onFrameCancelled(const uint64_t bufferId) override; 185 virtual void onFrameDetached(const uint64_t bufferId) override; 186 virtual void onBuffersReleased() override; 187 virtual void onSidebandStreamChanged() override; 188 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) 189 virtual void onSlotCountChanged(int slotCount) override; 190 #endif 191 virtual int getSlotForBufferLocked(const sp<GraphicBuffer>& buffer); 192 193 virtual void onBuffersReleasedLocked(); 194 195 virtual status_t detachBufferLocked(int slotIndex); 196 197 // freeBufferLocked frees up the given buffer slot. If the slot has been 198 // initialized this will release the reference to the GraphicBuffer in that 199 // slot. Otherwise it has no effect. 200 // 201 // Derived classes should override this method to clean up any state they 202 // keep per slot. If it is overridden, the derived class's implementation 203 // must call ConsumerBase::freeBufferLocked. 204 // 205 // This method must be called with mMutex locked. 206 virtual void freeBufferLocked(int slotIndex); 207 208 // abandonLocked puts the BufferQueue into the abandoned state, causing 209 // all future operations on it to fail. This method rather than the public 210 // abandon method should be overridden by child classes to add abandon- 211 // time behavior. 212 // 213 // Derived classes should override this method to clean up any object 214 // state they keep (as opposed to per-slot state). If it is overridden, 215 // the derived class's implementation must call ConsumerBase::abandonLocked. 216 // 217 // This method must be called with mMutex locked. 218 virtual void abandonLocked(); 219 220 // dumpLocked dumps the current state of the ConsumerBase object to the 221 // result string. Each line is prefixed with the string pointed to by the 222 // prefix argument. The buffer argument points to a buffer that may be 223 // used for intermediate formatting data, and the size of that buffer is 224 // indicated by the size argument. 225 // 226 // Derived classes should override this method to dump their internal 227 // state. If this method is overridden the derived class's implementation 228 // should call ConsumerBase::dumpLocked. 229 // 230 // This method must be called with mMutex locked. 231 virtual void dumpLocked(String8& result, const char* prefix) const; 232 233 // acquireBufferLocked fetches the next buffer from the BufferQueue and 234 // updates the buffer slot for the buffer returned. 235 // 236 // Derived classes should override this method to perform any 237 // initialization that must take place the first time a buffer is assigned 238 // to a slot. If it is overridden the derived class's implementation must 239 // call ConsumerBase::acquireBufferLocked. 240 virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, 241 uint64_t maxFrameNumber = 0); 242 243 // releaseBufferLocked relinquishes control over a buffer, returning that 244 // control to the BufferQueue. 245 // 246 // Derived classes should override this method to perform any cleanup that 247 // must take place when a buffer is released back to the BufferQueue. If 248 // it is overridden the derived class's implementation must call 249 // ConsumerBase::releaseBufferLocked. 250 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) 251 virtual status_t releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer); 252 #else 253 virtual status_t releaseBufferLocked(int slot, 254 const sp<GraphicBuffer> graphicBuffer, 255 EGLDisplay display = EGL_NO_DISPLAY, EGLSyncKHR eglFence = EGL_NO_SYNC_KHR); 256 #endif 257 // returns true iff the slot still has the graphicBuffer in it. 258 bool stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer); 259 260 // addReleaseFence* adds the sync points associated with a fence to the set 261 // of sync points that must be reached before the buffer in the given slot 262 // may be used after the slot has been released. This should be called by 263 // derived classes each time some asynchronous work is kicked off that 264 // references the buffer. 265 status_t addReleaseFence(int slot, 266 const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence); 267 status_t addReleaseFenceLocked(int slot, 268 const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence); 269 270 // Slot contains the information and object references that 271 // ConsumerBase maintains about a BufferQueue buffer slot. 272 struct Slot { 273 // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if 274 // no Gralloc buffer is in the slot. 275 sp<GraphicBuffer> mGraphicBuffer; 276 277 // mFence is a fence which will signal when the buffer associated with 278 // this buffer slot is no longer being used by the consumer and can be 279 // overwritten. The buffer can be dequeued before the fence signals; 280 // the producer is responsible for delaying writes until it signals. 281 sp<Fence> mFence; 282 283 // the frame number of the last acquired frame for this slot 284 uint64_t mFrameNumber; 285 }; 286 287 // mSlots stores the buffers that have been allocated by the BufferQueue 288 // for each buffer slot. It is initialized to null pointers, and gets 289 // filled in with the result of BufferQueue::acquire when the 290 // client dequeues a buffer from a 291 // slot that has not yet been used. The buffer allocated to a slot will also 292 // be replaced if the requested buffer usage or geometry differs from that 293 // of the buffer allocated to a slot. 294 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) 295 std::vector<Slot> mSlots; 296 #else 297 Slot mSlots[BufferQueueDefs::NUM_BUFFER_SLOTS]; 298 #endif 299 300 // mAbandoned indicates that the BufferQueue will no longer be used to 301 // consume images buffers pushed to it using the IGraphicBufferProducer 302 // interface. It is initialized to false, and set to true in the abandon 303 // method. A BufferQueue that has been abandoned will return the NO_INIT 304 // error from all IConsumerBase methods capable of returning an error. 305 bool mAbandoned; 306 307 // mName is a string used to identify the ConsumerBase in log messages. 308 // It can be set by the setName method. 309 String8 mName; 310 311 // mFrameAvailableListener is the listener object that will be called when a 312 // new frame becomes available. If it is not NULL it will be called from 313 // queueBuffer. The listener object is protected by mFrameAvailableMutex 314 // (not mMutex). 315 Mutex mFrameAvailableMutex; 316 wp<FrameAvailableListener> mFrameAvailableListener; 317 318 // The ConsumerBase has-a BufferQueue and is responsible for creating these 319 // objects if not supplied. 320 sp<IGraphicBufferConsumer> mConsumer; 321 322 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 323 // This Surface wraps the IGraphicBufferConsumer created for this 324 // ConsumerBase. 325 sp<Surface> mSurface; 326 #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 327 328 // The final release fence of the most recent buffer released by 329 // releaseBufferLocked. 330 sp<Fence> mPrevFinalReleaseFence; 331 332 // mMutex is the mutex used to prevent concurrent access to the member 333 // variables of ConsumerBase objects. It must be locked whenever the 334 // member variables are accessed or when any of the *Locked methods are 335 // called. 336 // 337 // This mutex is intended to be locked by derived classes. 338 mutable Mutex mMutex; 339 }; 340 341 // ---------------------------------------------------------------------------- 342 }; // namespace android 343 344 #endif // ANDROID_GUI_CONSUMERBASE_H 345