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; addAndGetFrameTimestamps(const NewFrameEventsEntry *,FrameEventHistoryDelta *)239 void addAndGetFrameTimestamps(const NewFrameEventsEntry*, FrameEventHistoryDelta*) override {} 240 241 // computeCurrentTransformMatrixLocked computes the transform matrix for the 242 // current texture. It uses mCurrentTransform and the current GraphicBuffer 243 // to compute this matrix and stores it in mCurrentTransformMatrix. 244 // mCurrentTextureImage must not be nullptr. 245 void computeCurrentTransformMatrixLocked(); 246 247 // getCurrentCropLocked returns the cropping rectangle of the current buffer. 248 Rect getCurrentCropLocked() const; 249 250 // The default consumer usage flags that BufferLayerConsumer always sets on its 251 // BufferQueue instance; these will be OR:d with any additional flags passed 252 // from the BufferLayerConsumer user. In particular, BufferLayerConsumer will always 253 // consume buffers as hardware textures. 254 static const uint64_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE; 255 256 // mCurrentTextureBuffer is the buffer containing the current texture. It's 257 // possible that this buffer is not associated with any buffer slot, so we 258 // must track it separately in order to support the getCurrentBuffer method. 259 std::shared_ptr<renderengine::ExternalTexture> mCurrentTextureBuffer; 260 261 // mCurrentCrop is the crop rectangle that applies to the current texture. 262 // It gets set each time updateTexImage is called. 263 Rect mCurrentCrop; 264 265 // mCurrentTransform is the transform identifier for the current texture. It 266 // gets set each time updateTexImage is called. 267 uint32_t mCurrentTransform; 268 269 // mCurrentScalingMode is the scaling mode for the current texture. It gets 270 // set each time updateTexImage is called. 271 uint32_t mCurrentScalingMode; 272 273 // mCurrentFence is the fence received from BufferQueue in updateTexImage. 274 sp<Fence> mCurrentFence; 275 276 // The FenceTime wrapper around mCurrentFence. 277 std::shared_ptr<FenceTime> mCurrentFenceTime{FenceTime::NO_FENCE}; 278 279 // mCurrentTransformMatrix is the transform matrix for the current texture. 280 // It gets computed by computeTransformMatrix each time updateTexImage is 281 // called. 282 float mCurrentTransformMatrix[16]; 283 284 // mCurrentTimestamp is the timestamp for the current texture. It 285 // gets set each time updateTexImage is called. 286 int64_t mCurrentTimestamp; 287 288 // mCurrentDataSpace is the dataspace for the current texture. It 289 // gets set each time updateTexImage is called. 290 ui::Dataspace mCurrentDataSpace; 291 292 // mCurrentHdrMetadata is the HDR metadata for the current texture. It 293 // gets set each time updateTexImage is called. 294 HdrMetadata mCurrentHdrMetadata; 295 296 // mCurrentFrameNumber is the frame counter for the current texture. 297 // It gets set each time updateTexImage is called. 298 uint64_t mCurrentFrameNumber; 299 300 // Indicates this buffer must be transformed by the inverse transform of the screen 301 // it is displayed onto. This is applied after BufferLayerConsumer::mCurrentTransform. 302 // This must be set/read from SurfaceFlinger's main thread. 303 bool mCurrentTransformToDisplayInverse; 304 305 // The portion of this surface that has changed since the previous frame 306 Region mCurrentSurfaceDamage; 307 308 int mCurrentApi; 309 310 uint32_t mDefaultWidth, mDefaultHeight; 311 312 // mFilteringEnabled indicates whether the transform matrix is computed for 313 // use with bilinear filtering. It defaults to true and is changed by 314 // setFilteringEnabled(). 315 bool mFilteringEnabled; 316 317 renderengine::RenderEngine& mRE; 318 319 // mTexName is the name of the RenderEngine texture to which streamed 320 // images will be bound when bindTexImage is called. It is set at 321 // construction time. 322 const uint32_t mTexName; 323 324 // The layer for this BufferLayerConsumer. Always check mAbandoned before accessing. 325 Layer* mLayer GUARDED_BY(mMutex); 326 327 wp<ContentsChangedListener> mContentsChangedListener; 328 329 // mCurrentTexture is the buffer slot index of the buffer that is currently 330 // bound to the RenderEngine texture. It is initialized to INVALID_BUFFER_SLOT, 331 // indicating that no buffer slot is currently bound to the texture. Note, 332 // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean 333 // that no buffer is bound to the texture. A call to setBufferCount will 334 // reset mCurrentTexture to INVALID_BUFFER_SLOT. 335 int mCurrentTexture; 336 337 // Shadow buffer cache for cleaning up renderengine references. 338 std::shared_ptr<renderengine::ExternalTexture> 339 mImages[BufferQueueDefs::NUM_BUFFER_SLOTS] GUARDED_BY(mImagesMutex); 340 341 // Separate mutex guarding the shadow buffer cache. 342 // mImagesMutex can be manipulated with binder threads (e.g. onBuffersAllocated) 343 // which is contentious enough that we can't just use mMutex. 344 mutable std::mutex mImagesMutex; 345 346 // A release that is pending on the receipt of a new release fence from 347 // presentDisplay 348 PendingRelease mPendingRelease; 349 }; 350 351 // ---------------------------------------------------------------------------- 352 }; // namespace android 353 354 #endif // ANDROID_BUFFERLAYERCONSUMER_H 355