Skip to content

Commit 8aff163

Browse files
Anton IvanovAndroid (Google) Code Review
authored andcommitted
Merge "Delay initialization of a ConsumerBase instance to construction of a sp/wp." into main
2 parents b3ad731 + 4efd0d9 commit 8aff163

2 files changed

Lines changed: 26 additions & 15 deletions

File tree

libs/gui/ConsumerBase.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <gui/BufferItem.h>
3232
#include <gui/BufferQueue.h>
3333
#include <gui/ConsumerBase.h>
34+
#include <gui/IConsumerListener.h>
3435
#include <gui/ISurfaceComposer.h>
3536
#include <gui/Surface.h>
3637
#include <gui/SurfaceComposerClient.h>
@@ -68,8 +69,8 @@ ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool c
6869
#endif
6970
mAbandoned(false),
7071
mConsumer(bufferQueue),
71-
mPrevFinalReleaseFence(Fence::NO_FENCE) {
72-
initialize(controlledByApp);
72+
mPrevFinalReleaseFence(Fence::NO_FENCE),
73+
mIsControlledByApp(controlledByApp) {
7374
}
7475

7576
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
@@ -79,11 +80,11 @@ ConsumerBase::ConsumerBase(bool controlledByApp, bool consumerIsSurfaceFlinger)
7980
mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS),
8081
#endif
8182
mAbandoned(false),
82-
mPrevFinalReleaseFence(Fence::NO_FENCE) {
83+
mPrevFinalReleaseFence(Fence::NO_FENCE),
84+
mIsControlledByApp(controlledByApp) {
8385
sp<IGraphicBufferProducer> producer;
8486
BufferQueue::createBufferQueue(&producer, &mConsumer, consumerIsSurfaceFlinger);
8587
mSurface = sp<Surface>::make(producer, controlledByApp);
86-
initialize(controlledByApp);
8788
}
8889

8990
ConsumerBase::ConsumerBase(const sp<IGraphicBufferProducer>& producer,
@@ -95,24 +96,27 @@ ConsumerBase::ConsumerBase(const sp<IGraphicBufferProducer>& producer,
9596
mAbandoned(false),
9697
mConsumer(consumer),
9798
mSurface(sp<Surface>::make(producer, controlledByApp)),
98-
mPrevFinalReleaseFence(Fence::NO_FENCE) {
99-
initialize(controlledByApp);
99+
mPrevFinalReleaseFence(Fence::NO_FENCE),
100+
mIsControlledByApp(controlledByApp) {
100101
}
101102

102103
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
103104

104-
void ConsumerBase::initialize(bool controlledByApp) {
105+
void ConsumerBase::onFirstRef() {
106+
ConsumerListener::onFirstRef();
107+
initialize();
108+
}
109+
110+
void ConsumerBase::initialize() {
105111
// Choose a name using the PID and a process-unique ID.
106112
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
107113

108-
// Note that we can't create an sp<...>(this) in a ctor that will not keep a
109-
// reference once the ctor ends, as that would cause the refcount of 'this'
110-
// dropping to 0 at the end of the ctor. Since all we need is a wp<...>
111-
// that's what we create.
112-
wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
113-
sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
114+
// Here we depend on an sp/wp having been created for `this`. For this
115+
// reason, initialize() cannot be called from a ctor.
116+
wp<ConsumerListener> listener = wp<ConsumerListener>::fromExisting(this);
117+
sp<IConsumerListener> proxy = sp<BufferQueue::ProxyConsumerListener>::make(listener);
114118

115-
status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
119+
status_t err = mConsumer->consumerConnect(proxy, mIsControlledByApp);
116120
if (err != NO_ERROR) {
117121
CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)",
118122
strerror(-err), err);

libs/gui/include/gui/ConsumerBase.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ class ConsumerBase : public virtual RefBase,
139139
ConsumerBase(const ConsumerBase&);
140140
void operator=(const ConsumerBase&);
141141

142-
void initialize(bool controlledByApp);
142+
// Requires `this` to be sp/wp so must not be called from ctor.
143+
void initialize();
143144

144145
protected:
145146
// ConsumerBase constructs a new ConsumerBase object to consume image
@@ -252,6 +253,10 @@ class ConsumerBase : public virtual RefBase,
252253
const sp<GraphicBuffer> graphicBuffer,
253254
EGLDisplay display = EGL_NO_DISPLAY, EGLSyncKHR eglFence = EGL_NO_SYNC_KHR);
254255
#endif
256+
// Required to complete initialization, so `final` lest overrides forget to
257+
// delegate.
258+
void onFirstRef() override final;
259+
255260
// returns true iff the slot still has the graphicBuffer in it.
256261
bool stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer);
257262

@@ -327,6 +332,8 @@ class ConsumerBase : public virtual RefBase,
327332
// releaseBufferLocked.
328333
sp<Fence> mPrevFinalReleaseFence;
329334

335+
const bool mIsControlledByApp;
336+
330337
// mMutex is the mutex used to prevent concurrent access to the member
331338
// variables of ConsumerBase objects. It must be locked whenever the
332339
// member variables are accessed or when any of the *Locked methods are

0 commit comments

Comments
 (0)