Merge "BufferQueue: Add producer buffer-released callback"
This commit is contained in:
commit
fd34b65f71
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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 \
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue