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