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