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) 2012 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_GONKNATIVEWINDOW_ICS_H |
michael@0 | 19 | #define NATIVEWINDOW_GONKNATIVEWINDOW_ICS_H |
michael@0 | 20 | |
michael@0 | 21 | #include <stdint.h> |
michael@0 | 22 | #include <sys/types.h> |
michael@0 | 23 | |
michael@0 | 24 | #include <gui/ISurfaceTexture.h> |
michael@0 | 25 | #include <ui/egl/android_natives.h> |
michael@0 | 26 | #include <ui/GraphicBuffer.h> |
michael@0 | 27 | #include <ui/Rect.h> |
michael@0 | 28 | #include <utils/Errors.h> |
michael@0 | 29 | #include <utils/RefBase.h> |
michael@0 | 30 | #include <utils/String8.h> |
michael@0 | 31 | #include <utils/threads.h> |
michael@0 | 32 | |
michael@0 | 33 | #include "CameraCommon.h" |
michael@0 | 34 | #include "GrallocImages.h" |
michael@0 | 35 | #include "mozilla/layers/LayersSurfaces.h" |
michael@0 | 36 | #include "mozilla/layers/TextureClient.h" |
michael@0 | 37 | |
michael@0 | 38 | namespace android { |
michael@0 | 39 | |
michael@0 | 40 | // The user of GonkNativeWindow who wants to receive notification of |
michael@0 | 41 | // new frames should implement this interface. |
michael@0 | 42 | class GonkNativeWindowNewFrameCallback { |
michael@0 | 43 | public: |
michael@0 | 44 | virtual void OnNewFrame() = 0; |
michael@0 | 45 | }; |
michael@0 | 46 | |
michael@0 | 47 | class GonkNativeWindow : public BnSurfaceTexture |
michael@0 | 48 | { |
michael@0 | 49 | friend class GonkNativeWindowClient; |
michael@0 | 50 | |
michael@0 | 51 | typedef mozilla::layers::TextureClient TextureClient; |
michael@0 | 52 | |
michael@0 | 53 | public: |
michael@0 | 54 | enum { MIN_UNDEQUEUED_BUFFERS = 2 }; |
michael@0 | 55 | enum { MIN_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS }; |
michael@0 | 56 | enum { NUM_BUFFER_SLOTS = 32 }; |
michael@0 | 57 | enum { NO_CONNECTED_API = 0 }; |
michael@0 | 58 | enum { NATIVE_WINDOW_SET_BUFFERS_SIZE = 0x10000000 }; |
michael@0 | 59 | |
michael@0 | 60 | GonkNativeWindow(); |
michael@0 | 61 | ~GonkNativeWindow(); // this class cannot be overloaded |
michael@0 | 62 | |
michael@0 | 63 | // Get next frame from the queue and mark it as RENDERING, caller |
michael@0 | 64 | // owns the returned buffer. |
michael@0 | 65 | mozilla::TemporaryRef<TextureClient> getCurrentBuffer(); |
michael@0 | 66 | |
michael@0 | 67 | // Return the buffer to the queue and mark it as FREE. After that |
michael@0 | 68 | // the buffer is useable again for the decoder. |
michael@0 | 69 | void returnBuffer(TextureClient* client); |
michael@0 | 70 | |
michael@0 | 71 | // setBufferCount updates the number of available buffer slots. After |
michael@0 | 72 | // calling this all buffer slots are owned by the GonkNativeWindow object |
michael@0 | 73 | // (i.e. they are not owned by the client). |
michael@0 | 74 | virtual status_t setBufferCount(int bufferCount); |
michael@0 | 75 | |
michael@0 | 76 | // requestBuffer requests a new buffer for the given index. |
michael@0 | 77 | virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf); |
michael@0 | 78 | |
michael@0 | 79 | // dequeueBuffer gets the next buffer slot index for the client to use. If a |
michael@0 | 80 | // buffer slot is available then that slot index is written to the location |
michael@0 | 81 | // pointed to by the buf argument and a status of OK is returned. If no |
michael@0 | 82 | // slot is available then a status of -EBUSY is returned and buf is |
michael@0 | 83 | // unmodified. |
michael@0 | 84 | virtual status_t dequeueBuffer(int *buf, uint32_t width, uint32_t height, |
michael@0 | 85 | uint32_t format, uint32_t usage); |
michael@0 | 86 | |
michael@0 | 87 | // queueBuffer returns a filled buffer to the GonkNativeWindow. In addition, |
michael@0 | 88 | // a timestamp must be provided for the buffer. The timestamp is in |
michael@0 | 89 | // nanoseconds, and must be monotonically increasing. Its other semantics |
michael@0 | 90 | // (zero point, etc) are client-dependent and should be documented by the |
michael@0 | 91 | // client. |
michael@0 | 92 | virtual status_t queueBuffer(int buf, int64_t timestamp, |
michael@0 | 93 | uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform); |
michael@0 | 94 | virtual void cancelBuffer(int buf); |
michael@0 | 95 | virtual status_t setCrop(const Rect& reg); |
michael@0 | 96 | virtual status_t setTransform(uint32_t transform); |
michael@0 | 97 | virtual status_t setScalingMode(int mode); |
michael@0 | 98 | |
michael@0 | 99 | virtual int query(int what, int* value); |
michael@0 | 100 | |
michael@0 | 101 | // Qcom specific function |
michael@0 | 102 | virtual int performQcomOperation(int operation, int arg1, int arg2, int arg3) { |
michael@0 | 103 | return OK; |
michael@0 | 104 | } |
michael@0 | 105 | |
michael@0 | 106 | // GonkNativeWindow do not implement the function and always works in |
michael@0 | 107 | // synchronous mode. |
michael@0 | 108 | virtual status_t setSynchronousMode(bool enabled); |
michael@0 | 109 | |
michael@0 | 110 | // connect attempts to connect a client API to the GonkNativeWindow. |
michael@0 | 111 | // |
michael@0 | 112 | // This method will fail if the connect was previously called on the |
michael@0 | 113 | // GonkNativeWindow and no corresponding disconnect call was made. |
michael@0 | 114 | virtual status_t connect(int api, |
michael@0 | 115 | uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform); |
michael@0 | 116 | |
michael@0 | 117 | // disconnect attempts to disconnect a client API from the GonkNativeWindow. |
michael@0 | 118 | // This method will fail if the the GonkNativeWindow is not currently |
michael@0 | 119 | // connected to the specified client API. |
michael@0 | 120 | virtual status_t disconnect(int api); |
michael@0 | 121 | |
michael@0 | 122 | void setNewFrameCallback(GonkNativeWindowNewFrameCallback* aCallback); |
michael@0 | 123 | |
michael@0 | 124 | // setDefaultBufferSize is used to set the size of buffers returned by |
michael@0 | 125 | // requestBuffers when a with and height of zero is requested. |
michael@0 | 126 | // A call to setDefaultBufferSize() may trigger requestBuffers() to |
michael@0 | 127 | // be called from the client. |
michael@0 | 128 | status_t setDefaultBufferSize(uint32_t width, uint32_t height); |
michael@0 | 129 | |
michael@0 | 130 | // abandon frees all the buffers and puts the GonkNativeWindow into the |
michael@0 | 131 | // 'abandoned' state. Once put in this state the GonkNativeWindow can never |
michael@0 | 132 | // leave it. When in the 'abandoned' state, all methods of the |
michael@0 | 133 | // ISurfaceTexture interface will fail with the NO_INIT error. |
michael@0 | 134 | // |
michael@0 | 135 | // Note that while calling this method causes all the buffers to be freed |
michael@0 | 136 | // from the perspective of the the GonkNativeWindow, if there are additional |
michael@0 | 137 | // references on the buffers (e.g. if a buffer is referenced by a client) |
michael@0 | 138 | // then those buffer will remain allocated. |
michael@0 | 139 | void abandon(); |
michael@0 | 140 | |
michael@0 | 141 | mozilla::TemporaryRef<TextureClient> getTextureClientFromBuffer(ANativeWindowBuffer* buffer); |
michael@0 | 142 | |
michael@0 | 143 | static void RecycleCallback(TextureClient* client, void* closure); |
michael@0 | 144 | |
michael@0 | 145 | protected: |
michael@0 | 146 | |
michael@0 | 147 | // freeAllBuffersLocked frees the resources (both GraphicBuffer and |
michael@0 | 148 | // EGLImage) for all slots by removing them from the slots and appending |
michael@0 | 149 | // then to the freeList. This must be called with mMutex locked. |
michael@0 | 150 | void freeAllBuffersLocked(); |
michael@0 | 151 | |
michael@0 | 152 | // clearRenderingStateBuffersLocked clear the resources in RENDERING state; |
michael@0 | 153 | // But do not destroy the gralloc buffer. It is still in the video stream |
michael@0 | 154 | // awaiting rendering. |
michael@0 | 155 | // this must be called with mMutex locked. |
michael@0 | 156 | void clearRenderingStateBuffersLocked(); |
michael@0 | 157 | |
michael@0 | 158 | private: |
michael@0 | 159 | void init(); |
michael@0 | 160 | |
michael@0 | 161 | int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; |
michael@0 | 162 | |
michael@0 | 163 | int getSlotFromTextureClientLocked(TextureClient* client) const; |
michael@0 | 164 | |
michael@0 | 165 | enum { INVALID_BUFFER_SLOT = -1 }; |
michael@0 | 166 | |
michael@0 | 167 | struct BufferSlot { |
michael@0 | 168 | |
michael@0 | 169 | BufferSlot() |
michael@0 | 170 | : mBufferState(BufferSlot::FREE), |
michael@0 | 171 | mTimestamp(0), |
michael@0 | 172 | mFrameNumber(0){ |
michael@0 | 173 | } |
michael@0 | 174 | |
michael@0 | 175 | // mGraphicBuffer points to the buffer allocated for this slot or is NULL |
michael@0 | 176 | // if no buffer has been allocated. |
michael@0 | 177 | sp<GraphicBuffer> mGraphicBuffer; |
michael@0 | 178 | |
michael@0 | 179 | // mTextureClient is a thin abstraction over remotely allocated GraphicBuffer. |
michael@0 | 180 | mozilla::RefPtr<TextureClient> mTextureClient; |
michael@0 | 181 | |
michael@0 | 182 | // BufferState represents the different states in which a buffer slot |
michael@0 | 183 | // can be. |
michael@0 | 184 | enum BufferState { |
michael@0 | 185 | // FREE indicates that the buffer is not currently being used and |
michael@0 | 186 | // will not be used in the future until it gets dequeued and |
michael@0 | 187 | // subsequently queued by the client. |
michael@0 | 188 | FREE = 0, |
michael@0 | 189 | |
michael@0 | 190 | // DEQUEUED indicates that the buffer has been dequeued by the |
michael@0 | 191 | // client, but has not yet been queued or canceled. The buffer is |
michael@0 | 192 | // considered 'owned' by the client, and the server should not use |
michael@0 | 193 | // it for anything. |
michael@0 | 194 | // |
michael@0 | 195 | // Note that when in synchronous-mode (mSynchronousMode == true), |
michael@0 | 196 | // the buffer that's currently attached to the texture may be |
michael@0 | 197 | // dequeued by the client. That means that the current buffer can |
michael@0 | 198 | // be in either the DEQUEUED or QUEUED state. In asynchronous mode, |
michael@0 | 199 | // however, the current buffer is always in the QUEUED state. |
michael@0 | 200 | DEQUEUED = 1, |
michael@0 | 201 | |
michael@0 | 202 | // QUEUED indicates that the buffer has been queued by the client, |
michael@0 | 203 | // and has not since been made available for the client to dequeue. |
michael@0 | 204 | // Attaching the buffer to the texture does NOT transition the |
michael@0 | 205 | // buffer away from the QUEUED state. However, in Synchronous mode |
michael@0 | 206 | // the current buffer may be dequeued by the client under some |
michael@0 | 207 | // circumstances. See the note about the current buffer in the |
michael@0 | 208 | // documentation for DEQUEUED. |
michael@0 | 209 | QUEUED = 2, |
michael@0 | 210 | |
michael@0 | 211 | // RENDERING indicates that the buffer has been sent to |
michael@0 | 212 | // the compositor, and has not yet available for the |
michael@0 | 213 | // client to dequeue. When the compositor has finished its |
michael@0 | 214 | // job, the buffer will be returned to FREE state. |
michael@0 | 215 | RENDERING = 3, |
michael@0 | 216 | }; |
michael@0 | 217 | |
michael@0 | 218 | // mBufferState is the current state of this buffer slot. |
michael@0 | 219 | BufferState mBufferState; |
michael@0 | 220 | |
michael@0 | 221 | // mRequestBufferCalled is used for validating that the client did |
michael@0 | 222 | // call requestBuffer() when told to do so. Technically this is not |
michael@0 | 223 | // needed but useful for debugging and catching client bugs. |
michael@0 | 224 | bool mRequestBufferCalled; |
michael@0 | 225 | |
michael@0 | 226 | // mTimestamp is the current timestamp for this buffer slot. This gets |
michael@0 | 227 | // to set by queueBuffer each time this slot is queued. |
michael@0 | 228 | int64_t mTimestamp; |
michael@0 | 229 | |
michael@0 | 230 | // mFrameNumber is the number of the queued frame for this slot. |
michael@0 | 231 | uint64_t mFrameNumber; |
michael@0 | 232 | }; |
michael@0 | 233 | |
michael@0 | 234 | // mSlots is the array of buffer slots that must be mirrored on the client |
michael@0 | 235 | // side. This allows buffer ownership to be transferred between the client |
michael@0 | 236 | // and server without sending a GraphicBuffer over binder. The entire array |
michael@0 | 237 | // is initialized to NULL at construction time, and buffers are allocated |
michael@0 | 238 | // for a slot when requestBuffer is called with that slot's index. |
michael@0 | 239 | BufferSlot mSlots[NUM_BUFFER_SLOTS]; |
michael@0 | 240 | |
michael@0 | 241 | // mDequeueCondition condition used for dequeueBuffer in synchronous mode |
michael@0 | 242 | mutable Condition mDequeueCondition; |
michael@0 | 243 | |
michael@0 | 244 | // mAbandoned indicates that the GonkNativeWindow will no longer be used to |
michael@0 | 245 | // consume buffers pushed to it. |
michael@0 | 246 | // It is initialized to false, and set to true in the abandon method. A |
michael@0 | 247 | // GonkNativeWindow that has been abandoned will return the NO_INIT error |
michael@0 | 248 | // from all control methods capable of returning an error. |
michael@0 | 249 | bool mAbandoned; |
michael@0 | 250 | |
michael@0 | 251 | // mTimestamp is the timestamp that will be used for the next buffer queue |
michael@0 | 252 | // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that |
michael@0 | 253 | // a timestamp is auto-generated when queueBuffer is called. |
michael@0 | 254 | int64_t mTimestamp; |
michael@0 | 255 | |
michael@0 | 256 | // mDefaultWidth holds the default width of allocated buffers. It is used |
michael@0 | 257 | // in requestBuffers() if a width and height of zero is specified. |
michael@0 | 258 | uint32_t mDefaultWidth; |
michael@0 | 259 | |
michael@0 | 260 | // mDefaultHeight holds the default height of allocated buffers. It is used |
michael@0 | 261 | // in requestBuffers() if a width and height of zero is specified. |
michael@0 | 262 | uint32_t mDefaultHeight; |
michael@0 | 263 | |
michael@0 | 264 | // mPixelFormat holds the pixel format of allocated buffers. It is used |
michael@0 | 265 | // in requestBuffers() if a format of zero is specified. |
michael@0 | 266 | uint32_t mPixelFormat; |
michael@0 | 267 | |
michael@0 | 268 | // mBufferCount is the number of buffer slots that the client and server |
michael@0 | 269 | // must maintain. It defaults to MIN_BUFFER_SLOTS + 1 and can be changed |
michael@0 | 270 | // by calling setBufferCount or setBufferCountServer |
michael@0 | 271 | int mBufferCount; |
michael@0 | 272 | |
michael@0 | 273 | // mConnectedApi indicates the API that is currently connected to this |
michael@0 | 274 | // GonkNativeWindow. It defaults to NO_CONNECTED_API (= 0), and gets updated |
michael@0 | 275 | // by the connect and disconnect methods. |
michael@0 | 276 | int mConnectedApi; |
michael@0 | 277 | |
michael@0 | 278 | // mQueue is a FIFO of queued buffers used in synchronous mode |
michael@0 | 279 | // GonkNativeWindow always works in synchronous mode |
michael@0 | 280 | typedef Vector<int> Fifo; |
michael@0 | 281 | Fifo mQueue; |
michael@0 | 282 | |
michael@0 | 283 | // mMutex is the mutex used to prevent concurrent access to the member |
michael@0 | 284 | // variables of GonkNativeWindow objects. It must be locked whenever the |
michael@0 | 285 | // member variables are accessed. |
michael@0 | 286 | mutable Mutex mMutex; |
michael@0 | 287 | |
michael@0 | 288 | // mFrameCounter is the free running counter, incremented for every buffer queued |
michael@0 | 289 | uint64_t mFrameCounter; |
michael@0 | 290 | |
michael@0 | 291 | GonkNativeWindowNewFrameCallback* mNewFrameCallback; |
michael@0 | 292 | }; |
michael@0 | 293 | |
michael@0 | 294 | }; // namespace android |
michael@0 | 295 | |
michael@0 | 296 | #endif // NATIVEWINDOW_GONKNATIVEWINDOW_ICS_H |