1 /* 2 * Copyright (C) 2007 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_GRAPHIC_BUFFER_H 18 #define ANDROID_GRAPHIC_BUFFER_H 19 20 #include <stdint.h> 21 #include <sys/types.h> 22 23 #include <string> 24 #include <utility> 25 #include <vector> 26 27 #include <android/hardware_buffer.h> 28 #include <ui/ANativeObjectBase.h> 29 #include <ui/GraphicBufferMapper.h> 30 #include <ui/PixelFormat.h> 31 #include <ui/Rect.h> 32 #include <utils/Flattenable.h> 33 #include <utils/RefBase.h> 34 35 #include <nativebase/nativebase.h> 36 37 #include <hardware/gralloc.h> 38 39 namespace android { 40 41 #ifndef LIBUI_IN_VNDK 42 class BufferHubBuffer; 43 #endif // LIBUI_IN_VNDK 44 45 class GraphicBufferMapper; 46 47 using GraphicBufferDeathCallback = std::function<void(void* /*context*/, uint64_t bufferId)>; 48 49 // =========================================================================== 50 // GraphicBuffer 51 // =========================================================================== 52 53 class GraphicBuffer 54 : public ANativeObjectBase<ANativeWindowBuffer, GraphicBuffer, RefBase>, 55 public Flattenable<GraphicBuffer> 56 { 57 friend class Flattenable<GraphicBuffer>; 58 public: 59 60 enum { 61 USAGE_SW_READ_NEVER = GRALLOC_USAGE_SW_READ_NEVER, 62 USAGE_SW_READ_RARELY = GRALLOC_USAGE_SW_READ_RARELY, 63 USAGE_SW_READ_OFTEN = GRALLOC_USAGE_SW_READ_OFTEN, 64 USAGE_SW_READ_MASK = GRALLOC_USAGE_SW_READ_MASK, 65 66 USAGE_SW_WRITE_NEVER = GRALLOC_USAGE_SW_WRITE_NEVER, 67 USAGE_SW_WRITE_RARELY = GRALLOC_USAGE_SW_WRITE_RARELY, 68 USAGE_SW_WRITE_OFTEN = GRALLOC_USAGE_SW_WRITE_OFTEN, 69 USAGE_SW_WRITE_MASK = GRALLOC_USAGE_SW_WRITE_MASK, 70 71 USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK, 72 73 USAGE_PROTECTED = GRALLOC_USAGE_PROTECTED, 74 75 USAGE_HW_TEXTURE = GRALLOC_USAGE_HW_TEXTURE, 76 USAGE_HW_RENDER = GRALLOC_USAGE_HW_RENDER, 77 USAGE_HW_2D = GRALLOC_USAGE_HW_2D, 78 USAGE_HW_COMPOSER = GRALLOC_USAGE_HW_COMPOSER, 79 USAGE_HW_VIDEO_ENCODER = GRALLOC_USAGE_HW_VIDEO_ENCODER, 80 USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK, 81 82 USAGE_CURSOR = GRALLOC_USAGE_CURSOR, 83 }; 84 85 static sp<GraphicBuffer> from(ANativeWindowBuffer *); 86 87 static GraphicBuffer* fromAHardwareBuffer(AHardwareBuffer*); 88 static GraphicBuffer const* fromAHardwareBuffer(AHardwareBuffer const*); 89 AHardwareBuffer* toAHardwareBuffer(); 90 AHardwareBuffer const* toAHardwareBuffer() const; 91 92 // Create a GraphicBuffer to be unflatten'ed into or be reallocated. 93 GraphicBuffer(); 94 95 // Create a GraphicBuffer by allocating and managing a buffer internally. 96 // This function is privileged. See reallocate for details. 97 GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, 98 uint32_t inLayerCount, uint64_t inUsage, 99 std::string requestorName = "<Unknown>"); 100 101 // Create a GraphicBuffer from an existing handle. 102 enum HandleWrapMethod : uint8_t { 103 // Wrap and use the handle directly. It assumes the handle has been 104 // registered and never fails. The handle must have a longer lifetime 105 // than this wrapping GraphicBuffer. 106 // 107 // This can be used when, for example, you want to wrap a handle that 108 // is already managed by another GraphicBuffer. 109 WRAP_HANDLE, 110 111 // Take ownership of the handle and use it directly. It assumes the 112 // handle has been registered and never fails. 113 // 114 // This can be used to manage an already registered handle with 115 // GraphicBuffer. 116 TAKE_HANDLE, 117 118 // Take onwership of an unregistered handle and use it directly. It 119 // can fail when the buffer does not register. There is no ownership 120 // transfer on failures. 121 // 122 // This can be used to, for example, create a GraphicBuffer from a 123 // handle returned by Parcel::readNativeHandle. 124 TAKE_UNREGISTERED_HANDLE, 125 126 // Make a clone of the handle and use the cloned handle. It can fail 127 // when cloning fails or when the buffer does not register. There is 128 // never ownership transfer. 129 // 130 // This can be used to create a GraphicBuffer from a handle that 131 // cannot be used directly, such as one from hidl_handle. 132 CLONE_HANDLE, 133 }; 134 GraphicBuffer(const native_handle_t* inHandle, HandleWrapMethod method, uint32_t inWidth, 135 uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage, 136 uint32_t inStride); 137 138 // These functions are deprecated because they only take 32 bits of usage 139 GraphicBuffer(const native_handle_t* inHandle, HandleWrapMethod method, uint32_t inWidth, 140 uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage, 141 uint32_t inStride) 142 : GraphicBuffer(inHandle, method, inWidth, inHeight, inFormat, inLayerCount, 143 static_cast<uint64_t>(inUsage), inStride) {} 144 GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, 145 uint32_t inLayerCount, uint32_t inUsage, uint32_t inStride, 146 native_handle_t* inHandle, bool keepOwnership); 147 GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, 148 uint32_t inUsage, std::string requestorName = "<Unknown>"); 149 150 #ifndef LIBUI_IN_VNDK 151 // Create a GraphicBuffer from an existing BufferHubBuffer. 152 GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer); 153 #endif // LIBUI_IN_VNDK 154 155 // return status 156 status_t initCheck() const; 157 158 uint32_t getWidth() const { return static_cast<uint32_t>(width); } 159 uint32_t getHeight() const { return static_cast<uint32_t>(height); } 160 uint32_t getStride() const { return static_cast<uint32_t>(stride); } 161 uint64_t getUsage() const { return usage; } 162 PixelFormat getPixelFormat() const { return format; } 163 uint32_t getLayerCount() const { return static_cast<uint32_t>(layerCount); } 164 Rect getBounds() const { return Rect(width, height); } 165 uint64_t getId() const { return mId; } 166 int32_t getBufferId() const { return mBufferId; } 167 168 uint32_t getGenerationNumber() const { return mGenerationNumber; } 169 void setGenerationNumber(uint32_t generation) { 170 mGenerationNumber = generation; 171 } 172 173 // This function is privileged. It requires access to the allocator 174 // device or service, which usually involves adding suitable selinux 175 // rules. 176 status_t reallocate(uint32_t inWidth, uint32_t inHeight, 177 PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage); 178 179 bool needsReallocation(uint32_t inWidth, uint32_t inHeight, 180 PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage); 181 182 // For the following two lock functions, if bytesPerStride or bytesPerPixel 183 // are unknown or variable, -1 will be returned 184 status_t lock(uint32_t inUsage, void** vaddr, int32_t* outBytesPerPixel = nullptr, 185 int32_t* outBytesPerStride = nullptr); 186 status_t lock(uint32_t inUsage, const Rect& rect, void** vaddr, 187 int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr); 188 // For HAL_PIXEL_FORMAT_YCbCr_420_888 189 status_t lockYCbCr(uint32_t inUsage, android_ycbcr *ycbcr); 190 status_t lockYCbCr(uint32_t inUsage, const Rect& rect, 191 android_ycbcr *ycbcr); 192 status_t unlock(); 193 // For the following three lockAsync functions, if bytesPerStride or bytesPerPixel 194 // are unknown or variable, -1 will be returned 195 status_t lockAsync(uint32_t inUsage, void** vaddr, int fenceFd, 196 int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr); 197 status_t lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr, int fenceFd, 198 int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr); 199 status_t lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage, const Rect& rect, 200 void** vaddr, int fenceFd, int32_t* outBytesPerPixel = nullptr, 201 int32_t* outBytesPerStride = nullptr); 202 status_t lockAsyncYCbCr(uint32_t inUsage, android_ycbcr *ycbcr, 203 int fenceFd); 204 status_t lockAsyncYCbCr(uint32_t inUsage, const Rect& rect, 205 android_ycbcr *ycbcr, int fenceFd); 206 status_t unlockAsync(int *fenceFd); 207 208 status_t isSupported(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, 209 uint32_t inLayerCount, uint64_t inUsage, bool* outSupported) const; 210 211 ANativeWindowBuffer* getNativeBuffer() const; 212 213 // for debugging 214 static void dumpAllocationsToSystemLog(); 215 216 // Flattenable protocol 217 size_t getFlattenedSize() const; 218 size_t getFdCount() const; 219 status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; 220 status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); 221 222 GraphicBufferMapper::Version getBufferMapperVersion() const { 223 return mBufferMapper.getMapperVersion(); 224 } 225 226 void addDeathCallback(GraphicBufferDeathCallback deathCallback, void* context); 227 228 #ifndef LIBUI_IN_VNDK 229 // Returns whether this GraphicBuffer is backed by BufferHubBuffer. 230 bool isBufferHubBuffer() const; 231 #endif // LIBUI_IN_VNDK 232 233 private: 234 ~GraphicBuffer(); 235 236 enum { 237 ownNone = 0, 238 ownHandle = 1, 239 ownData = 2, 240 }; 241 242 inline const GraphicBufferMapper& getBufferMapper() const { 243 return mBufferMapper; 244 } 245 inline GraphicBufferMapper& getBufferMapper() { 246 return mBufferMapper; 247 } 248 uint8_t mOwner; 249 250 private: 251 friend class Surface; 252 friend class BpSurface; 253 friend class BnSurface; 254 friend class LightRefBase<GraphicBuffer>; 255 GraphicBuffer(const GraphicBuffer& rhs); 256 GraphicBuffer& operator = (const GraphicBuffer& rhs); 257 const GraphicBuffer& operator = (const GraphicBuffer& rhs) const; 258 259 status_t initWithSize(uint32_t inWidth, uint32_t inHeight, 260 PixelFormat inFormat, uint32_t inLayerCount, 261 uint64_t inUsage, std::string requestorName); 262 263 status_t initWithHandle(const native_handle_t* inHandle, HandleWrapMethod method, 264 uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, 265 uint32_t inLayerCount, uint64_t inUsage, uint32_t inStride); 266 267 void free_handle(); 268 269 GraphicBufferMapper& mBufferMapper; 270 ssize_t mInitCheck; 271 272 // numbers of fds/ints in native_handle_t to flatten 273 uint32_t mTransportNumFds; 274 uint32_t mTransportNumInts; 275 276 uint64_t mId; 277 278 // System unique buffer ID. Note that this is different from mId, which is process unique. For 279 // GraphicBuffer backed by BufferHub, the mBufferId is a system unique identifier that stays the 280 // same cross process for the same chunck of underlying memory. Also note that this only applies 281 // to GraphicBuffers that are backed by BufferHub. 282 int32_t mBufferId = -1; 283 284 // Stores the generation number of this buffer. If this number does not 285 // match the BufferQueue's internal generation number (set through 286 // IGBP::setGenerationNumber), attempts to attach the buffer will fail. 287 uint32_t mGenerationNumber; 288 289 // Send a callback when a GraphicBuffer dies. 290 // 291 // This is used for BufferStateLayer caching. GraphicBuffers are refcounted per process. When 292 // A GraphicBuffer doesn't have any more sp<> in a process, it is destroyed. This causes 293 // problems when trying to implicitcly cache across process boundaries. Ideally, both sides 294 // of the cache would hold onto wp<> references. When an app dropped its sp<>, the GraphicBuffer 295 // would be destroyed. Unfortunately, when SurfaceFlinger has only a wp<> reference to the 296 // GraphicBuffer, it immediately goes out of scope in the SurfaceFlinger process. SurfaceFlinger 297 // must hold onto a sp<> to the buffer. When the GraphicBuffer goes out of scope in the app's 298 // process, the client side cache will get this callback. It erases the buffer from its cache 299 // and informs SurfaceFlinger that it should drop its strong pointer reference to the buffer. 300 std::vector<std::pair<GraphicBufferDeathCallback, void* /*mDeathCallbackContext*/>> 301 mDeathCallbacks; 302 303 #ifndef LIBUI_IN_VNDK 304 // Flatten this GraphicBuffer object if backed by BufferHubBuffer. 305 status_t flattenBufferHubBuffer(void*& buffer, size_t& size) const; 306 307 // Unflatten into BufferHubBuffer backed GraphicBuffer. 308 // Unflatten will fail if the original GraphicBuffer object is destructed. For instance, a 309 // GraphicBuffer backed by BufferHubBuffer_1 flatten in process/thread A, transport the token 310 // to process/thread B through a socket, BufferHubBuffer_1 dies and bufferhub invalidated the 311 // token. Race condition occurs between the invalidation of the token in bufferhub process and 312 // process/thread B trying to unflatten and import the buffer with that token. 313 status_t unflattenBufferHubBuffer(void const*& buffer, size_t& size); 314 315 // Stores a BufferHubBuffer that handles buffer signaling, identification. 316 std::unique_ptr<BufferHubBuffer> mBufferHubBuffer; 317 #endif // LIBUI_IN_VNDK 318 }; 319 320 }; // namespace android 321 322 #endif // ANDROID_GRAPHIC_BUFFER_H 323