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