Merge "Add sideband streams to BufferQueue and related classes"
This commit is contained in:
commit
73ed82f809
@ -100,6 +100,7 @@ public:
|
||||
virtual ~ProxyConsumerListener();
|
||||
virtual void onFrameAvailable();
|
||||
virtual void onBuffersReleased();
|
||||
virtual void onSidebandStreamChanged();
|
||||
private:
|
||||
// mConsumerListener is a weak reference to the IConsumerListener. This is
|
||||
// the raison d'etre of ProxyConsumerListener.
|
||||
@ -253,6 +254,18 @@ public:
|
||||
// connected to the specified producer API.
|
||||
virtual status_t disconnect(int api);
|
||||
|
||||
// Attaches a sideband buffer stream to the BufferQueue.
|
||||
//
|
||||
// A sideband stream is a device-specific mechanism for passing buffers
|
||||
// from the producer to the consumer without using dequeueBuffer/
|
||||
// queueBuffer. If a sideband stream is present, the consumer can choose
|
||||
// whether to acquire buffers from the sideband stream or from the queued
|
||||
// buffers.
|
||||
//
|
||||
// Passing NULL or a different stream handle will detach the previous
|
||||
// handle if any.
|
||||
virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
|
||||
|
||||
/*
|
||||
* IGraphicBufferConsumer interface
|
||||
*/
|
||||
@ -362,6 +375,9 @@ public:
|
||||
// NATIVE_WINDOW_TRANSFORM_ROT_90. The default is 0 (no transform).
|
||||
virtual status_t setTransformHint(uint32_t hint);
|
||||
|
||||
// Retrieve the BufferQueue's sideband stream, if any.
|
||||
virtual sp<NativeHandle> getSidebandStream() const;
|
||||
|
||||
// dump our state in a String
|
||||
virtual void dump(String8& result, const char* prefix) const;
|
||||
|
||||
|
@ -139,6 +139,9 @@ public:
|
||||
// NATIVE_WINDOW_TRANSFORM_ROT_90. The default is 0 (no transform).
|
||||
virtual status_t setTransformHint(uint32_t hint);
|
||||
|
||||
// Retrieve the sideband buffer stream, if any.
|
||||
virtual sp<NativeHandle> getSidebandStream() const;
|
||||
|
||||
// dump our state in a String
|
||||
virtual void dump(String8& result, const char* prefix) const;
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <utils/Condition.h>
|
||||
#include <utils/Mutex.h>
|
||||
#include <utils/NativeHandle.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/StrongPointer.h>
|
||||
@ -230,6 +231,9 @@ private:
|
||||
// mTransformHint is used to optimize for screen rotations.
|
||||
uint32_t mTransformHint;
|
||||
|
||||
// mSidebandStream is a handle to the sideband buffer stream, if any
|
||||
sp<NativeHandle> mSidebandStream;
|
||||
|
||||
}; // class BufferQueueCore
|
||||
|
||||
} // namespace android
|
||||
|
@ -153,6 +153,18 @@ public:
|
||||
// connected to the specified producer API.
|
||||
virtual status_t disconnect(int api);
|
||||
|
||||
// Attaches a sideband buffer stream to the IGraphicBufferProducer.
|
||||
//
|
||||
// A sideband stream is a device-specific mechanism for passing buffers
|
||||
// from the producer to the consumer without using dequeueBuffer/
|
||||
// queueBuffer. If a sideband stream is present, the consumer can choose
|
||||
// whether to acquire buffers from the sideband stream or from the queued
|
||||
// buffers.
|
||||
//
|
||||
// Passing NULL or a different stream handle will detach the previous
|
||||
// handle if any.
|
||||
virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
|
||||
|
||||
private:
|
||||
// This is required by the IBinder::DeathRecipient interface
|
||||
virtual void binderDied(const wp<IBinder>& who);
|
||||
|
@ -101,11 +101,14 @@ protected:
|
||||
|
||||
// Implementation of the IConsumerListener interface. These
|
||||
// calls are used to notify the ConsumerBase of asynchronous events in the
|
||||
// BufferQueue. These methods should not need to be overridden by derived
|
||||
// classes, but if they are overridden the ConsumerBase implementation
|
||||
// must be called from the derived class.
|
||||
// BufferQueue. The onFrameAvailable and onBuffersReleased methods should
|
||||
// not need to be overridden by derived classes, but if they are overridden
|
||||
// the ConsumerBase implementation must be called from the derived class.
|
||||
// The ConsumerBase version of onSidebandStreamChanged does nothing and can
|
||||
// be overriden by derived classes if they want the notification.
|
||||
virtual void onFrameAvailable();
|
||||
virtual void onBuffersReleased();
|
||||
virtual void onSidebandStreamChanged();
|
||||
|
||||
// freeBufferLocked frees up the given buffer slot. If the slot has been
|
||||
// initialized this will release the reference to the GraphicBuffer in that
|
||||
|
@ -57,6 +57,12 @@ public:
|
||||
// This is called without any lock held and can be called concurrently
|
||||
// by multiple threads.
|
||||
virtual void onBuffersReleased() = 0; /* Asynchronous */
|
||||
|
||||
// onSidebandStreamChanged is called to notify the buffer consumer that the
|
||||
// BufferQueue's sideband buffer stream has changed. This is called when a
|
||||
// stream is first attached and when it is either detached or replaced by a
|
||||
// different stream.
|
||||
virtual void onSidebandStreamChanged() = 0; /* Asynchronous */
|
||||
};
|
||||
|
||||
|
||||
|
@ -30,9 +30,10 @@
|
||||
namespace android {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class IConsumerListener;
|
||||
class GraphicBuffer;
|
||||
class Fence;
|
||||
class GraphicBuffer;
|
||||
class IConsumerListener;
|
||||
class NativeHandle;
|
||||
|
||||
class IGraphicBufferConsumer : public IInterface {
|
||||
|
||||
@ -296,6 +297,9 @@ public:
|
||||
// Return of a value other than NO_ERROR means an unknown error has occurred.
|
||||
virtual status_t setTransformHint(uint32_t hint) = 0;
|
||||
|
||||
// Retrieve the sideband buffer stream, if any.
|
||||
virtual sp<NativeHandle> getSidebandStream() const = 0;
|
||||
|
||||
// dump state into a string
|
||||
virtual void dump(String8& result, const char* prefix) const = 0;
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
namespace android {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class NativeHandle;
|
||||
class Surface;
|
||||
|
||||
/*
|
||||
@ -392,6 +393,18 @@ public:
|
||||
// * api was out of range (see above).
|
||||
// * DEAD_OBJECT - the token is hosted by an already-dead process
|
||||
virtual status_t disconnect(int api) = 0;
|
||||
|
||||
// Attaches a sideband buffer stream to the IGraphicBufferProducer.
|
||||
//
|
||||
// A sideband stream is a device-specific mechanism for passing buffers
|
||||
// from the producer to the consumer without using dequeueBuffer/
|
||||
// queueBuffer. If a sideband stream is present, the consumer can choose
|
||||
// whether to acquire buffers from the sideband stream or from the queued
|
||||
// buffers.
|
||||
//
|
||||
// Passing NULL or a different stream handle will detach the previous
|
||||
// handle if any.
|
||||
virtual status_t setSidebandStream(const sp<NativeHandle>& stream) = 0;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -78,6 +78,19 @@ public:
|
||||
return surface != NULL && surface->getIGraphicBufferProducer() != NULL;
|
||||
}
|
||||
|
||||
/* Attaches a sideband buffer stream to the Surface's IGraphicBufferProducer.
|
||||
*
|
||||
* A sideband stream is a device-specific mechanism for passing buffers
|
||||
* from the producer to the consumer without using dequeueBuffer/
|
||||
* queueBuffer. If a sideband stream is present, the consumer can choose
|
||||
* whether to acquire buffers from the sideband stream or from the queued
|
||||
* buffers.
|
||||
*
|
||||
* Passing NULL or a different stream handle will detach the previous
|
||||
* handle if any.
|
||||
*/
|
||||
void setSidebandStream(const sp<NativeHandle>& stream);
|
||||
|
||||
protected:
|
||||
virtual ~Surface();
|
||||
|
||||
|
@ -128,6 +128,10 @@ status_t BufferQueue::disconnect(int api) {
|
||||
return mProducer->disconnect(api);
|
||||
}
|
||||
|
||||
status_t BufferQueue::setSidebandStream(const sp<NativeHandle>& stream) {
|
||||
return mProducer->setSidebandStream(stream);
|
||||
}
|
||||
|
||||
status_t BufferQueue::acquireBuffer(BufferItem* buffer, nsecs_t presentWhen) {
|
||||
return mConsumer->acquireBuffer(buffer, presentWhen);
|
||||
}
|
||||
@ -192,8 +196,19 @@ status_t BufferQueue::setTransformHint(uint32_t hint) {
|
||||
return mConsumer->setTransformHint(hint);
|
||||
}
|
||||
|
||||
sp<NativeHandle> BufferQueue::getSidebandStream() const {
|
||||
return mConsumer->getSidebandStream();
|
||||
}
|
||||
|
||||
void BufferQueue::dump(String8& result, const char* prefix) const {
|
||||
mConsumer->dump(result, prefix);
|
||||
}
|
||||
|
||||
void BufferQueue::ProxyConsumerListener::onSidebandStreamChanged() {
|
||||
sp<ConsumerListener> listener(mConsumerListener.promote());
|
||||
if (listener != NULL) {
|
||||
listener->onSidebandStreamChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
@ -478,6 +478,10 @@ status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
sp<NativeHandle> BufferQueueConsumer::getSidebandStream() const {
|
||||
return mCore->mSidebandStream;
|
||||
}
|
||||
|
||||
void BufferQueueConsumer::dump(String8& result, const char* prefix) const {
|
||||
mCore->dump(result, prefix);
|
||||
}
|
||||
|
@ -767,6 +767,7 @@ status_t BufferQueueProducer::disconnect(int api) {
|
||||
}
|
||||
mCore->mConnectedProducerToken = NULL;
|
||||
mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
|
||||
mCore->mSidebandStream.clear();
|
||||
mCore->mDequeueCondition.broadcast();
|
||||
listener = mCore->mConsumerListener;
|
||||
} else {
|
||||
@ -790,6 +791,12 @@ status_t BufferQueueProducer::disconnect(int api) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
|
||||
Mutex::Autolock _l(mCore->mMutex);
|
||||
mCore->mSidebandStream = stream;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
|
||||
// If we're here, it means that a producer we were connected to died.
|
||||
// We're guaranteed that we are still connected to it because we remove
|
||||
|
@ -130,6 +130,9 @@ void ConsumerBase::onBuffersReleased() {
|
||||
}
|
||||
}
|
||||
|
||||
void ConsumerBase::onSidebandStreamChanged() {
|
||||
}
|
||||
|
||||
void ConsumerBase::abandon() {
|
||||
CB_LOGV("abandon");
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
@ -28,7 +28,8 @@ namespace android {
|
||||
|
||||
enum {
|
||||
ON_FRAME_AVAILABLE = IBinder::FIRST_CALL_TRANSACTION,
|
||||
ON_BUFFER_RELEASED
|
||||
ON_BUFFER_RELEASED,
|
||||
ON_SIDEBAND_STREAM_CHANGED,
|
||||
};
|
||||
|
||||
class BpConsumerListener : public BpInterface<IConsumerListener>
|
||||
@ -49,6 +50,12 @@ public:
|
||||
data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
|
||||
remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
|
||||
}
|
||||
|
||||
virtual void onSidebandStreamChanged() {
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
|
||||
remote()->transact(ON_SIDEBAND_STREAM_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_META_INTERFACE(ConsumerListener, "android.gui.IConsumerListener");
|
||||
@ -67,6 +74,10 @@ status_t BnConsumerListener::onTransact(
|
||||
CHECK_INTERFACE(IConsumerListener, data, reply);
|
||||
onBuffersReleased();
|
||||
return NO_ERROR;
|
||||
case ON_SIDEBAND_STREAM_CHANGED:
|
||||
CHECK_INTERFACE(IConsumerListener, data, reply);
|
||||
onSidebandStreamChanged();
|
||||
return NO_ERROR;
|
||||
}
|
||||
return BBinder::onTransact(code, data, reply, flags);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/NativeHandle.h>
|
||||
|
||||
#include <binder/Parcel.h>
|
||||
#include <binder/IInterface.h>
|
||||
@ -197,6 +198,7 @@ enum {
|
||||
SET_DEFAULT_BUFFER_FORMAT,
|
||||
SET_CONSUMER_USAGE_BITS,
|
||||
SET_TRANSFORM_HINT,
|
||||
GET_SIDEBAND_STREAM,
|
||||
DUMP,
|
||||
};
|
||||
|
||||
@ -381,6 +383,20 @@ public:
|
||||
return reply.readInt32();
|
||||
}
|
||||
|
||||
virtual sp<NativeHandle> getSidebandStream() const {
|
||||
Parcel data, reply;
|
||||
status_t err;
|
||||
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
|
||||
if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) {
|
||||
return NULL;
|
||||
}
|
||||
sp<NativeHandle> stream;
|
||||
if (reply.readInt32()) {
|
||||
stream = NativeHandle::create(reply.readNativeHandle());
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
virtual void dump(String8& result, const char* prefix) const {
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
|
||||
|
@ -18,9 +18,10 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/NativeHandle.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/Timers.h>
|
||||
#include <utils/Vector.h>
|
||||
|
||||
#include <binder/Parcel.h>
|
||||
#include <binder/IInterface.h>
|
||||
@ -41,6 +42,7 @@ enum {
|
||||
QUERY,
|
||||
CONNECT,
|
||||
DISCONNECT,
|
||||
SET_SIDEBAND_STREAM,
|
||||
};
|
||||
|
||||
class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
|
||||
@ -196,6 +198,22 @@ public:
|
||||
result = reply.readInt32();
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual status_t setSidebandStream(const sp<NativeHandle>& stream) {
|
||||
Parcel data, reply;
|
||||
status_t result;
|
||||
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
|
||||
if (stream.get()) {
|
||||
data.writeInt32(true);
|
||||
data.writeNativeHandle(stream->handle());
|
||||
} else {
|
||||
data.writeInt32(false);
|
||||
}
|
||||
if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) {
|
||||
result = reply.readInt32();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
|
||||
@ -307,6 +325,16 @@ status_t BnGraphicBufferProducer::onTransact(
|
||||
reply->writeInt32(res);
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
case SET_SIDEBAND_STREAM: {
|
||||
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
|
||||
sp<NativeHandle> stream;
|
||||
if (data.readInt32()) {
|
||||
stream = NativeHandle::create(data.readNativeHandle());
|
||||
}
|
||||
status_t result = setSidebandStream(stream);
|
||||
reply->writeInt32(result);
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
}
|
||||
return BBinder::onTransact(code, data, reply, flags);
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/misc.h>
|
||||
#include <utils/NativeHandle.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Thread.h>
|
||||
#include <utils/Trace.h>
|
||||
@ -942,12 +943,22 @@ public:
|
||||
SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects);
|
||||
visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
|
||||
}
|
||||
virtual void setSidebandStream(const sp<NativeHandle>& stream) {
|
||||
ALOG_ASSERT(stream->handle() != NULL);
|
||||
getLayer()->compositionType = HWC_SIDEBAND;
|
||||
getLayer()->sidebandStream = stream->handle();
|
||||
}
|
||||
virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
|
||||
if (buffer == 0 || buffer->handle == 0) {
|
||||
getLayer()->compositionType = HWC_FRAMEBUFFER;
|
||||
getLayer()->flags |= HWC_SKIP_LAYER;
|
||||
getLayer()->handle = 0;
|
||||
} else {
|
||||
if (getLayer()->compositionType == HWC_SIDEBAND) {
|
||||
// If this was a sideband layer but the stream was removed, reset
|
||||
// it to FRAMEBUFFER. The HWC can change it to OVERLAY in prepare.
|
||||
getLayer()->compositionType = HWC_FRAMEBUFFER;
|
||||
}
|
||||
getLayer()->handle = buffer->handle;
|
||||
}
|
||||
}
|
||||
|
@ -45,9 +45,10 @@ struct framebuffer_device_t;
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class GraphicBuffer;
|
||||
class Fence;
|
||||
class FloatRect;
|
||||
class GraphicBuffer;
|
||||
class NativeHandle;
|
||||
class Region;
|
||||
class String8;
|
||||
class SurfaceFlinger;
|
||||
@ -164,6 +165,7 @@ public:
|
||||
virtual void setFrame(const Rect& frame) = 0;
|
||||
virtual void setCrop(const FloatRect& crop) = 0;
|
||||
virtual void setVisibleRegionScreen(const Region& reg) = 0;
|
||||
virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0;
|
||||
virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
|
||||
virtual void setAcquireFenceFd(int fenceFd) = 0;
|
||||
virtual void setPlaneAlpha(uint8_t alpha) = 0;
|
||||
|
@ -469,6 +469,10 @@ status_t VirtualDisplaySurface::disconnect(int api) {
|
||||
return mSource[SOURCE_SINK]->disconnect(api);
|
||||
}
|
||||
|
||||
status_t VirtualDisplaySurface::setSidebandStream(const sp<NativeHandle>& /*stream*/) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
|
||||
void VirtualDisplaySurface::updateQueueBufferOutput(
|
||||
const QueueBufferOutput& qbo) {
|
||||
uint32_t w, h, transformHint, numPendingBuffers;
|
||||
|
@ -107,6 +107,7 @@ private:
|
||||
virtual status_t connect(const sp<IBinder>& token,
|
||||
int api, bool producerControlledByApp, QueueBufferOutput* output);
|
||||
virtual status_t disconnect(int api);
|
||||
virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
|
||||
|
||||
//
|
||||
// Utility methods
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/NativeHandle.h>
|
||||
#include <utils/StopWatch.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
@ -66,6 +67,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
|
||||
mFormat(PIXEL_FORMAT_NONE),
|
||||
mTransactionFlags(0),
|
||||
mQueuedFrames(0),
|
||||
mSidebandStreamChanged(false),
|
||||
mCurrentTransform(0),
|
||||
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
|
||||
mCurrentOpacity(true),
|
||||
@ -118,7 +120,7 @@ void Layer::onFirstRef() {
|
||||
mBufferQueue = new SurfaceTextureLayer(mFlinger);
|
||||
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
|
||||
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
|
||||
mSurfaceFlingerConsumer->setFrameAvailableListener(this);
|
||||
mSurfaceFlingerConsumer->setContentsChangedListener(this);
|
||||
mSurfaceFlingerConsumer->setName(mName);
|
||||
|
||||
#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
|
||||
@ -158,6 +160,13 @@ void Layer::onFrameAvailable() {
|
||||
mFlinger->signalLayerUpdate();
|
||||
}
|
||||
|
||||
void Layer::onSidebandStreamChanged() {
|
||||
if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
|
||||
// mSidebandStreamChanged was false
|
||||
mFlinger->signalLayerUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
// called with SurfaceFlinger::mStateLock from the drawing thread after
|
||||
// the layer has been remove from the current state list (and just before
|
||||
// it's removed from the drawing state list)
|
||||
@ -413,9 +422,13 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
|
||||
Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
|
||||
layer.setVisibleRegionScreen(visible);
|
||||
|
||||
// NOTE: buffer can be NULL if the client never drew into this
|
||||
// layer yet, or if we ran out of memory
|
||||
layer.setBuffer(mActiveBuffer);
|
||||
if (mSidebandStream.get()) {
|
||||
layer.setSidebandStream(mSidebandStream);
|
||||
} else {
|
||||
// NOTE: buffer can be NULL if the client never drew into this
|
||||
// layer yet, or if we ran out of memory
|
||||
layer.setBuffer(mActiveBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
|
||||
@ -907,7 +920,7 @@ bool Layer::setLayerStack(uint32_t layerStack) {
|
||||
|
||||
bool Layer::onPreComposition() {
|
||||
mRefreshPending = false;
|
||||
return mQueuedFrames > 0;
|
||||
return mQueuedFrames > 0 || mSidebandStreamChanged;
|
||||
}
|
||||
|
||||
void Layer::onPostComposition() {
|
||||
@ -950,6 +963,11 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
|
||||
{
|
||||
ATRACE_CALL();
|
||||
|
||||
if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
|
||||
// mSidebandStreamChanged was true
|
||||
mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
|
||||
}
|
||||
|
||||
Region outDirtyRegion;
|
||||
if (mQueuedFrames > 0) {
|
||||
|
||||
|
@ -66,7 +66,7 @@ class SurfaceFlinger;
|
||||
* This also implements onFrameAvailable(), which notifies SurfaceFlinger
|
||||
* that new data has arrived.
|
||||
*/
|
||||
class Layer : public SurfaceFlingerConsumer::FrameAvailableListener {
|
||||
class Layer : public SurfaceFlingerConsumer::ContentsChangedListener {
|
||||
static int32_t sSequence;
|
||||
|
||||
public:
|
||||
@ -313,8 +313,9 @@ protected:
|
||||
|
||||
|
||||
private:
|
||||
// Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener
|
||||
// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
|
||||
virtual void onFrameAvailable();
|
||||
virtual void onSidebandStreamChanged();
|
||||
|
||||
void commitTransaction();
|
||||
|
||||
@ -351,10 +352,12 @@ private:
|
||||
|
||||
// thread-safe
|
||||
volatile int32_t mQueuedFrames;
|
||||
volatile int32_t mSidebandStreamChanged; // used like an atomic boolean
|
||||
FrameTracker mFrameTracker;
|
||||
|
||||
// main thread
|
||||
sp<GraphicBuffer> mActiveBuffer;
|
||||
sp<NativeHandle> mSidebandStream;
|
||||
Rect mCurrentCrop;
|
||||
uint32_t mCurrentTransform;
|
||||
uint32_t mCurrentScalingMode;
|
||||
|
@ -21,8 +21,9 @@
|
||||
|
||||
#include <private/gui/SyncFeatures.h>
|
||||
|
||||
#include <utils/Trace.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/NativeHandle.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
@ -112,6 +113,10 @@ bool SurfaceFlingerConsumer::getTransformToDisplayInverse() const {
|
||||
return mTransformToDisplayInverse;
|
||||
}
|
||||
|
||||
sp<NativeHandle> SurfaceFlingerConsumer::getSidebandStream() const {
|
||||
return mConsumer->getSidebandStream();
|
||||
}
|
||||
|
||||
// We need to determine the time when a buffer acquired now will be
|
||||
// displayed. This can be calculated:
|
||||
// time when previous buffer's actual-present fence was signaled
|
||||
@ -154,6 +159,26 @@ nsecs_t SurfaceFlingerConsumer::computeExpectedPresent()
|
||||
return prevVsync + hwcLatency * vsyncPeriod + extraPadding;
|
||||
}
|
||||
|
||||
void SurfaceFlingerConsumer::setContentsChangedListener(
|
||||
const wp<ContentsChangedListener>& listener) {
|
||||
setFrameAvailableListener(listener);
|
||||
Mutex::Autolock lock(mMutex);
|
||||
mContentsChangedListener = listener;
|
||||
}
|
||||
|
||||
void SurfaceFlingerConsumer::onSidebandStreamChanged() {
|
||||
sp<ContentsChangedListener> listener;
|
||||
{ // scope for the lock
|
||||
Mutex::Autolock lock(mMutex);
|
||||
ALOG_ASSERT(mFrameAvailableListener.unsafe_get() == mContentsChangedListener.unsafe_get());
|
||||
listener = mContentsChangedListener.promote();
|
||||
}
|
||||
|
||||
if (listener != NULL) {
|
||||
listener->onSidebandStreamChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
|
||||
|
@ -27,6 +27,10 @@ namespace android {
|
||||
*/
|
||||
class SurfaceFlingerConsumer : public GLConsumer {
|
||||
public:
|
||||
struct ContentsChangedListener: public FrameAvailableListener {
|
||||
virtual void onSidebandStreamChanged() = 0;
|
||||
};
|
||||
|
||||
SurfaceFlingerConsumer(const sp<BufferQueue>& bq, uint32_t tex)
|
||||
: GLConsumer(bq, tex, GLConsumer::TEXTURE_EXTERNAL, false)
|
||||
{}
|
||||
@ -54,9 +58,19 @@ public:
|
||||
// must be called from SF main thread
|
||||
bool getTransformToDisplayInverse() const;
|
||||
|
||||
// Sets the contents changed listener. This should be used instead of
|
||||
// ConsumerBase::setFrameAvailableListener().
|
||||
void setContentsChangedListener(const wp<ContentsChangedListener>& listener);
|
||||
|
||||
sp<NativeHandle> getSidebandStream() const;
|
||||
|
||||
private:
|
||||
nsecs_t computeExpectedPresent();
|
||||
|
||||
virtual void onSidebandStreamChanged();
|
||||
|
||||
wp<ContentsChangedListener> mContentsChangedListener;
|
||||
|
||||
// Indicates this buffer must be transformed by the inverse transform of the screen
|
||||
// it is displayed onto. This is applied after GLConsumer::mCurrentTransform.
|
||||
// This must be set/read from SurfaceFlinger's main thread.
|
||||
|
Loading…
Reference in New Issue
Block a user