Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright (C) 2010 The Android Open Source Project |
michael@0 | 3 | * Copyright (C) 2013 Mozilla Foundation |
michael@0 | 4 | * |
michael@0 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
michael@0 | 6 | * you may not use this file except in compliance with the License. |
michael@0 | 7 | * You may obtain a copy of the License at |
michael@0 | 8 | * |
michael@0 | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
michael@0 | 10 | * |
michael@0 | 11 | * Unless required by applicable law or agreed to in writing, software |
michael@0 | 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
michael@0 | 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
michael@0 | 14 | * See the License for the specific language governing permissions and |
michael@0 | 15 | * limitations under the License. |
michael@0 | 16 | */ |
michael@0 | 17 | |
michael@0 | 18 | #ifndef NATIVEWINDOW_GONKCONSUMERBASE_JB_H |
michael@0 | 19 | #define NATIVEWINDOW_GONKCONSUMERBASE_JB_H |
michael@0 | 20 | |
michael@0 | 21 | #include <ui/GraphicBuffer.h> |
michael@0 | 22 | |
michael@0 | 23 | #include <utils/String8.h> |
michael@0 | 24 | #include <utils/Vector.h> |
michael@0 | 25 | #include <utils/threads.h> |
michael@0 | 26 | |
michael@0 | 27 | #include "GonkBufferQueueJB.h" |
michael@0 | 28 | |
michael@0 | 29 | namespace android { |
michael@0 | 30 | // ---------------------------------------------------------------------------- |
michael@0 | 31 | |
michael@0 | 32 | class String8; |
michael@0 | 33 | |
michael@0 | 34 | // GonkConsumerBase is a base class for GonkBufferQueue consumer end-points. It |
michael@0 | 35 | // handles common tasks like management of the connection to the GonkBufferQueue |
michael@0 | 36 | // and the buffer pool. |
michael@0 | 37 | class GonkConsumerBase : public virtual RefBase, |
michael@0 | 38 | protected GonkBufferQueue::ConsumerListener { |
michael@0 | 39 | public: |
michael@0 | 40 | struct FrameAvailableListener : public virtual RefBase { |
michael@0 | 41 | // onFrameAvailable() is called each time an additional frame becomes |
michael@0 | 42 | // available for consumption. This means that frames that are queued |
michael@0 | 43 | // while in asynchronous mode only trigger the callback if no previous |
michael@0 | 44 | // frames are pending. Frames queued while in synchronous mode always |
michael@0 | 45 | // trigger the callback. |
michael@0 | 46 | // |
michael@0 | 47 | // This is called without any lock held and can be called concurrently |
michael@0 | 48 | // by multiple threads. |
michael@0 | 49 | virtual void onFrameAvailable() = 0; |
michael@0 | 50 | }; |
michael@0 | 51 | |
michael@0 | 52 | virtual ~GonkConsumerBase(); |
michael@0 | 53 | |
michael@0 | 54 | // abandon frees all the buffers and puts the GonkConsumerBase into the |
michael@0 | 55 | // 'abandoned' state. Once put in this state the GonkConsumerBase can never |
michael@0 | 56 | // leave it. When in the 'abandoned' state, all methods of the |
michael@0 | 57 | // IGraphicBufferProducer interface will fail with the NO_INIT error. |
michael@0 | 58 | // |
michael@0 | 59 | // Note that while calling this method causes all the buffers to be freed |
michael@0 | 60 | // from the perspective of the the GonkConsumerBase, if there are additional |
michael@0 | 61 | // references on the buffers (e.g. if a buffer is referenced by a client |
michael@0 | 62 | // or by OpenGL ES as a texture) then those buffer will remain allocated. |
michael@0 | 63 | void abandon(); |
michael@0 | 64 | |
michael@0 | 65 | // set the name of the GonkConsumerBase that will be used to identify it in |
michael@0 | 66 | // log messages. |
michael@0 | 67 | void setName(const String8& name); |
michael@0 | 68 | |
michael@0 | 69 | // getBufferQueue returns the GonkBufferQueue object to which this |
michael@0 | 70 | // GonkConsumerBase is connected. |
michael@0 | 71 | sp<GonkBufferQueue> getBufferQueue() const; |
michael@0 | 72 | |
michael@0 | 73 | // dump writes the current state to a string. Child classes should add |
michael@0 | 74 | // their state to the dump by overriding the dumpLocked method, which is |
michael@0 | 75 | // called by these methods after locking the mutex. |
michael@0 | 76 | void dump(String8& result) const; |
michael@0 | 77 | void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const; |
michael@0 | 78 | |
michael@0 | 79 | // setFrameAvailableListener sets the listener object that will be notified |
michael@0 | 80 | // when a new frame becomes available. |
michael@0 | 81 | #if ANDROID_VERSION == 17 |
michael@0 | 82 | void setFrameAvailableListener(const sp<FrameAvailableListener>& listener); |
michael@0 | 83 | #else |
michael@0 | 84 | void setFrameAvailableListener(const wp<FrameAvailableListener>& listener); |
michael@0 | 85 | #endif |
michael@0 | 86 | |
michael@0 | 87 | private: |
michael@0 | 88 | GonkConsumerBase(const GonkConsumerBase&); |
michael@0 | 89 | void operator=(const GonkConsumerBase&); |
michael@0 | 90 | |
michael@0 | 91 | protected: |
michael@0 | 92 | |
michael@0 | 93 | // GonkConsumerBase constructs a new GonkConsumerBase object to consume image |
michael@0 | 94 | // buffers from the given GonkBufferQueue. |
michael@0 | 95 | GonkConsumerBase(const sp<GonkBufferQueue> &bufferQueue); |
michael@0 | 96 | |
michael@0 | 97 | // onLastStrongRef gets called by RefBase just before the dtor of the most |
michael@0 | 98 | // derived class. It is used to clean up the buffers so that GonkConsumerBase |
michael@0 | 99 | // can coordinate the clean-up by calling into virtual methods implemented |
michael@0 | 100 | // by the derived classes. This would not be possible from the |
michael@0 | 101 | // ConsuemrBase dtor because by the time that gets called the derived |
michael@0 | 102 | // classes have already been destructed. |
michael@0 | 103 | // |
michael@0 | 104 | // This methods should not need to be overridden by derived classes, but |
michael@0 | 105 | // if they are overridden the GonkConsumerBase implementation must be called |
michael@0 | 106 | // from the derived class. |
michael@0 | 107 | virtual void onLastStrongRef(const void* id); |
michael@0 | 108 | |
michael@0 | 109 | // Implementation of the GonkBufferQueue::ConsumerListener interface. These |
michael@0 | 110 | // calls are used to notify the GonkConsumerBase of asynchronous events in the |
michael@0 | 111 | // GonkBufferQueue. These methods should not need to be overridden by derived |
michael@0 | 112 | // classes, but if they are overridden the GonkConsumerBase implementation |
michael@0 | 113 | // must be called from the derived class. |
michael@0 | 114 | virtual void onFrameAvailable(); |
michael@0 | 115 | virtual void onBuffersReleased(); |
michael@0 | 116 | |
michael@0 | 117 | // freeBufferLocked frees up the given buffer slot. If the slot has been |
michael@0 | 118 | // initialized this will release the reference to the GraphicBuffer in that |
michael@0 | 119 | // slot. Otherwise it has no effect. |
michael@0 | 120 | // |
michael@0 | 121 | // Derived classes should override this method to clean up any state they |
michael@0 | 122 | // keep per slot. If it is overridden, the derived class's implementation |
michael@0 | 123 | // must call GonkConsumerBase::freeBufferLocked. |
michael@0 | 124 | // |
michael@0 | 125 | // This method must be called with mMutex locked. |
michael@0 | 126 | virtual void freeBufferLocked(int slotIndex); |
michael@0 | 127 | |
michael@0 | 128 | // abandonLocked puts the GonkBufferQueue into the abandoned state, causing |
michael@0 | 129 | // all future operations on it to fail. This method rather than the public |
michael@0 | 130 | // abandon method should be overridden by child classes to add abandon- |
michael@0 | 131 | // time behavior. |
michael@0 | 132 | // |
michael@0 | 133 | // Derived classes should override this method to clean up any object |
michael@0 | 134 | // state they keep (as opposed to per-slot state). If it is overridden, |
michael@0 | 135 | // the derived class's implementation must call GonkConsumerBase::abandonLocked. |
michael@0 | 136 | // |
michael@0 | 137 | // This method must be called with mMutex locked. |
michael@0 | 138 | virtual void abandonLocked(); |
michael@0 | 139 | |
michael@0 | 140 | // dumpLocked dumps the current state of the GonkConsumerBase object to the |
michael@0 | 141 | // result string. Each line is prefixed with the string pointed to by the |
michael@0 | 142 | // prefix argument. The buffer argument points to a buffer that may be |
michael@0 | 143 | // used for intermediate formatting data, and the size of that buffer is |
michael@0 | 144 | // indicated by the size argument. |
michael@0 | 145 | // |
michael@0 | 146 | // Derived classes should override this method to dump their internal |
michael@0 | 147 | // state. If this method is overridden the derived class's implementation |
michael@0 | 148 | // should call GonkConsumerBase::dumpLocked. |
michael@0 | 149 | // |
michael@0 | 150 | // This method must be called with mMutex locked. |
michael@0 | 151 | virtual void dumpLocked(String8& result, const char* prefix, char* buffer, |
michael@0 | 152 | size_t size) const; |
michael@0 | 153 | |
michael@0 | 154 | // acquireBufferLocked fetches the next buffer from the GonkBufferQueue and |
michael@0 | 155 | // updates the buffer slot for the buffer returned. |
michael@0 | 156 | // |
michael@0 | 157 | // Derived classes should override this method to perform any |
michael@0 | 158 | // initialization that must take place the first time a buffer is assigned |
michael@0 | 159 | // to a slot. If it is overridden the derived class's implementation must |
michael@0 | 160 | // call GonkConsumerBase::acquireBufferLocked. |
michael@0 | 161 | virtual status_t acquireBufferLocked(GonkBufferQueue::BufferItem *item); |
michael@0 | 162 | |
michael@0 | 163 | // releaseBufferLocked relinquishes control over a buffer, returning that |
michael@0 | 164 | // control to the GonkBufferQueue. |
michael@0 | 165 | // |
michael@0 | 166 | // Derived classes should override this method to perform any cleanup that |
michael@0 | 167 | // must take place when a buffer is released back to the GonkBufferQueue. If |
michael@0 | 168 | // it is overridden the derived class's implementation must call |
michael@0 | 169 | // GonkConsumerBase::releaseBufferLocked. |
michael@0 | 170 | virtual status_t releaseBufferLocked(int buf); |
michael@0 | 171 | |
michael@0 | 172 | // addReleaseFence* adds the sync points associated with a fence to the set |
michael@0 | 173 | // of sync points that must be reached before the buffer in the given slot |
michael@0 | 174 | // may be used after the slot has been released. This should be called by |
michael@0 | 175 | // derived classes each time some asynchronous work is kicked off that |
michael@0 | 176 | // references the buffer. |
michael@0 | 177 | status_t addReleaseFence(int slot, const sp<Fence>& fence); |
michael@0 | 178 | status_t addReleaseFenceLocked(int slot, const sp<Fence>& fence); |
michael@0 | 179 | |
michael@0 | 180 | // Slot contains the information and object references that |
michael@0 | 181 | // GonkConsumerBase maintains about a GonkBufferQueue buffer slot. |
michael@0 | 182 | struct Slot { |
michael@0 | 183 | // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if |
michael@0 | 184 | // no Gralloc buffer is in the slot. |
michael@0 | 185 | sp<GraphicBuffer> mGraphicBuffer; |
michael@0 | 186 | |
michael@0 | 187 | // mFence is a fence which will signal when the buffer associated with |
michael@0 | 188 | // this buffer slot is no longer being used by the consumer and can be |
michael@0 | 189 | // overwritten. The buffer can be dequeued before the fence signals; |
michael@0 | 190 | // the producer is responsible for delaying writes until it signals. |
michael@0 | 191 | sp<Fence> mFence; |
michael@0 | 192 | }; |
michael@0 | 193 | |
michael@0 | 194 | // mSlots stores the buffers that have been allocated by the GonkBufferQueue |
michael@0 | 195 | // for each buffer slot. It is initialized to null pointers, and gets |
michael@0 | 196 | // filled in with the result of GonkBufferQueue::acquire when the |
michael@0 | 197 | // client dequeues a buffer from a |
michael@0 | 198 | // slot that has not yet been used. The buffer allocated to a slot will also |
michael@0 | 199 | // be replaced if the requested buffer usage or geometry differs from that |
michael@0 | 200 | // of the buffer allocated to a slot. |
michael@0 | 201 | Slot mSlots[GonkBufferQueue::NUM_BUFFER_SLOTS]; |
michael@0 | 202 | |
michael@0 | 203 | // mAbandoned indicates that the GonkBufferQueue will no longer be used to |
michael@0 | 204 | // consume images buffers pushed to it using the IGraphicBufferProducer |
michael@0 | 205 | // interface. It is initialized to false, and set to true in the abandon |
michael@0 | 206 | // method. A GonkBufferQueue that has been abandoned will return the NO_INIT |
michael@0 | 207 | // error from all IGonkConsumerBase methods capable of returning an error. |
michael@0 | 208 | bool mAbandoned; |
michael@0 | 209 | |
michael@0 | 210 | // mName is a string used to identify the GonkConsumerBase in log messages. |
michael@0 | 211 | // It can be set by the setName method. |
michael@0 | 212 | String8 mName; |
michael@0 | 213 | |
michael@0 | 214 | // mFrameAvailableListener is the listener object that will be called when a |
michael@0 | 215 | // new frame becomes available. If it is not NULL it will be called from |
michael@0 | 216 | // queueBuffer. |
michael@0 | 217 | #if ANDROID_VERSION == 17 |
michael@0 | 218 | sp<FrameAvailableListener> mFrameAvailableListener; |
michael@0 | 219 | #else |
michael@0 | 220 | wp<FrameAvailableListener> mFrameAvailableListener; |
michael@0 | 221 | #endif |
michael@0 | 222 | |
michael@0 | 223 | // The GonkConsumerBase has-a GonkBufferQueue and is responsible for creating this object |
michael@0 | 224 | // if none is supplied |
michael@0 | 225 | sp<GonkBufferQueue> mBufferQueue; |
michael@0 | 226 | |
michael@0 | 227 | // mMutex is the mutex used to prevent concurrent access to the member |
michael@0 | 228 | // variables of GonkConsumerBase objects. It must be locked whenever the |
michael@0 | 229 | // member variables are accessed or when any of the *Locked methods are |
michael@0 | 230 | // called. |
michael@0 | 231 | // |
michael@0 | 232 | // This mutex is intended to be locked by derived classes. |
michael@0 | 233 | mutable Mutex mMutex; |
michael@0 | 234 | }; |
michael@0 | 235 | |
michael@0 | 236 | // ---------------------------------------------------------------------------- |
michael@0 | 237 | }; // namespace android |
michael@0 | 238 | |
michael@0 | 239 | #endif // NATIVEWINDOW_GONKCONSUMERBASE_H |