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_BUFFERLAYERCONSUMER_H 18 #define ANDROID_BUFFERLAYERCONSUMER_H 19 20 #include <gui/BufferQueueDefs.h> 21 #include <gui/ConsumerBase.h> 22 #include <gui/HdrMetadata.h> 23 24 #include <ui/FenceTime.h> 25 #include <ui/GraphicBuffer.h> 26 #include <ui/GraphicTypes.h> 27 #include <ui/Region.h> 28 29 #include <utils/String8.h> 30 #include <utils/Vector.h> 31 #include <utils/threads.h> 32 33 namespace android { 34 // ---------------------------------------------------------------------------- 35 36 class DispSync; 37 class Layer; 38 class String8; 39 40 namespace RE { 41 class RenderEngine; 42 class Image; 43 } // namespace RE 44 45 /* 46 * BufferLayerConsumer consumes buffers of graphics data from a BufferQueue, 47 * and makes them available to RenderEngine as a texture. 48 * 49 * A typical usage pattern is to call updateTexImage() when a new frame is 50 * desired. If a new frame is available, the frame is latched. If not, the 51 * previous contents are retained. The texture is attached and updated after 52 * bindTextureImage() is called. 53 * 54 * All calls to updateTexImage must be made with RenderEngine being current. 55 * The texture is attached to the TEXTURE_EXTERNAL texture target. 56 */ 57 class BufferLayerConsumer : public ConsumerBase { 58 public: 59 static const status_t BUFFER_REJECTED = UNKNOWN_ERROR + 8; 60 61 class BufferRejecter { 62 friend class BufferLayerConsumer; 63 virtual bool reject(const sp<GraphicBuffer>& buf, const BufferItem& item) = 0; 64 65 protected: ~BufferRejecter()66 virtual ~BufferRejecter() {} 67 }; 68 69 struct ContentsChangedListener : public FrameAvailableListener { 70 virtual void onSidebandStreamChanged() = 0; 71 }; 72 73 // BufferLayerConsumer constructs a new BufferLayerConsumer object. The 74 // tex parameter indicates the name of the RenderEngine texture to which 75 // images are to be streamed. 76 BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, RE::RenderEngine& engine, 77 uint32_t tex, Layer* layer); 78 79 // Sets the contents changed listener. This should be used instead of 80 // ConsumerBase::setFrameAvailableListener(). 81 void setContentsChangedListener(const wp<ContentsChangedListener>& listener); 82 83 nsecs_t computeExpectedPresent(const DispSync& dispSync); 84 85 // updateTexImage acquires the most recently queued buffer, and sets the 86 // image contents of the target texture to it. 87 // 88 // This call may only be made while RenderEngine is current. 89 // 90 // This calls doFenceWait to ensure proper synchronization unless native 91 // fence is supported. 92 // 93 // Unlike the GLConsumer version, this version takes a functor that may be 94 // used to reject the newly acquired buffer. It also does not bind the 95 // RenderEngine texture until bindTextureImage is called. 96 status_t updateTexImage(BufferRejecter* rejecter, const DispSync& dispSync, bool* autoRefresh, 97 bool* queuedBuffer, uint64_t maxFrameNumber); 98 99 // See BufferLayerConsumer::bindTextureImageLocked(). 100 status_t bindTextureImage(); 101 102 // setReleaseFence stores a fence that will signal when the current buffer 103 // is no longer being read. This fence will be returned to the producer 104 // when the current buffer is released by updateTexImage(). Multiple 105 // fences can be set for a given buffer; they will be merged into a single 106 // union fence. 107 void setReleaseFence(const sp<Fence>& fence); 108 109 bool releasePendingBuffer(); 110 111 sp<Fence> getPrevFinalReleaseFence() const; 112 113 // See GLConsumer::getTransformMatrix. 114 void getTransformMatrix(float mtx[16]); 115 116 // getTimestamp retrieves the timestamp associated with the texture image 117 // set by the most recent call to updateTexImage. 118 // 119 // The timestamp is in nanoseconds, and is monotonically increasing. Its 120 // other semantics (zero point, etc) are source-dependent and should be 121 // documented by the source. 122 int64_t getTimestamp(); 123 124 // getDataSpace retrieves the DataSpace associated with the texture image 125 // set by the most recent call to updateTexImage. 126 ui::Dataspace getCurrentDataSpace(); 127 128 // getCurrentHdrMetadata retrieves the HDR metadata associated with the 129 // texture image set by the most recent call to updateTexImage. 130 const HdrMetadata& getCurrentHdrMetadata() const; 131 132 // getFrameNumber retrieves the frame number associated with the texture 133 // image set by the most recent call to updateTexImage. 134 // 135 // The frame number is an incrementing counter set to 0 at the creation of 136 // the BufferQueue associated with this consumer. 137 uint64_t getFrameNumber(); 138 139 bool getTransformToDisplayInverse() const; 140 141 // must be called from SF main thread 142 const Region& getSurfaceDamage() const; 143 144 // getCurrentApi retrieves the API which queues the current buffer. 145 int getCurrentApi() const; 146 147 // See GLConsumer::setDefaultBufferSize. 148 status_t setDefaultBufferSize(uint32_t width, uint32_t height); 149 150 // setFilteringEnabled sets whether the transform matrix should be computed 151 // for use with bilinear filtering. 152 void setFilteringEnabled(bool enabled); 153 154 // getCurrentBuffer returns the buffer associated with the current image. 155 // When outSlot is not nullptr, the current buffer slot index is also 156 // returned. 157 sp<GraphicBuffer> getCurrentBuffer(int* outSlot = nullptr) const; 158 159 // getCurrentCrop returns the cropping rectangle of the current buffer. 160 Rect getCurrentCrop() const; 161 162 // getCurrentTransform returns the transform of the current buffer. 163 uint32_t getCurrentTransform() const; 164 165 // getCurrentScalingMode returns the scaling mode of the current buffer. 166 uint32_t getCurrentScalingMode() const; 167 168 // getCurrentFence returns the fence indicating when the current buffer is 169 // ready to be read from. 170 sp<Fence> getCurrentFence() const; 171 172 // getCurrentFence returns the FenceTime indicating when the current 173 // buffer is ready to be read from. 174 std::shared_ptr<FenceTime> getCurrentFenceTime() const; 175 176 // setConsumerUsageBits overrides the ConsumerBase method to OR 177 // DEFAULT_USAGE_FLAGS to usage. 178 status_t setConsumerUsageBits(uint64_t usage); 179 180 protected: 181 // abandonLocked overrides the ConsumerBase method to clear 182 // mCurrentTextureImage in addition to the ConsumerBase behavior. 183 virtual void abandonLocked(); 184 185 // dumpLocked overrides the ConsumerBase method to dump BufferLayerConsumer- 186 // specific info in addition to the ConsumerBase behavior. 187 virtual void dumpLocked(String8& result, const char* prefix) const; 188 189 // acquireBufferLocked overrides the ConsumerBase method to update the 190 // mImages array in addition to the ConsumerBase behavior. 191 virtual status_t acquireBufferLocked(BufferItem* item, nsecs_t presentWhen, 192 uint64_t maxFrameNumber = 0) override; 193 194 bool canUseImageCrop(const Rect& crop) const; 195 196 struct PendingRelease { PendingReleasePendingRelease197 PendingRelease() : isPending(false), currentTexture(-1), graphicBuffer() {} 198 199 bool isPending; 200 int currentTexture; 201 sp<GraphicBuffer> graphicBuffer; 202 }; 203 204 // This releases the buffer in the slot referenced by mCurrentTexture, 205 // then updates state to refer to the BufferItem, which must be a 206 // newly-acquired buffer. If pendingRelease is not null, the parameters 207 // which would have been passed to releaseBufferLocked upon the successful 208 // completion of the method will instead be returned to the caller, so that 209 // it may call releaseBufferLocked itself later. 210 status_t updateAndReleaseLocked(const BufferItem& item, 211 PendingRelease* pendingRelease = nullptr); 212 213 // Binds mTexName and the current buffer to TEXTURE_EXTERNAL target. Uses 214 // mCurrentTexture if it's set, mCurrentTextureImage if not. If the 215 // bind succeeds, this calls doFenceWait. 216 status_t bindTextureImageLocked(); 217 218 private: 219 // Image is a utility class for tracking and creating RE::Images. There 220 // is primarily just one image per slot, but there is also special cases: 221 // - After freeBuffer, we must still keep the current image/buffer 222 // Reference counting RE::Images lets us handle all these cases easily while 223 // also only creating new RE::Images from buffers when required. 224 class Image : public LightRefBase<Image> { 225 public: 226 Image(sp<GraphicBuffer> graphicBuffer, RE::RenderEngine& engine); 227 228 Image(const Image& rhs) = delete; 229 Image& operator=(const Image& rhs) = delete; 230 231 // createIfNeeded creates an RE::Image if required (we haven't created 232 // one yet, or the crop-rect has changed). 233 status_t createIfNeeded(const Rect& imageCrop); 234 graphicBuffer()235 const sp<GraphicBuffer>& graphicBuffer() { return mGraphicBuffer; } graphicBufferHandle()236 const native_handle* graphicBufferHandle() { 237 return mGraphicBuffer == nullptr ? nullptr : mGraphicBuffer->handle; 238 } 239 image()240 const RE::Image& image() const { return *mImage; } 241 242 private: 243 // Only allow instantiation using ref counting. 244 friend class LightRefBase<Image>; 245 virtual ~Image(); 246 247 // mGraphicBuffer is the buffer that was used to create this image. 248 sp<GraphicBuffer> mGraphicBuffer; 249 250 // mImage is the image created from mGraphicBuffer. 251 std::unique_ptr<RE::Image> mImage; 252 bool mCreated; 253 int32_t mCropWidth; 254 int32_t mCropHeight; 255 }; 256 257 // freeBufferLocked frees up the given buffer slot. If the slot has been 258 // initialized this will release the reference to the GraphicBuffer in 259 // that slot and destroy the RE::Image in that slot. Otherwise it has no 260 // effect. 261 // 262 // This method must be called with mMutex locked. 263 virtual void freeBufferLocked(int slotIndex); 264 265 // IConsumerListener interface 266 void onDisconnect() override; 267 void onSidebandStreamChanged() override; 268 void addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, 269 FrameEventHistoryDelta* outDelta) override; 270 271 // computeCurrentTransformMatrixLocked computes the transform matrix for the 272 // current texture. It uses mCurrentTransform and the current GraphicBuffer 273 // to compute this matrix and stores it in mCurrentTransformMatrix. 274 // mCurrentTextureImage must not be nullptr. 275 void computeCurrentTransformMatrixLocked(); 276 277 // doFenceWaitLocked inserts a wait command into the RenderEngine command 278 // stream to ensure that it is safe for future RenderEngine commands to 279 // access the current texture buffer. 280 status_t doFenceWaitLocked() const; 281 282 // syncForReleaseLocked performs the synchronization needed to release the 283 // current slot from RenderEngine. If needed it will set the current 284 // slot's fence to guard against a producer accessing the buffer before 285 // the outstanding accesses have completed. 286 status_t syncForReleaseLocked(); 287 288 // The default consumer usage flags that BufferLayerConsumer always sets on its 289 // BufferQueue instance; these will be OR:d with any additional flags passed 290 // from the BufferLayerConsumer user. In particular, BufferLayerConsumer will always 291 // consume buffers as hardware textures. 292 static const uint64_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE; 293 294 // mCurrentTextureImage is the Image/buffer of the current texture. It's 295 // possible that this buffer is not associated with any buffer slot, so we 296 // must track it separately in order to support the getCurrentBuffer method. 297 sp<Image> mCurrentTextureImage; 298 299 // mCurrentCrop is the crop rectangle that applies to the current texture. 300 // It gets set each time updateTexImage is called. 301 Rect mCurrentCrop; 302 303 // mCurrentTransform is the transform identifier for the current texture. It 304 // gets set each time updateTexImage is called. 305 uint32_t mCurrentTransform; 306 307 // mCurrentScalingMode is the scaling mode for the current texture. It gets 308 // set each time updateTexImage is called. 309 uint32_t mCurrentScalingMode; 310 311 // mCurrentFence is the fence received from BufferQueue in updateTexImage. 312 sp<Fence> mCurrentFence; 313 314 // The FenceTime wrapper around mCurrentFence. 315 std::shared_ptr<FenceTime> mCurrentFenceTime{FenceTime::NO_FENCE}; 316 317 // mCurrentTransformMatrix is the transform matrix for the current texture. 318 // It gets computed by computeTransformMatrix each time updateTexImage is 319 // called. 320 float mCurrentTransformMatrix[16]; 321 322 // mCurrentTimestamp is the timestamp for the current texture. It 323 // gets set each time updateTexImage is called. 324 int64_t mCurrentTimestamp; 325 326 // mCurrentDataSpace is the dataspace for the current texture. It 327 // gets set each time updateTexImage is called. 328 ui::Dataspace mCurrentDataSpace; 329 330 // mCurrentHdrMetadata is the HDR metadata for the current texture. It 331 // gets set each time updateTexImage is called. 332 HdrMetadata mCurrentHdrMetadata; 333 334 // mCurrentFrameNumber is the frame counter for the current texture. 335 // It gets set each time updateTexImage is called. 336 uint64_t mCurrentFrameNumber; 337 338 // Indicates this buffer must be transformed by the inverse transform of the screen 339 // it is displayed onto. This is applied after BufferLayerConsumer::mCurrentTransform. 340 // This must be set/read from SurfaceFlinger's main thread. 341 bool mCurrentTransformToDisplayInverse; 342 343 // The portion of this surface that has changed since the previous frame 344 Region mCurrentSurfaceDamage; 345 346 int mCurrentApi; 347 348 uint32_t mDefaultWidth, mDefaultHeight; 349 350 // mFilteringEnabled indicates whether the transform matrix is computed for 351 // use with bilinear filtering. It defaults to true and is changed by 352 // setFilteringEnabled(). 353 bool mFilteringEnabled; 354 355 RE::RenderEngine& mRE; 356 357 // mTexName is the name of the RenderEngine texture to which streamed 358 // images will be bound when bindTexImage is called. It is set at 359 // construction time. 360 const uint32_t mTexName; 361 362 // The layer for this BufferLayerConsumer 363 const wp<Layer> mLayer; 364 365 wp<ContentsChangedListener> mContentsChangedListener; 366 367 // mImages stores the buffers that have been allocated by the BufferQueue 368 // for each buffer slot. It is initialized to null pointers, and gets 369 // filled in with the result of BufferQueue::acquire when the 370 // client dequeues a buffer from a 371 // slot that has not yet been used. The buffer allocated to a slot will also 372 // be replaced if the requested buffer usage or geometry differs from that 373 // of the buffer allocated to a slot. 374 sp<Image> mImages[BufferQueueDefs::NUM_BUFFER_SLOTS]; 375 376 // mCurrentTexture is the buffer slot index of the buffer that is currently 377 // bound to the RenderEngine texture. It is initialized to INVALID_BUFFER_SLOT, 378 // indicating that no buffer slot is currently bound to the texture. Note, 379 // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean 380 // that no buffer is bound to the texture. A call to setBufferCount will 381 // reset mCurrentTexture to INVALID_BUFFER_SLOT. 382 int mCurrentTexture; 383 384 // A release that is pending on the receipt of a new release fence from 385 // presentDisplay 386 PendingRelease mPendingRelease; 387 }; 388 389 // ---------------------------------------------------------------------------- 390 }; // namespace android 391 392 #endif // ANDROID_BUFFERLAYERCONSUMER_H 393