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