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 // getCurrentApi retrieves the API which queues the current buffer. 144 int getCurrentApi() const; 145 146 // See GLConsumer::setDefaultBufferSize. 147 status_t setDefaultBufferSize(uint32_t width, uint32_t height); 148 149 // setFilteringEnabled sets whether the transform matrix should be computed 150 // for use with bilinear filtering. 151 void setFilteringEnabled(bool enabled); 152 153 // getCurrentBuffer returns the buffer associated with the current image. 154 // When outSlot is not nullptr, the current buffer slot index is also 155 // returned. Simiarly, when outFence is not nullptr, the current output 156 // fence is returned. 157 sp<GraphicBuffer> getCurrentBuffer(int* outSlot = nullptr, sp<Fence>* outFence = 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 void onBufferAvailable(const BufferItem& item) EXCLUDES(mImagesMutex); 180 181 protected: 182 // abandonLocked overrides the ConsumerBase method to clear 183 // mCurrentTextureImage in addition to the ConsumerBase behavior. 184 virtual void abandonLocked() EXCLUDES(mImagesMutex); 185 186 // dumpLocked overrides the ConsumerBase method to dump BufferLayerConsumer- 187 // specific info in addition to the ConsumerBase behavior. 188 virtual void dumpLocked(String8& result, const char* prefix) const; 189 190 // See ConsumerBase::acquireBufferLocked 191 virtual status_t acquireBufferLocked(BufferItem* item, nsecs_t presentWhen, 192 uint64_t maxFrameNumber = 0) override 193 EXCLUDES(mImagesMutex); 194 195 bool canUseImageCrop(const Rect& crop) const; 196 197 struct PendingRelease { PendingReleasePendingRelease198 PendingRelease() : isPending(false), currentTexture(-1), graphicBuffer() {} 199 200 bool isPending; 201 int currentTexture; 202 sp<GraphicBuffer> graphicBuffer; 203 }; 204 205 // This releases the buffer in the slot referenced by mCurrentTexture, 206 // then updates state to refer to the BufferItem, which must be a 207 // newly-acquired buffer. If pendingRelease is not null, the parameters 208 // which would have been passed to releaseBufferLocked upon the successful 209 // completion of the method will instead be returned to the caller, so that 210 // it may call releaseBufferLocked itself later. 211 status_t updateAndReleaseLocked(const BufferItem& item, 212 PendingRelease* pendingRelease = nullptr) 213 EXCLUDES(mImagesMutex); 214 215 // Binds mTexName and the current buffer to TEXTURE_EXTERNAL target. 216 // If the bind succeeds, this calls doFenceWait. 217 status_t bindTextureImageLocked(); 218 219 private: 220 // Utility class for managing GraphicBuffer references into renderengine 221 class Image { 222 public: Image(sp<GraphicBuffer> graphicBuffer,renderengine::RenderEngine & engine)223 Image(sp<GraphicBuffer> graphicBuffer, renderengine::RenderEngine& engine) 224 : mGraphicBuffer(graphicBuffer), mRE(engine) {} 225 virtual ~Image(); graphicBuffer()226 const sp<GraphicBuffer>& graphicBuffer() { return mGraphicBuffer; } 227 228 private: 229 // mGraphicBuffer is the buffer that was used to create this image. 230 sp<GraphicBuffer> mGraphicBuffer; 231 // Back-reference into renderengine to initiate cleanup. 232 renderengine::RenderEngine& mRE; 233 DISALLOW_COPY_AND_ASSIGN(Image); 234 }; 235 236 // freeBufferLocked frees up the given buffer slot. If the slot has been 237 // initialized this will release the reference to the GraphicBuffer in 238 // that slot. Otherwise it has no effect. 239 // 240 // This method must be called with mMutex locked. 241 virtual void freeBufferLocked(int slotIndex) EXCLUDES(mImagesMutex); 242 243 // IConsumerListener interface 244 void onDisconnect() override; 245 void onSidebandStreamChanged() override; 246 void addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, 247 FrameEventHistoryDelta* outDelta) override; 248 249 // computeCurrentTransformMatrixLocked computes the transform matrix for the 250 // current texture. It uses mCurrentTransform and the current GraphicBuffer 251 // to compute this matrix and stores it in mCurrentTransformMatrix. 252 // mCurrentTextureImage must not be nullptr. 253 void computeCurrentTransformMatrixLocked(); 254 255 // doFenceWaitLocked inserts a wait command into the RenderEngine command 256 // stream to ensure that it is safe for future RenderEngine commands to 257 // access the current texture buffer. 258 status_t doFenceWaitLocked() const; 259 260 // getCurrentCropLocked returns the cropping rectangle of the current buffer. 261 Rect getCurrentCropLocked() const; 262 263 // The default consumer usage flags that BufferLayerConsumer always sets on its 264 // BufferQueue instance; these will be OR:d with any additional flags passed 265 // from the BufferLayerConsumer user. In particular, BufferLayerConsumer will always 266 // consume buffers as hardware textures. 267 static const uint64_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE; 268 269 // mCurrentTextureBuffer is the buffer containing the current texture. It's 270 // possible that this buffer is not associated with any buffer slot, so we 271 // must track it separately in order to support the getCurrentBuffer method. 272 std::shared_ptr<Image> mCurrentTextureBuffer; 273 274 // mCurrentCrop is the crop rectangle that applies to the current texture. 275 // It gets set each time updateTexImage is called. 276 Rect mCurrentCrop; 277 278 // mCurrentTransform is the transform identifier for the current texture. It 279 // gets set each time updateTexImage is called. 280 uint32_t mCurrentTransform; 281 282 // mCurrentScalingMode is the scaling mode for the current texture. It gets 283 // set each time updateTexImage is called. 284 uint32_t mCurrentScalingMode; 285 286 // mCurrentFence is the fence received from BufferQueue in updateTexImage. 287 sp<Fence> mCurrentFence; 288 289 // The FenceTime wrapper around mCurrentFence. 290 std::shared_ptr<FenceTime> mCurrentFenceTime{FenceTime::NO_FENCE}; 291 292 // mCurrentTransformMatrix is the transform matrix for the current texture. 293 // It gets computed by computeTransformMatrix each time updateTexImage is 294 // called. 295 float mCurrentTransformMatrix[16]; 296 297 // mCurrentTimestamp is the timestamp for the current texture. It 298 // gets set each time updateTexImage is called. 299 int64_t mCurrentTimestamp; 300 301 // mCurrentDataSpace is the dataspace for the current texture. It 302 // gets set each time updateTexImage is called. 303 ui::Dataspace mCurrentDataSpace; 304 305 // mCurrentHdrMetadata is the HDR metadata for the current texture. It 306 // gets set each time updateTexImage is called. 307 HdrMetadata mCurrentHdrMetadata; 308 309 // mCurrentFrameNumber is the frame counter for the current texture. 310 // It gets set each time updateTexImage is called. 311 uint64_t mCurrentFrameNumber; 312 313 // Indicates this buffer must be transformed by the inverse transform of the screen 314 // it is displayed onto. This is applied after BufferLayerConsumer::mCurrentTransform. 315 // This must be set/read from SurfaceFlinger's main thread. 316 bool mCurrentTransformToDisplayInverse; 317 318 // The portion of this surface that has changed since the previous frame 319 Region mCurrentSurfaceDamage; 320 321 int mCurrentApi; 322 323 uint32_t mDefaultWidth, mDefaultHeight; 324 325 // mFilteringEnabled indicates whether the transform matrix is computed for 326 // use with bilinear filtering. It defaults to true and is changed by 327 // setFilteringEnabled(). 328 bool mFilteringEnabled; 329 330 renderengine::RenderEngine& mRE; 331 332 // mTexName is the name of the RenderEngine texture to which streamed 333 // images will be bound when bindTexImage is called. It is set at 334 // construction time. 335 const uint32_t mTexName; 336 337 // The layer for this BufferLayerConsumer 338 const wp<Layer> mLayer; 339 340 wp<ContentsChangedListener> mContentsChangedListener; 341 342 // mCurrentTexture is the buffer slot index of the buffer that is currently 343 // bound to the RenderEngine texture. It is initialized to INVALID_BUFFER_SLOT, 344 // indicating that no buffer slot is currently bound to the texture. Note, 345 // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean 346 // that no buffer is bound to the texture. A call to setBufferCount will 347 // reset mCurrentTexture to INVALID_BUFFER_SLOT. 348 int mCurrentTexture; 349 350 // Shadow buffer cache for cleaning up renderengine references. 351 std::shared_ptr<Image> mImages[BufferQueueDefs::NUM_BUFFER_SLOTS] GUARDED_BY(mImagesMutex); 352 353 // Separate mutex guarding the shadow buffer cache. 354 // mImagesMutex can be manipulated with binder threads (e.g. onBuffersAllocated) 355 // which is contentious enough that we can't just use mMutex. 356 mutable std::mutex mImagesMutex; 357 358 // A release that is pending on the receipt of a new release fence from 359 // presentDisplay 360 PendingRelease mPendingRelease; 361 }; 362 363 // ---------------------------------------------------------------------------- 364 }; // namespace android 365 366 #endif // ANDROID_BUFFERLAYERCONSUMER_H 367