• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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