1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "ConsumerBase"
18*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19*38e8c45fSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
20*38e8c45fSAndroid Build Coastguard Worker
21*38e8c45fSAndroid Build Coastguard Worker #define EGL_EGLEXT_PROTOTYPES
22*38e8c45fSAndroid Build Coastguard Worker
23*38e8c45fSAndroid Build Coastguard Worker #include <EGL/egl.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <EGL/eglext.h>
25*38e8c45fSAndroid Build Coastguard Worker
26*38e8c45fSAndroid Build Coastguard Worker #include <hardware/hardware.h>
27*38e8c45fSAndroid Build Coastguard Worker
28*38e8c45fSAndroid Build Coastguard Worker #include <cutils/atomic.h>
29*38e8c45fSAndroid Build Coastguard Worker
30*38e8c45fSAndroid Build Coastguard Worker #include <com_android_graphics_libgui_flags.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <gui/BufferItem.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <gui/BufferQueue.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <gui/ConsumerBase.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <gui/ISurfaceComposer.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <gui/Surface.h>
36*38e8c45fSAndroid Build Coastguard Worker #include <gui/SurfaceComposerClient.h>
37*38e8c45fSAndroid Build Coastguard Worker
38*38e8c45fSAndroid Build Coastguard Worker #include <private/gui/ComposerService.h>
39*38e8c45fSAndroid Build Coastguard Worker
40*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
41*38e8c45fSAndroid Build Coastguard Worker #include <utils/Log.h>
42*38e8c45fSAndroid Build Coastguard Worker #include <utils/String8.h>
43*38e8c45fSAndroid Build Coastguard Worker #include <utils/Trace.h>
44*38e8c45fSAndroid Build Coastguard Worker
45*38e8c45fSAndroid Build Coastguard Worker #include <inttypes.h>
46*38e8c45fSAndroid Build Coastguard Worker
47*38e8c45fSAndroid Build Coastguard Worker // Macros for including the ConsumerBase name in log messages
48*38e8c45fSAndroid Build Coastguard Worker #define CB_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
49*38e8c45fSAndroid Build Coastguard Worker // #define CB_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
50*38e8c45fSAndroid Build Coastguard Worker // #define CB_LOGI(x, ...) ALOGI("[%s] " x, mName.c_str(), ##__VA_ARGS__)
51*38e8c45fSAndroid Build Coastguard Worker // #define CB_LOGW(x, ...) ALOGW("[%s] " x, mName.c_str(), ##__VA_ARGS__)
52*38e8c45fSAndroid Build Coastguard Worker #define CB_LOGE(x, ...) ALOGE("[%s] " x, mName.c_str(), ##__VA_ARGS__)
53*38e8c45fSAndroid Build Coastguard Worker
54*38e8c45fSAndroid Build Coastguard Worker namespace android {
55*38e8c45fSAndroid Build Coastguard Worker
56*38e8c45fSAndroid Build Coastguard Worker // Get an ID that's unique within this process.
createProcessUniqueId()57*38e8c45fSAndroid Build Coastguard Worker static int32_t createProcessUniqueId() {
58*38e8c45fSAndroid Build Coastguard Worker static volatile int32_t globalCounter = 0;
59*38e8c45fSAndroid Build Coastguard Worker return android_atomic_inc(&globalCounter);
60*38e8c45fSAndroid Build Coastguard Worker }
61*38e8c45fSAndroid Build Coastguard Worker
ConsumerBase(const sp<IGraphicBufferConsumer> & bufferQueue,bool controlledByApp)62*38e8c45fSAndroid Build Coastguard Worker ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
63*38e8c45fSAndroid Build Coastguard Worker mAbandoned(false),
64*38e8c45fSAndroid Build Coastguard Worker mConsumer(bufferQueue),
65*38e8c45fSAndroid Build Coastguard Worker mPrevFinalReleaseFence(Fence::NO_FENCE) {
66*38e8c45fSAndroid Build Coastguard Worker initialize(controlledByApp);
67*38e8c45fSAndroid Build Coastguard Worker }
68*38e8c45fSAndroid Build Coastguard Worker
69*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
ConsumerBase(bool controlledByApp,bool consumerIsSurfaceFlinger)70*38e8c45fSAndroid Build Coastguard Worker ConsumerBase::ConsumerBase(bool controlledByApp, bool consumerIsSurfaceFlinger)
71*38e8c45fSAndroid Build Coastguard Worker : mAbandoned(false), mPrevFinalReleaseFence(Fence::NO_FENCE) {
72*38e8c45fSAndroid Build Coastguard Worker sp<IGraphicBufferProducer> producer;
73*38e8c45fSAndroid Build Coastguard Worker BufferQueue::createBufferQueue(&producer, &mConsumer, consumerIsSurfaceFlinger);
74*38e8c45fSAndroid Build Coastguard Worker mSurface = sp<Surface>::make(producer, controlledByApp);
75*38e8c45fSAndroid Build Coastguard Worker initialize(controlledByApp);
76*38e8c45fSAndroid Build Coastguard Worker }
77*38e8c45fSAndroid Build Coastguard Worker
ConsumerBase(const sp<IGraphicBufferProducer> & producer,const sp<IGraphicBufferConsumer> & consumer,bool controlledByApp)78*38e8c45fSAndroid Build Coastguard Worker ConsumerBase::ConsumerBase(const sp<IGraphicBufferProducer>& producer,
79*38e8c45fSAndroid Build Coastguard Worker const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp)
80*38e8c45fSAndroid Build Coastguard Worker : mAbandoned(false),
81*38e8c45fSAndroid Build Coastguard Worker mConsumer(consumer),
82*38e8c45fSAndroid Build Coastguard Worker mSurface(sp<Surface>::make(producer, controlledByApp)),
83*38e8c45fSAndroid Build Coastguard Worker mPrevFinalReleaseFence(Fence::NO_FENCE) {
84*38e8c45fSAndroid Build Coastguard Worker initialize(controlledByApp);
85*38e8c45fSAndroid Build Coastguard Worker }
86*38e8c45fSAndroid Build Coastguard Worker
87*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
88*38e8c45fSAndroid Build Coastguard Worker
initialize(bool controlledByApp)89*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::initialize(bool controlledByApp) {
90*38e8c45fSAndroid Build Coastguard Worker // Choose a name using the PID and a process-unique ID.
91*38e8c45fSAndroid Build Coastguard Worker mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
92*38e8c45fSAndroid Build Coastguard Worker
93*38e8c45fSAndroid Build Coastguard Worker // Note that we can't create an sp<...>(this) in a ctor that will not keep a
94*38e8c45fSAndroid Build Coastguard Worker // reference once the ctor ends, as that would cause the refcount of 'this'
95*38e8c45fSAndroid Build Coastguard Worker // dropping to 0 at the end of the ctor. Since all we need is a wp<...>
96*38e8c45fSAndroid Build Coastguard Worker // that's what we create.
97*38e8c45fSAndroid Build Coastguard Worker wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
98*38e8c45fSAndroid Build Coastguard Worker sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
99*38e8c45fSAndroid Build Coastguard Worker
100*38e8c45fSAndroid Build Coastguard Worker status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
101*38e8c45fSAndroid Build Coastguard Worker if (err != NO_ERROR) {
102*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)",
103*38e8c45fSAndroid Build Coastguard Worker strerror(-err), err);
104*38e8c45fSAndroid Build Coastguard Worker } else {
105*38e8c45fSAndroid Build Coastguard Worker mConsumer->setConsumerName(mName);
106*38e8c45fSAndroid Build Coastguard Worker }
107*38e8c45fSAndroid Build Coastguard Worker }
108*38e8c45fSAndroid Build Coastguard Worker
~ConsumerBase()109*38e8c45fSAndroid Build Coastguard Worker ConsumerBase::~ConsumerBase() {
110*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("~ConsumerBase");
111*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
112*38e8c45fSAndroid Build Coastguard Worker
113*38e8c45fSAndroid Build Coastguard Worker // Verify that abandon() has been called before we get here. This should
114*38e8c45fSAndroid Build Coastguard Worker // be done by ConsumerBase::onLastStrongRef(), but it's possible for a
115*38e8c45fSAndroid Build Coastguard Worker // derived class to override that method and not call
116*38e8c45fSAndroid Build Coastguard Worker // ConsumerBase::onLastStrongRef().
117*38e8c45fSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(!mAbandoned,
118*38e8c45fSAndroid Build Coastguard Worker "[%s] ~ConsumerBase was called, but the "
119*38e8c45fSAndroid Build Coastguard Worker "consumer is not abandoned!",
120*38e8c45fSAndroid Build Coastguard Worker mName.c_str());
121*38e8c45fSAndroid Build Coastguard Worker }
122*38e8c45fSAndroid Build Coastguard Worker
onLastStrongRef(const void * id)123*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::onLastStrongRef(const void* id __attribute__((unused))) {
124*38e8c45fSAndroid Build Coastguard Worker abandon();
125*38e8c45fSAndroid Build Coastguard Worker }
126*38e8c45fSAndroid Build Coastguard Worker
getSlotForBufferLocked(const sp<GraphicBuffer> & buffer)127*38e8c45fSAndroid Build Coastguard Worker int ConsumerBase::getSlotForBufferLocked(const sp<GraphicBuffer>& buffer) {
128*38e8c45fSAndroid Build Coastguard Worker if (!buffer) {
129*38e8c45fSAndroid Build Coastguard Worker return BufferQueue::INVALID_BUFFER_SLOT;
130*38e8c45fSAndroid Build Coastguard Worker }
131*38e8c45fSAndroid Build Coastguard Worker
132*38e8c45fSAndroid Build Coastguard Worker uint64_t id = buffer->getId();
133*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) {
134*38e8c45fSAndroid Build Coastguard Worker auto& slot = mSlots[i];
135*38e8c45fSAndroid Build Coastguard Worker if (slot.mGraphicBuffer && slot.mGraphicBuffer->getId() == id) {
136*38e8c45fSAndroid Build Coastguard Worker return i;
137*38e8c45fSAndroid Build Coastguard Worker }
138*38e8c45fSAndroid Build Coastguard Worker }
139*38e8c45fSAndroid Build Coastguard Worker
140*38e8c45fSAndroid Build Coastguard Worker return BufferQueue::INVALID_BUFFER_SLOT;
141*38e8c45fSAndroid Build Coastguard Worker }
142*38e8c45fSAndroid Build Coastguard Worker
detachBufferLocked(int slotIndex)143*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::detachBufferLocked(int slotIndex) {
144*38e8c45fSAndroid Build Coastguard Worker status_t result = mConsumer->detachBuffer(slotIndex);
145*38e8c45fSAndroid Build Coastguard Worker
146*38e8c45fSAndroid Build Coastguard Worker if (result != NO_ERROR) {
147*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("Failed to detach buffer: %d", result);
148*38e8c45fSAndroid Build Coastguard Worker return result;
149*38e8c45fSAndroid Build Coastguard Worker }
150*38e8c45fSAndroid Build Coastguard Worker
151*38e8c45fSAndroid Build Coastguard Worker freeBufferLocked(slotIndex);
152*38e8c45fSAndroid Build Coastguard Worker
153*38e8c45fSAndroid Build Coastguard Worker return result;
154*38e8c45fSAndroid Build Coastguard Worker }
155*38e8c45fSAndroid Build Coastguard Worker
freeBufferLocked(int slotIndex)156*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::freeBufferLocked(int slotIndex) {
157*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
158*38e8c45fSAndroid Build Coastguard Worker mSlots[slotIndex].mGraphicBuffer = nullptr;
159*38e8c45fSAndroid Build Coastguard Worker mSlots[slotIndex].mFence = Fence::NO_FENCE;
160*38e8c45fSAndroid Build Coastguard Worker mSlots[slotIndex].mFrameNumber = 0;
161*38e8c45fSAndroid Build Coastguard Worker }
162*38e8c45fSAndroid Build Coastguard Worker
onFrameDequeued(const uint64_t bufferId)163*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::onFrameDequeued(const uint64_t bufferId) {
164*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("onFrameDequeued");
165*38e8c45fSAndroid Build Coastguard Worker
166*38e8c45fSAndroid Build Coastguard Worker sp<FrameAvailableListener> listener;
167*38e8c45fSAndroid Build Coastguard Worker {
168*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mFrameAvailableMutex);
169*38e8c45fSAndroid Build Coastguard Worker listener = mFrameAvailableListener.promote();
170*38e8c45fSAndroid Build Coastguard Worker }
171*38e8c45fSAndroid Build Coastguard Worker
172*38e8c45fSAndroid Build Coastguard Worker if (listener != nullptr) {
173*38e8c45fSAndroid Build Coastguard Worker listener->onFrameDequeued(bufferId);
174*38e8c45fSAndroid Build Coastguard Worker }
175*38e8c45fSAndroid Build Coastguard Worker }
176*38e8c45fSAndroid Build Coastguard Worker
onFrameCancelled(const uint64_t bufferId)177*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::onFrameCancelled(const uint64_t bufferId) {
178*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("onFrameCancelled");
179*38e8c45fSAndroid Build Coastguard Worker
180*38e8c45fSAndroid Build Coastguard Worker sp<FrameAvailableListener> listener;
181*38e8c45fSAndroid Build Coastguard Worker {
182*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mFrameAvailableMutex);
183*38e8c45fSAndroid Build Coastguard Worker listener = mFrameAvailableListener.promote();
184*38e8c45fSAndroid Build Coastguard Worker }
185*38e8c45fSAndroid Build Coastguard Worker
186*38e8c45fSAndroid Build Coastguard Worker if (listener != nullptr) {
187*38e8c45fSAndroid Build Coastguard Worker listener->onFrameCancelled(bufferId);
188*38e8c45fSAndroid Build Coastguard Worker }
189*38e8c45fSAndroid Build Coastguard Worker }
190*38e8c45fSAndroid Build Coastguard Worker
onFrameDetached(const uint64_t bufferId)191*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::onFrameDetached(const uint64_t bufferId) {
192*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("onFrameDetached");
193*38e8c45fSAndroid Build Coastguard Worker
194*38e8c45fSAndroid Build Coastguard Worker sp<FrameAvailableListener> listener;
195*38e8c45fSAndroid Build Coastguard Worker {
196*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mFrameAvailableMutex);
197*38e8c45fSAndroid Build Coastguard Worker listener = mFrameAvailableListener.promote();
198*38e8c45fSAndroid Build Coastguard Worker }
199*38e8c45fSAndroid Build Coastguard Worker
200*38e8c45fSAndroid Build Coastguard Worker if (listener != nullptr) {
201*38e8c45fSAndroid Build Coastguard Worker listener->onFrameDetached(bufferId);
202*38e8c45fSAndroid Build Coastguard Worker }
203*38e8c45fSAndroid Build Coastguard Worker }
204*38e8c45fSAndroid Build Coastguard Worker
onFrameAvailable(const BufferItem & item)205*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::onFrameAvailable(const BufferItem& item) {
206*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("onFrameAvailable");
207*38e8c45fSAndroid Build Coastguard Worker
208*38e8c45fSAndroid Build Coastguard Worker sp<FrameAvailableListener> listener;
209*38e8c45fSAndroid Build Coastguard Worker { // scope for the lock
210*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mFrameAvailableMutex);
211*38e8c45fSAndroid Build Coastguard Worker listener = mFrameAvailableListener.promote();
212*38e8c45fSAndroid Build Coastguard Worker }
213*38e8c45fSAndroid Build Coastguard Worker
214*38e8c45fSAndroid Build Coastguard Worker if (listener != nullptr) {
215*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("actually calling onFrameAvailable");
216*38e8c45fSAndroid Build Coastguard Worker listener->onFrameAvailable(item);
217*38e8c45fSAndroid Build Coastguard Worker }
218*38e8c45fSAndroid Build Coastguard Worker }
219*38e8c45fSAndroid Build Coastguard Worker
onFrameReplaced(const BufferItem & item)220*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::onFrameReplaced(const BufferItem &item) {
221*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("onFrameReplaced");
222*38e8c45fSAndroid Build Coastguard Worker
223*38e8c45fSAndroid Build Coastguard Worker sp<FrameAvailableListener> listener;
224*38e8c45fSAndroid Build Coastguard Worker {
225*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mFrameAvailableMutex);
226*38e8c45fSAndroid Build Coastguard Worker listener = mFrameAvailableListener.promote();
227*38e8c45fSAndroid Build Coastguard Worker }
228*38e8c45fSAndroid Build Coastguard Worker
229*38e8c45fSAndroid Build Coastguard Worker if (listener != nullptr) {
230*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("actually calling onFrameReplaced");
231*38e8c45fSAndroid Build Coastguard Worker listener->onFrameReplaced(item);
232*38e8c45fSAndroid Build Coastguard Worker }
233*38e8c45fSAndroid Build Coastguard Worker }
234*38e8c45fSAndroid Build Coastguard Worker
onBuffersReleased()235*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::onBuffersReleased() {
236*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
237*38e8c45fSAndroid Build Coastguard Worker
238*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("onBuffersReleased");
239*38e8c45fSAndroid Build Coastguard Worker
240*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
241*38e8c45fSAndroid Build Coastguard Worker // Nothing to do if we're already abandoned.
242*38e8c45fSAndroid Build Coastguard Worker return;
243*38e8c45fSAndroid Build Coastguard Worker }
244*38e8c45fSAndroid Build Coastguard Worker
245*38e8c45fSAndroid Build Coastguard Worker uint64_t mask = 0;
246*38e8c45fSAndroid Build Coastguard Worker mConsumer->getReleasedBuffers(&mask);
247*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
248*38e8c45fSAndroid Build Coastguard Worker if (mask & (1ULL << i)) {
249*38e8c45fSAndroid Build Coastguard Worker freeBufferLocked(i);
250*38e8c45fSAndroid Build Coastguard Worker }
251*38e8c45fSAndroid Build Coastguard Worker }
252*38e8c45fSAndroid Build Coastguard Worker }
253*38e8c45fSAndroid Build Coastguard Worker
onSidebandStreamChanged()254*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::onSidebandStreamChanged() {
255*38e8c45fSAndroid Build Coastguard Worker }
256*38e8c45fSAndroid Build Coastguard Worker
abandon()257*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::abandon() {
258*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("abandon");
259*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
260*38e8c45fSAndroid Build Coastguard Worker
261*38e8c45fSAndroid Build Coastguard Worker if (!mAbandoned) {
262*38e8c45fSAndroid Build Coastguard Worker abandonLocked();
263*38e8c45fSAndroid Build Coastguard Worker mAbandoned = true;
264*38e8c45fSAndroid Build Coastguard Worker }
265*38e8c45fSAndroid Build Coastguard Worker }
266*38e8c45fSAndroid Build Coastguard Worker
abandonLocked()267*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::abandonLocked() {
268*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("abandonLocked");
269*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
270*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("abandonLocked: ConsumerBase is abandoned!");
271*38e8c45fSAndroid Build Coastguard Worker return;
272*38e8c45fSAndroid Build Coastguard Worker }
273*38e8c45fSAndroid Build Coastguard Worker for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
274*38e8c45fSAndroid Build Coastguard Worker freeBufferLocked(i);
275*38e8c45fSAndroid Build Coastguard Worker }
276*38e8c45fSAndroid Build Coastguard Worker // disconnect from the BufferQueue
277*38e8c45fSAndroid Build Coastguard Worker mConsumer->consumerDisconnect();
278*38e8c45fSAndroid Build Coastguard Worker mConsumer.clear();
279*38e8c45fSAndroid Build Coastguard Worker }
280*38e8c45fSAndroid Build Coastguard Worker
isAbandoned()281*38e8c45fSAndroid Build Coastguard Worker bool ConsumerBase::isAbandoned() {
282*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock _l(mMutex);
283*38e8c45fSAndroid Build Coastguard Worker return mAbandoned;
284*38e8c45fSAndroid Build Coastguard Worker }
285*38e8c45fSAndroid Build Coastguard Worker
setName(const String8 & name)286*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::setName(const String8& name) {
287*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock _l(mMutex);
288*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
289*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("setName: ConsumerBase is abandoned!");
290*38e8c45fSAndroid Build Coastguard Worker return;
291*38e8c45fSAndroid Build Coastguard Worker }
292*38e8c45fSAndroid Build Coastguard Worker mName = name;
293*38e8c45fSAndroid Build Coastguard Worker mConsumer->setConsumerName(name);
294*38e8c45fSAndroid Build Coastguard Worker }
295*38e8c45fSAndroid Build Coastguard Worker
setFrameAvailableListener(const wp<FrameAvailableListener> & listener)296*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::setFrameAvailableListener(
297*38e8c45fSAndroid Build Coastguard Worker const wp<FrameAvailableListener>& listener) {
298*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("setFrameAvailableListener");
299*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mFrameAvailableMutex);
300*38e8c45fSAndroid Build Coastguard Worker mFrameAvailableListener = listener;
301*38e8c45fSAndroid Build Coastguard Worker }
302*38e8c45fSAndroid Build Coastguard Worker
detachBuffer(int slot)303*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::detachBuffer(int slot) {
304*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("detachBuffer");
305*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
306*38e8c45fSAndroid Build Coastguard Worker
307*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
308*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("detachBuffer: ConsumerBase is abandoned!");
309*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
310*38e8c45fSAndroid Build Coastguard Worker }
311*38e8c45fSAndroid Build Coastguard Worker
312*38e8c45fSAndroid Build Coastguard Worker return detachBufferLocked(slot);
313*38e8c45fSAndroid Build Coastguard Worker }
314*38e8c45fSAndroid Build Coastguard Worker
315*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
detachBuffer(const sp<GraphicBuffer> & buffer)316*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::detachBuffer(const sp<GraphicBuffer>& buffer) {
317*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("detachBuffer");
318*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
319*38e8c45fSAndroid Build Coastguard Worker
320*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
321*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("detachBuffer: ConsumerBase is abandoned!");
322*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
323*38e8c45fSAndroid Build Coastguard Worker }
324*38e8c45fSAndroid Build Coastguard Worker if (buffer == nullptr) {
325*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
326*38e8c45fSAndroid Build Coastguard Worker }
327*38e8c45fSAndroid Build Coastguard Worker
328*38e8c45fSAndroid Build Coastguard Worker int slotIndex = getSlotForBufferLocked(buffer);
329*38e8c45fSAndroid Build Coastguard Worker if (slotIndex == BufferQueue::INVALID_BUFFER_SLOT) {
330*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
331*38e8c45fSAndroid Build Coastguard Worker }
332*38e8c45fSAndroid Build Coastguard Worker
333*38e8c45fSAndroid Build Coastguard Worker return detachBufferLocked(slotIndex);
334*38e8c45fSAndroid Build Coastguard Worker }
335*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
336*38e8c45fSAndroid Build Coastguard Worker
setDefaultBufferSize(uint32_t width,uint32_t height)337*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::setDefaultBufferSize(uint32_t width, uint32_t height) {
338*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock _l(mMutex);
339*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
340*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("setDefaultBufferSize: ConsumerBase is abandoned!");
341*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
342*38e8c45fSAndroid Build Coastguard Worker }
343*38e8c45fSAndroid Build Coastguard Worker return mConsumer->setDefaultBufferSize(width, height);
344*38e8c45fSAndroid Build Coastguard Worker }
345*38e8c45fSAndroid Build Coastguard Worker
setDefaultBufferFormat(PixelFormat defaultFormat)346*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::setDefaultBufferFormat(PixelFormat defaultFormat) {
347*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock _l(mMutex);
348*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
349*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("setDefaultBufferFormat: ConsumerBase is abandoned!");
350*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
351*38e8c45fSAndroid Build Coastguard Worker }
352*38e8c45fSAndroid Build Coastguard Worker return mConsumer->setDefaultBufferFormat(defaultFormat);
353*38e8c45fSAndroid Build Coastguard Worker }
354*38e8c45fSAndroid Build Coastguard Worker
setDefaultBufferDataSpace(android_dataspace defaultDataSpace)355*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::setDefaultBufferDataSpace(
356*38e8c45fSAndroid Build Coastguard Worker android_dataspace defaultDataSpace) {
357*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock _l(mMutex);
358*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
359*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("setDefaultBufferDataSpace: ConsumerBase is abandoned!");
360*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
361*38e8c45fSAndroid Build Coastguard Worker }
362*38e8c45fSAndroid Build Coastguard Worker return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
363*38e8c45fSAndroid Build Coastguard Worker }
364*38e8c45fSAndroid Build Coastguard Worker
setConsumerUsageBits(uint64_t usage)365*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::setConsumerUsageBits(uint64_t usage) {
366*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
367*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
368*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("setConsumerUsageBits: ConsumerBase is abandoned!");
369*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
370*38e8c45fSAndroid Build Coastguard Worker }
371*38e8c45fSAndroid Build Coastguard Worker return mConsumer->setConsumerUsageBits(usage);
372*38e8c45fSAndroid Build Coastguard Worker }
373*38e8c45fSAndroid Build Coastguard Worker
setTransformHint(uint32_t hint)374*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::setTransformHint(uint32_t hint) {
375*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
376*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
377*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("setTransformHint: ConsumerBase is abandoned!");
378*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
379*38e8c45fSAndroid Build Coastguard Worker }
380*38e8c45fSAndroid Build Coastguard Worker return mConsumer->setTransformHint(hint);
381*38e8c45fSAndroid Build Coastguard Worker }
382*38e8c45fSAndroid Build Coastguard Worker
383*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
setMaxBufferCount(int bufferCount)384*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::setMaxBufferCount(int bufferCount) {
385*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
386*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
387*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("setMaxBufferCount: ConsumerBase is abandoned!");
388*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
389*38e8c45fSAndroid Build Coastguard Worker }
390*38e8c45fSAndroid Build Coastguard Worker return mConsumer->setMaxBufferCount(bufferCount);
391*38e8c45fSAndroid Build Coastguard Worker }
392*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
393*38e8c45fSAndroid Build Coastguard Worker
setMaxAcquiredBufferCount(int maxAcquiredBuffers)394*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
395*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
396*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
397*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("setMaxAcquiredBufferCount: ConsumerBase is abandoned!");
398*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
399*38e8c45fSAndroid Build Coastguard Worker }
400*38e8c45fSAndroid Build Coastguard Worker return mConsumer->setMaxAcquiredBufferCount(maxAcquiredBuffers);
401*38e8c45fSAndroid Build Coastguard Worker }
402*38e8c45fSAndroid Build Coastguard Worker
403*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
setConsumerIsProtected(bool isProtected)404*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::setConsumerIsProtected(bool isProtected) {
405*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
406*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
407*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("setConsumerIsProtected: ConsumerBase is abandoned!");
408*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
409*38e8c45fSAndroid Build Coastguard Worker }
410*38e8c45fSAndroid Build Coastguard Worker return mConsumer->setConsumerIsProtected(isProtected);
411*38e8c45fSAndroid Build Coastguard Worker }
412*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
413*38e8c45fSAndroid Build Coastguard Worker
getSidebandStream() const414*38e8c45fSAndroid Build Coastguard Worker sp<NativeHandle> ConsumerBase::getSidebandStream() const {
415*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock _l(mMutex);
416*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
417*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("getSidebandStream: ConsumerBase is abandoned!");
418*38e8c45fSAndroid Build Coastguard Worker return nullptr;
419*38e8c45fSAndroid Build Coastguard Worker }
420*38e8c45fSAndroid Build Coastguard Worker
421*38e8c45fSAndroid Build Coastguard Worker sp<NativeHandle> stream;
422*38e8c45fSAndroid Build Coastguard Worker status_t err = mConsumer->getSidebandStream(&stream);
423*38e8c45fSAndroid Build Coastguard Worker if (err != NO_ERROR) {
424*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("failed to get sideband stream: %d", err);
425*38e8c45fSAndroid Build Coastguard Worker return nullptr;
426*38e8c45fSAndroid Build Coastguard Worker }
427*38e8c45fSAndroid Build Coastguard Worker
428*38e8c45fSAndroid Build Coastguard Worker return stream;
429*38e8c45fSAndroid Build Coastguard Worker }
430*38e8c45fSAndroid Build Coastguard Worker
getOccupancyHistory(bool forceFlush,std::vector<OccupancyTracker::Segment> * outHistory)431*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::getOccupancyHistory(bool forceFlush,
432*38e8c45fSAndroid Build Coastguard Worker std::vector<OccupancyTracker::Segment>* outHistory) {
433*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock _l(mMutex);
434*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
435*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("getOccupancyHistory: ConsumerBase is abandoned!");
436*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
437*38e8c45fSAndroid Build Coastguard Worker }
438*38e8c45fSAndroid Build Coastguard Worker return mConsumer->getOccupancyHistory(forceFlush, outHistory);
439*38e8c45fSAndroid Build Coastguard Worker }
440*38e8c45fSAndroid Build Coastguard Worker
discardFreeBuffers()441*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::discardFreeBuffers() {
442*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock _l(mMutex);
443*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
444*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("discardFreeBuffers: ConsumerBase is abandoned!");
445*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
446*38e8c45fSAndroid Build Coastguard Worker }
447*38e8c45fSAndroid Build Coastguard Worker status_t err = mConsumer->discardFreeBuffers();
448*38e8c45fSAndroid Build Coastguard Worker if (err != OK) {
449*38e8c45fSAndroid Build Coastguard Worker return err;
450*38e8c45fSAndroid Build Coastguard Worker }
451*38e8c45fSAndroid Build Coastguard Worker uint64_t mask;
452*38e8c45fSAndroid Build Coastguard Worker mConsumer->getReleasedBuffers(&mask);
453*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
454*38e8c45fSAndroid Build Coastguard Worker if (mask & (1ULL << i)) {
455*38e8c45fSAndroid Build Coastguard Worker freeBufferLocked(i);
456*38e8c45fSAndroid Build Coastguard Worker }
457*38e8c45fSAndroid Build Coastguard Worker }
458*38e8c45fSAndroid Build Coastguard Worker return OK;
459*38e8c45fSAndroid Build Coastguard Worker }
460*38e8c45fSAndroid Build Coastguard Worker
dumpState(String8 & result) const461*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::dumpState(String8& result) const {
462*38e8c45fSAndroid Build Coastguard Worker dumpState(result, "");
463*38e8c45fSAndroid Build Coastguard Worker }
464*38e8c45fSAndroid Build Coastguard Worker
dumpState(String8 & result,const char * prefix) const465*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::dumpState(String8& result, const char* prefix) const {
466*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock _l(mMutex);
467*38e8c45fSAndroid Build Coastguard Worker dumpLocked(result, prefix);
468*38e8c45fSAndroid Build Coastguard Worker }
469*38e8c45fSAndroid Build Coastguard Worker
dumpLocked(String8 & result,const char * prefix) const470*38e8c45fSAndroid Build Coastguard Worker void ConsumerBase::dumpLocked(String8& result, const char* prefix) const {
471*38e8c45fSAndroid Build Coastguard Worker result.appendFormat("%smAbandoned=%d\n", prefix, int(mAbandoned));
472*38e8c45fSAndroid Build Coastguard Worker
473*38e8c45fSAndroid Build Coastguard Worker if (!mAbandoned) {
474*38e8c45fSAndroid Build Coastguard Worker String8 consumerState;
475*38e8c45fSAndroid Build Coastguard Worker mConsumer->dumpState(String8(prefix), &consumerState);
476*38e8c45fSAndroid Build Coastguard Worker result.append(consumerState);
477*38e8c45fSAndroid Build Coastguard Worker }
478*38e8c45fSAndroid Build Coastguard Worker }
479*38e8c45fSAndroid Build Coastguard Worker
480*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
getSurface() const481*38e8c45fSAndroid Build Coastguard Worker sp<Surface> ConsumerBase::getSurface() const {
482*38e8c45fSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(mSurface == nullptr,
483*38e8c45fSAndroid Build Coastguard Worker "It's illegal to get the surface of a Consumer that does not own it. This "
484*38e8c45fSAndroid Build Coastguard Worker "should be impossible once the old CTOR is removed.");
485*38e8c45fSAndroid Build Coastguard Worker return mSurface;
486*38e8c45fSAndroid Build Coastguard Worker }
487*38e8c45fSAndroid Build Coastguard Worker
getIGraphicBufferConsumer() const488*38e8c45fSAndroid Build Coastguard Worker sp<IGraphicBufferConsumer> ConsumerBase::getIGraphicBufferConsumer() const {
489*38e8c45fSAndroid Build Coastguard Worker return mConsumer;
490*38e8c45fSAndroid Build Coastguard Worker }
491*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
492*38e8c45fSAndroid Build Coastguard Worker
acquireBufferLocked(BufferItem * item,nsecs_t presentWhen,uint64_t maxFrameNumber)493*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::acquireBufferLocked(BufferItem *item,
494*38e8c45fSAndroid Build Coastguard Worker nsecs_t presentWhen, uint64_t maxFrameNumber) {
495*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
496*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("acquireBufferLocked: ConsumerBase is abandoned!");
497*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
498*38e8c45fSAndroid Build Coastguard Worker }
499*38e8c45fSAndroid Build Coastguard Worker
500*38e8c45fSAndroid Build Coastguard Worker status_t err = mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber);
501*38e8c45fSAndroid Build Coastguard Worker if (err != NO_ERROR) {
502*38e8c45fSAndroid Build Coastguard Worker return err;
503*38e8c45fSAndroid Build Coastguard Worker }
504*38e8c45fSAndroid Build Coastguard Worker
505*38e8c45fSAndroid Build Coastguard Worker if (item->mGraphicBuffer != nullptr) {
506*38e8c45fSAndroid Build Coastguard Worker if (mSlots[item->mSlot].mGraphicBuffer != nullptr) {
507*38e8c45fSAndroid Build Coastguard Worker freeBufferLocked(item->mSlot);
508*38e8c45fSAndroid Build Coastguard Worker }
509*38e8c45fSAndroid Build Coastguard Worker mSlots[item->mSlot].mGraphicBuffer = item->mGraphicBuffer;
510*38e8c45fSAndroid Build Coastguard Worker }
511*38e8c45fSAndroid Build Coastguard Worker
512*38e8c45fSAndroid Build Coastguard Worker mSlots[item->mSlot].mFrameNumber = item->mFrameNumber;
513*38e8c45fSAndroid Build Coastguard Worker mSlots[item->mSlot].mFence = item->mFence;
514*38e8c45fSAndroid Build Coastguard Worker
515*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("acquireBufferLocked: -> slot=%d/%" PRIu64,
516*38e8c45fSAndroid Build Coastguard Worker item->mSlot, item->mFrameNumber);
517*38e8c45fSAndroid Build Coastguard Worker
518*38e8c45fSAndroid Build Coastguard Worker return OK;
519*38e8c45fSAndroid Build Coastguard Worker }
520*38e8c45fSAndroid Build Coastguard Worker
addReleaseFence(int slot,const sp<GraphicBuffer> graphicBuffer,const sp<Fence> & fence)521*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::addReleaseFence(int slot,
522*38e8c45fSAndroid Build Coastguard Worker const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence) {
523*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
524*38e8c45fSAndroid Build Coastguard Worker return addReleaseFenceLocked(slot, graphicBuffer, fence);
525*38e8c45fSAndroid Build Coastguard Worker }
526*38e8c45fSAndroid Build Coastguard Worker
addReleaseFenceLocked(int slot,const sp<GraphicBuffer> graphicBuffer,const sp<Fence> & fence)527*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::addReleaseFenceLocked(int slot,
528*38e8c45fSAndroid Build Coastguard Worker const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence) {
529*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("addReleaseFenceLocked: slot=%d", slot);
530*38e8c45fSAndroid Build Coastguard Worker
531*38e8c45fSAndroid Build Coastguard Worker // If consumer no longer tracks this graphicBuffer, we can safely
532*38e8c45fSAndroid Build Coastguard Worker // drop this fence, as it will never be received by the producer.
533*38e8c45fSAndroid Build Coastguard Worker if (!stillTracking(slot, graphicBuffer)) {
534*38e8c45fSAndroid Build Coastguard Worker return OK;
535*38e8c45fSAndroid Build Coastguard Worker }
536*38e8c45fSAndroid Build Coastguard Worker
537*38e8c45fSAndroid Build Coastguard Worker if (!mSlots[slot].mFence.get()) {
538*38e8c45fSAndroid Build Coastguard Worker mSlots[slot].mFence = fence;
539*38e8c45fSAndroid Build Coastguard Worker return OK;
540*38e8c45fSAndroid Build Coastguard Worker }
541*38e8c45fSAndroid Build Coastguard Worker
542*38e8c45fSAndroid Build Coastguard Worker // Check status of fences first because merging is expensive.
543*38e8c45fSAndroid Build Coastguard Worker // Merging an invalid fence with any other fence results in an
544*38e8c45fSAndroid Build Coastguard Worker // invalid fence.
545*38e8c45fSAndroid Build Coastguard Worker auto currentStatus = mSlots[slot].mFence->getStatus();
546*38e8c45fSAndroid Build Coastguard Worker if (currentStatus == Fence::Status::Invalid) {
547*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("Existing fence has invalid state");
548*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
549*38e8c45fSAndroid Build Coastguard Worker }
550*38e8c45fSAndroid Build Coastguard Worker
551*38e8c45fSAndroid Build Coastguard Worker auto incomingStatus = fence->getStatus();
552*38e8c45fSAndroid Build Coastguard Worker if (incomingStatus == Fence::Status::Invalid) {
553*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("New fence has invalid state");
554*38e8c45fSAndroid Build Coastguard Worker mSlots[slot].mFence = fence;
555*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
556*38e8c45fSAndroid Build Coastguard Worker }
557*38e8c45fSAndroid Build Coastguard Worker
558*38e8c45fSAndroid Build Coastguard Worker // If both fences are signaled or both are unsignaled, we need to merge
559*38e8c45fSAndroid Build Coastguard Worker // them to get an accurate timestamp.
560*38e8c45fSAndroid Build Coastguard Worker if (currentStatus == incomingStatus) {
561*38e8c45fSAndroid Build Coastguard Worker char fenceName[32] = {};
562*38e8c45fSAndroid Build Coastguard Worker snprintf(fenceName, 32, "%.28s:%d", mName.c_str(), slot);
563*38e8c45fSAndroid Build Coastguard Worker sp<Fence> mergedFence = Fence::merge(
564*38e8c45fSAndroid Build Coastguard Worker fenceName, mSlots[slot].mFence, fence);
565*38e8c45fSAndroid Build Coastguard Worker if (!mergedFence.get()) {
566*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("failed to merge release fences");
567*38e8c45fSAndroid Build Coastguard Worker // synchronization is broken, the best we can do is hope fences
568*38e8c45fSAndroid Build Coastguard Worker // signal in order so the new fence will act like a union
569*38e8c45fSAndroid Build Coastguard Worker mSlots[slot].mFence = fence;
570*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
571*38e8c45fSAndroid Build Coastguard Worker }
572*38e8c45fSAndroid Build Coastguard Worker mSlots[slot].mFence = mergedFence;
573*38e8c45fSAndroid Build Coastguard Worker } else if (incomingStatus == Fence::Status::Unsignaled) {
574*38e8c45fSAndroid Build Coastguard Worker // If one fence has signaled and the other hasn't, the unsignaled
575*38e8c45fSAndroid Build Coastguard Worker // fence will approximately correspond with the correct timestamp.
576*38e8c45fSAndroid Build Coastguard Worker // There's a small race if both fences signal at about the same time
577*38e8c45fSAndroid Build Coastguard Worker // and their statuses are retrieved with unfortunate timing. However,
578*38e8c45fSAndroid Build Coastguard Worker // by this point, they will have both signaled and only the timestamp
579*38e8c45fSAndroid Build Coastguard Worker // will be slightly off; any dependencies after this point will
580*38e8c45fSAndroid Build Coastguard Worker // already have been met.
581*38e8c45fSAndroid Build Coastguard Worker mSlots[slot].mFence = fence;
582*38e8c45fSAndroid Build Coastguard Worker }
583*38e8c45fSAndroid Build Coastguard Worker // else if (currentStatus == Fence::Status::Unsignaled) is a no-op.
584*38e8c45fSAndroid Build Coastguard Worker
585*38e8c45fSAndroid Build Coastguard Worker return OK;
586*38e8c45fSAndroid Build Coastguard Worker }
587*38e8c45fSAndroid Build Coastguard Worker
releaseBufferLocked(int slot,const sp<GraphicBuffer> graphicBuffer,EGLDisplay display,EGLSyncKHR eglFence)588*38e8c45fSAndroid Build Coastguard Worker status_t ConsumerBase::releaseBufferLocked(
589*38e8c45fSAndroid Build Coastguard Worker int slot, const sp<GraphicBuffer> graphicBuffer,
590*38e8c45fSAndroid Build Coastguard Worker EGLDisplay display, EGLSyncKHR eglFence) {
591*38e8c45fSAndroid Build Coastguard Worker if (mAbandoned) {
592*38e8c45fSAndroid Build Coastguard Worker CB_LOGE("releaseBufferLocked: ConsumerBase is abandoned!");
593*38e8c45fSAndroid Build Coastguard Worker return NO_INIT;
594*38e8c45fSAndroid Build Coastguard Worker }
595*38e8c45fSAndroid Build Coastguard Worker // If consumer no longer tracks this graphicBuffer (we received a new
596*38e8c45fSAndroid Build Coastguard Worker // buffer on the same slot), the buffer producer is definitely no longer
597*38e8c45fSAndroid Build Coastguard Worker // tracking it.
598*38e8c45fSAndroid Build Coastguard Worker if (!stillTracking(slot, graphicBuffer)) {
599*38e8c45fSAndroid Build Coastguard Worker return OK;
600*38e8c45fSAndroid Build Coastguard Worker }
601*38e8c45fSAndroid Build Coastguard Worker
602*38e8c45fSAndroid Build Coastguard Worker CB_LOGV("releaseBufferLocked: slot=%d/%" PRIu64,
603*38e8c45fSAndroid Build Coastguard Worker slot, mSlots[slot].mFrameNumber);
604*38e8c45fSAndroid Build Coastguard Worker status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber,
605*38e8c45fSAndroid Build Coastguard Worker display, eglFence, mSlots[slot].mFence);
606*38e8c45fSAndroid Build Coastguard Worker if (err == IGraphicBufferConsumer::STALE_BUFFER_SLOT) {
607*38e8c45fSAndroid Build Coastguard Worker freeBufferLocked(slot);
608*38e8c45fSAndroid Build Coastguard Worker }
609*38e8c45fSAndroid Build Coastguard Worker
610*38e8c45fSAndroid Build Coastguard Worker mPrevFinalReleaseFence = mSlots[slot].mFence;
611*38e8c45fSAndroid Build Coastguard Worker mSlots[slot].mFence = Fence::NO_FENCE;
612*38e8c45fSAndroid Build Coastguard Worker
613*38e8c45fSAndroid Build Coastguard Worker return err;
614*38e8c45fSAndroid Build Coastguard Worker }
615*38e8c45fSAndroid Build Coastguard Worker
stillTracking(int slot,const sp<GraphicBuffer> graphicBuffer)616*38e8c45fSAndroid Build Coastguard Worker bool ConsumerBase::stillTracking(int slot,
617*38e8c45fSAndroid Build Coastguard Worker const sp<GraphicBuffer> graphicBuffer) {
618*38e8c45fSAndroid Build Coastguard Worker if (slot < 0 || slot >= BufferQueue::NUM_BUFFER_SLOTS) {
619*38e8c45fSAndroid Build Coastguard Worker return false;
620*38e8c45fSAndroid Build Coastguard Worker }
621*38e8c45fSAndroid Build Coastguard Worker return (mSlots[slot].mGraphicBuffer != nullptr &&
622*38e8c45fSAndroid Build Coastguard Worker mSlots[slot].mGraphicBuffer->handle == graphicBuffer->handle);
623*38e8c45fSAndroid Build Coastguard Worker }
624*38e8c45fSAndroid Build Coastguard Worker
625*38e8c45fSAndroid Build Coastguard Worker } // namespace android
626