Merge "BufferQueue: Add producer buffer-released callback"

This commit is contained in:
Dan Stoza 2014-04-11 17:57:11 +00:00 committed by Android (Google) Code Review
commit fd34b65f71
18 changed files with 191 additions and 56 deletions

View File

@ -228,16 +228,8 @@ public:
// will usually be the one obtained from dequeueBuffer. // will usually be the one obtained from dequeueBuffer.
virtual void cancelBuffer(int buf, const sp<Fence>& fence); virtual void cancelBuffer(int buf, const sp<Fence>& fence);
// connect attempts to connect a producer API to the BufferQueue. This // See IGraphicBufferProducer::connect
// must be called before any other IGraphicBufferProducer methods are virtual status_t connect(const sp<IProducerListener>& listener,
// called except for getAllocator. A consumer must already be connected.
//
// This method will fail if connect was previously called on the
// BufferQueue and no corresponding disconnect call was made (i.e. if
// it's still connected to a producer).
//
// APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU).
virtual status_t connect(const sp<IBinder>& token,
int api, bool producerControlledByApp, QueueBufferOutput* output); int api, bool producerControlledByApp, QueueBufferOutput* output);
// disconnect attempts to disconnect a producer API from the BufferQueue. // disconnect attempts to disconnect a producer API from the BufferQueue.

View File

@ -46,9 +46,9 @@
namespace android { namespace android {
class BufferItem; class BufferItem;
class IBinder;
class IConsumerListener; class IConsumerListener;
class IGraphicBufferAlloc; class IGraphicBufferAlloc;
class IProducerListener;
class BufferQueueCore : public virtual RefBase { class BufferQueueCore : public virtual RefBase {
@ -162,7 +162,7 @@ private:
// mConnectedProducerToken is used to set a binder death notification on // mConnectedProducerToken is used to set a binder death notification on
// the producer. // the producer.
sp<IBinder> mConnectedProducerToken; sp<IProducerListener> mConnectedProducerListener;
// mSlots is an array of buffer slots that must be mirrored on the producer // mSlots is an array of buffer slots that must be mirrored on the producer
// side. This allows buffer ownership to be transferred between the producer // side. This allows buffer ownership to be transferred between the producer

View File

@ -140,7 +140,7 @@ public:
// it's still connected to a producer). // it's still connected to a producer).
// //
// APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU). // APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU).
virtual status_t connect(const sp<IBinder>& token, virtual status_t connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output); int api, bool producerControlledByApp, QueueBufferOutput* output);
// disconnect attempts to disconnect a producer API from the BufferQueue. // disconnect attempts to disconnect a producer API from the BufferQueue.

View File

@ -32,6 +32,7 @@
namespace android { namespace android {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class IProducerListener;
class NativeHandle; class NativeHandle;
class Surface; class Surface;
@ -344,9 +345,11 @@ public:
// This method will fail if the connect was previously called on the // This method will fail if the connect was previously called on the
// IGraphicBufferProducer and no corresponding disconnect call was made. // IGraphicBufferProducer and no corresponding disconnect call was made.
// //
// The token needs to be any opaque binder object that lives in the // The listener is an optional binder callback object that can be used if
// producer process -- it is solely used for obtaining a death notification // the producer wants to be notified when the consumer releases a buffer
// when the producer is killed. // back to the BufferQueue. It is also used to detect the death of the
// producer. If only the latter functionality is desired, there is a
// DummyProducerListener class in IProducerListener.h that can be used.
// //
// The api should be one of the NATIVE_WINDOW_API_* values in <window.h> // The api should be one of the NATIVE_WINDOW_API_* values in <window.h>
// //
@ -370,7 +373,7 @@ public:
// //
// Additional negative errors may be returned by the internals, they // Additional negative errors may be returned by the internals, they
// should be treated as opaque fatal unrecoverable errors. // should be treated as opaque fatal unrecoverable errors.
virtual status_t connect(const sp<IBinder>& token, virtual status_t connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output) = 0; int api, bool producerControlledByApp, QueueBufferOutput* output) = 0;
// disconnect attempts to disconnect a client API from the // disconnect attempts to disconnect a client API from the

View File

@ -0,0 +1,67 @@
/*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_GUI_IPRODUCERLISTENER_H
#define ANDROID_GUI_IPRODUCERLISTENER_H
#include <binder/IInterface.h>
#include <utils/RefBase.h>
namespace android {
// ProducerListener is the interface through which the BufferQueue notifies the
// producer of events that the producer may wish to react to. Because the
// producer will generally have a mutex that is locked during calls from the
// producer to the BufferQueue, these calls from the BufferQueue to the
// producer *MUST* be called only when the BufferQueue mutex is NOT locked.
class ProducerListener : public virtual RefBase
{
public:
ProducerListener() {}
virtual ~ProducerListener() {}
// onBufferReleased is called from IGraphicBufferConsumer::releaseBuffer to
// notify the producer that a new buffer is free and ready to be dequeued.
//
// This is called without any lock held and can be called concurrently by
// multiple threads.
virtual void onBufferReleased() = 0; // Asynchronous
};
class IProducerListener : public ProducerListener, public IInterface
{
public:
DECLARE_META_INTERFACE(ProducerListener)
};
class BnProducerListener : public BnInterface<IProducerListener>
{
public:
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags = 0);
};
class DummyProducerListener : public BnProducerListener
{
public:
virtual void onBufferReleased() {}
};
} // namespace android
#endif

View File

@ -21,6 +21,7 @@ LOCAL_SRC_FILES:= \
IDisplayEventConnection.cpp \ IDisplayEventConnection.cpp \
IGraphicBufferAlloc.cpp \ IGraphicBufferAlloc.cpp \
IGraphicBufferProducer.cpp \ IGraphicBufferProducer.cpp \
IProducerListener.cpp \
ISensorEventConnection.cpp \ ISensorEventConnection.cpp \
ISensorServer.cpp \ ISensorServer.cpp \
ISurfaceComposer.cpp \ ISurfaceComposer.cpp \

View File

@ -117,9 +117,9 @@ void BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) {
mProducer->cancelBuffer(buf, fence); mProducer->cancelBuffer(buf, fence);
} }
status_t BufferQueue::connect(const sp<IBinder>& token, status_t BufferQueue::connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output) { int api, bool producerControlledByApp, QueueBufferOutput* output) {
return mProducer->connect(token, api, producerControlledByApp, output); return mProducer->connect(listener, api, producerControlledByApp, output);
} }
status_t BufferQueue::disconnect(int api) { status_t BufferQueue::disconnect(int api) {

View File

@ -26,6 +26,7 @@
#include <gui/BufferQueueCore.h> #include <gui/BufferQueueCore.h>
#include <gui/IConsumerListener.h> #include <gui/IConsumerListener.h>
#include <gui/IGraphicBufferAlloc.h> #include <gui/IGraphicBufferAlloc.h>
#include <gui/IProducerListener.h>
#include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h> #include <private/gui/ComposerService.h>
@ -49,7 +50,7 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
mConsumerListener(), mConsumerListener(),
mConsumerUsageBits(0), mConsumerUsageBits(0),
mConnectedApi(NO_CONNECTED_API), mConnectedApi(NO_CONNECTED_API),
mConnectedProducerToken(), mConnectedProducerListener(),
mSlots(), mSlots(),
mQueue(), mQueue(),
mOverrideMaxBufferCount(0), mOverrideMaxBufferCount(0),

View File

@ -25,6 +25,7 @@
#include <gui/BufferQueueProducer.h> #include <gui/BufferQueueProducer.h>
#include <gui/IConsumerListener.h> #include <gui/IConsumerListener.h>
#include <gui/IGraphicBufferAlloc.h> #include <gui/IGraphicBufferAlloc.h>
#include <gui/IProducerListener.h>
#include <utils/Log.h> #include <utils/Log.h>
#include <utils/Trace.h> #include <utils/Trace.h>
@ -654,7 +655,7 @@ int BufferQueueProducer::query(int what, int *outValue) {
return NO_ERROR; return NO_ERROR;
} }
status_t BufferQueueProducer::connect(const sp<android::IBinder> &token, status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput *output) { int api, bool producerControlledByApp, QueueBufferOutput *output) {
ATRACE_CALL(); ATRACE_CALL();
Mutex::Autolock lock(mCore->mMutex); Mutex::Autolock lock(mCore->mMutex);
@ -711,16 +712,16 @@ status_t BufferQueueProducer::connect(const sp<android::IBinder> &token,
// Set up a death notification so that we can disconnect // Set up a death notification so that we can disconnect
// automatically if the remote producer dies // automatically if the remote producer dies
if (token != NULL && token->remoteBinder() != NULL) { if (listener != NULL &&
status = token->linkToDeath( listener->asBinder()->remoteBinder() != NULL) {
status = listener->asBinder()->linkToDeath(
static_cast<IBinder::DeathRecipient*>(this)); static_cast<IBinder::DeathRecipient*>(this));
if (status == NO_ERROR) { if (status != NO_ERROR) {
mCore->mConnectedProducerToken = token;
} else {
BQ_LOGE("connect(P): linkToDeath failed: %s (%d)", BQ_LOGE("connect(P): linkToDeath failed: %s (%d)",
strerror(-status), status); strerror(-status), status);
} }
} }
mCore->mConnectedProducerListener = listener;
break; break;
default: default:
BQ_LOGE("connect(P): unknown API %d", api); BQ_LOGE("connect(P): unknown API %d", api);
@ -759,14 +760,15 @@ status_t BufferQueueProducer::disconnect(int api) {
mCore->freeAllBuffersLocked(); mCore->freeAllBuffersLocked();
// Remove our death notification callback if we have one // Remove our death notification callback if we have one
sp<IBinder> token = mCore->mConnectedProducerToken; if (mCore->mConnectedProducerListener != NULL) {
if (token != NULL) { sp<IBinder> token =
mCore->mConnectedProducerListener->asBinder();
// This can fail if we're here because of the death // This can fail if we're here because of the death
// notification, but we just ignore it // notification, but we just ignore it
token->unlinkToDeath( token->unlinkToDeath(
static_cast<IBinder::DeathRecipient*>(this)); static_cast<IBinder::DeathRecipient*>(this));
} }
mCore->mConnectedProducerToken = NULL; mCore->mConnectedProducerListener = NULL;
mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
mCore->mSidebandStream.clear(); mCore->mSidebandStream.clear();
mCore->mDequeueCondition.broadcast(); mCore->mDequeueCondition.broadcast();

View File

@ -27,6 +27,7 @@
#include <binder/IInterface.h> #include <binder/IInterface.h>
#include <gui/IGraphicBufferProducer.h> #include <gui/IGraphicBufferProducer.h>
#include <gui/IProducerListener.h>
namespace android { namespace android {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -171,11 +172,16 @@ public:
return result; return result;
} }
virtual status_t connect(const sp<IBinder>& token, virtual status_t connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output) { int api, bool producerControlledByApp, QueueBufferOutput* output) {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
data.writeStrongBinder(token); if (listener != NULL) {
data.writeInt32(1);
data.writeStrongBinder(listener->asBinder());
} else {
data.writeInt32(0);
}
data.writeInt32(api); data.writeInt32(api);
data.writeInt32(producerControlledByApp); data.writeInt32(producerControlledByApp);
status_t result = remote()->transact(CONNECT, data, &reply); status_t result = remote()->transact(CONNECT, data, &reply);
@ -308,13 +314,16 @@ status_t BnGraphicBufferProducer::onTransact(
} break; } break;
case CONNECT: { case CONNECT: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
sp<IBinder> token = data.readStrongBinder(); sp<IProducerListener> listener;
if (data.readInt32() == 1) {
listener = IProducerListener::asInterface(data.readStrongBinder());
}
int api = data.readInt32(); int api = data.readInt32();
bool producerControlledByApp = data.readInt32(); bool producerControlledByApp = data.readInt32();
QueueBufferOutput* const output = QueueBufferOutput* const output =
reinterpret_cast<QueueBufferOutput *>( reinterpret_cast<QueueBufferOutput *>(
reply->writeInplace(sizeof(QueueBufferOutput))); reply->writeInplace(sizeof(QueueBufferOutput)));
status_t res = connect(token, api, producerControlledByApp, output); status_t res = connect(listener, api, producerControlledByApp, output);
reply->writeInt32(res); reply->writeInt32(res);
return NO_ERROR; return NO_ERROR;
} break; } break;

View File

@ -0,0 +1,53 @@
/*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <binder/Parcel.h>
#include <gui/IProducerListener.h>
namespace android {
enum {
ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,
};
class BpProducerListener : public BpInterface<IProducerListener>
{
public:
BpProducerListener(const sp<IBinder>& impl)
: BpInterface<IProducerListener>(impl) {}
virtual void onBufferReleased() {
Parcel data, reply;
data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
}
};
IMPLEMENT_META_INTERFACE(ProducerListener, "android.gui.IProducerListener")
status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
switch (code) {
case ON_BUFFER_RELEASED:
CHECK_INTERFACE(IProducerListener, data, reply);
onBufferReleased();
return NO_ERROR;
}
return BBinder::onTransact(code, data, reply, flags);
}
} // namespace android

View File

@ -27,6 +27,7 @@
#include <ui/Fence.h> #include <ui/Fence.h>
#include <gui/IProducerListener.h>
#include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h> #include <gui/SurfaceComposerClient.h>
#include <gui/GLConsumer.h> #include <gui/GLConsumer.h>
@ -513,10 +514,10 @@ int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) {
int Surface::connect(int api) { int Surface::connect(int api) {
ATRACE_CALL(); ATRACE_CALL();
ALOGV("Surface::connect"); ALOGV("Surface::connect");
static sp<BBinder> sLife = new BBinder(); static sp<IProducerListener> listener = new DummyProducerListener();
Mutex::Autolock lock(mMutex); Mutex::Autolock lock(mMutex);
IGraphicBufferProducer::QueueBufferOutput output; IGraphicBufferProducer::QueueBufferOutput output;
int err = mGraphicBufferProducer->connect(sLife, api, mProducerControlledByApp, &output); int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
if (err == NO_ERROR) { if (err == NO_ERROR) {
uint32_t numPendingBuffers = 0; uint32_t numPendingBuffers = 0;
output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,

View File

@ -17,17 +17,19 @@
#define LOG_TAG "BufferQueue_test" #define LOG_TAG "BufferQueue_test"
//#define LOG_NDEBUG 0 //#define LOG_NDEBUG 0
#include <gtest/gtest.h> #include <gui/BufferQueue.h>
#include <gui/IProducerListener.h>
#include <utils/String8.h>
#include <utils/threads.h>
#include <ui/GraphicBuffer.h> #include <ui/GraphicBuffer.h>
#include <binder/IPCThreadState.h> #include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h> #include <binder/IServiceManager.h>
#include <binder/ProcessState.h> #include <binder/ProcessState.h>
#include <gui/BufferQueue.h>
#include <utils/String8.h>
#include <utils/threads.h>
#include <gtest/gtest.h>
namespace android { namespace android {
@ -141,7 +143,8 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
sp<DummyConsumer> dc(new DummyConsumer); sp<DummyConsumer> dc(new DummyConsumer);
mConsumer->consumerConnect(dc, false); mConsumer->consumerConnect(dc, false);
IGraphicBufferProducer::QueueBufferOutput qbo; IGraphicBufferProducer::QueueBufferOutput qbo;
mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &qbo); mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
&qbo);
mProducer->setBufferCount(4); mProducer->setBufferCount(4);
int slot; int slot;
@ -207,8 +210,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
sp<DummyConsumer> dc(new DummyConsumer); sp<DummyConsumer> dc(new DummyConsumer);
ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
IGraphicBufferProducer::QueueBufferOutput output; IGraphicBufferProducer::QueueBufferOutput output;
ASSERT_EQ(OK, ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); NATIVE_WINDOW_API_CPU, false, &output));
ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer( ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
@ -260,8 +263,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
sp<DummyConsumer> dc(new DummyConsumer); sp<DummyConsumer> dc(new DummyConsumer);
ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
IGraphicBufferProducer::QueueBufferOutput output; IGraphicBufferProducer::QueueBufferOutput output;
ASSERT_EQ(OK, ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); NATIVE_WINDOW_API_CPU, false, &output));
int slot; int slot;
sp<Fence> fence; sp<Fence> fence;
@ -318,8 +321,8 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
sp<DummyConsumer> dc(new DummyConsumer); sp<DummyConsumer> dc(new DummyConsumer);
ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
IGraphicBufferProducer::QueueBufferOutput output; IGraphicBufferProducer::QueueBufferOutput output;
ASSERT_EQ(OK, ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); NATIVE_WINDOW_API_CPU, false, &output));
int slot; int slot;
sp<Fence> fence; sp<Fence> fence;

View File

@ -25,13 +25,14 @@
#include <ui/GraphicBuffer.h> #include <ui/GraphicBuffer.h>
#include <gui/BufferQueue.h> #include <gui/BufferQueue.h>
#include <gui/IProducerListener.h>
#include <vector> #include <vector>
#define ASSERT_OK(x) ASSERT_EQ(OK, (x)) #define ASSERT_OK(x) ASSERT_EQ(OK, (x))
#define EXPECT_OK(x) EXPECT_EQ(OK, (x)) #define EXPECT_OK(x) EXPECT_EQ(OK, (x))
#define TEST_TOKEN ((IBinder*)(NULL)) #define TEST_TOKEN ((IProducerListener*)(NULL))
#define TEST_API NATIVE_WINDOW_API_CPU #define TEST_API NATIVE_WINDOW_API_CPU
#define TEST_API_OTHER NATIVE_WINDOW_API_EGL // valid API that's not TEST_API #define TEST_API_OTHER NATIVE_WINDOW_API_EGL // valid API that's not TEST_API
#define TEST_CONTROLLED_BY_APP false #define TEST_CONTROLLED_BY_APP false

View File

@ -454,11 +454,12 @@ int VirtualDisplaySurface::query(int what, int* value) {
return mSource[SOURCE_SINK]->query(what, value); return mSource[SOURCE_SINK]->query(what, value);
} }
status_t VirtualDisplaySurface::connect(const sp<IBinder>& token, status_t VirtualDisplaySurface::connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, int api, bool producerControlledByApp,
QueueBufferOutput* output) { QueueBufferOutput* output) {
QueueBufferOutput qbo; QueueBufferOutput qbo;
status_t result = mSource[SOURCE_SINK]->connect(token, api, producerControlledByApp, &qbo); status_t result = mSource[SOURCE_SINK]->connect(listener, api,
producerControlledByApp, &qbo);
if (result == NO_ERROR) { if (result == NO_ERROR) {
updateQueueBufferOutput(qbo); updateQueueBufferOutput(qbo);
*output = mQueueBufferOutput; *output = mQueueBufferOutput;

View File

@ -27,6 +27,7 @@ namespace android {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
class HWComposer; class HWComposer;
class IProducerListener;
/* This DisplaySurface implementation supports virtual displays, where GLES /* This DisplaySurface implementation supports virtual displays, where GLES
* and/or HWC compose into a buffer that is then passed to an arbitrary * and/or HWC compose into a buffer that is then passed to an arbitrary
@ -105,7 +106,7 @@ private:
const QueueBufferInput& input, QueueBufferOutput* output); const QueueBufferInput& input, QueueBufferOutput* output);
virtual void cancelBuffer(int pslot, const sp<Fence>& fence); virtual void cancelBuffer(int pslot, const sp<Fence>& fence);
virtual int query(int what, int* value); virtual int query(int what, int* value);
virtual status_t connect(const sp<IBinder>& token, virtual status_t connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output); int api, bool producerControlledByApp, QueueBufferOutput* output);
virtual status_t disconnect(int api); virtual status_t disconnect(int api);
virtual status_t setSidebandStream(const sp<NativeHandle>& stream); virtual status_t setSidebandStream(const sp<NativeHandle>& stream);

View File

@ -87,9 +87,9 @@ int MonitoredProducer::query(int what, int* value) {
return mProducer->query(what, value); return mProducer->query(what, value);
} }
status_t MonitoredProducer::connect(const sp<IBinder>& token, int api, status_t MonitoredProducer::connect(const sp<IProducerListener>& listener,
bool producerControlledByApp, QueueBufferOutput* output) { int api, bool producerControlledByApp, QueueBufferOutput* output) {
return mProducer->connect(token, api, producerControlledByApp, output); return mProducer->connect(listener, api, producerControlledByApp, output);
} }
status_t MonitoredProducer::disconnect(int api) { status_t MonitoredProducer::disconnect(int api) {

View File

@ -21,7 +21,7 @@
namespace android { namespace android {
class IBinder; class IProducerListener;
class NativeHandle; class NativeHandle;
class SurfaceFlinger; class SurfaceFlinger;
@ -45,7 +45,7 @@ public:
QueueBufferOutput* output); QueueBufferOutput* output);
virtual void cancelBuffer(int slot, const sp<Fence>& fence); virtual void cancelBuffer(int slot, const sp<Fence>& fence);
virtual int query(int what, int* value); virtual int query(int what, int* value);
virtual status_t connect(const sp<IBinder>& token, int api, virtual status_t connect(const sp<IProducerListener>& token, int api,
bool producerControlledByApp, QueueBufferOutput* output); bool producerControlledByApp, QueueBufferOutput* output);
virtual status_t disconnect(int api); virtual status_t disconnect(int api);
virtual status_t setSidebandStream(const sp<NativeHandle>& stream); virtual status_t setSidebandStream(const sp<NativeHandle>& stream);