• 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 #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