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