Skip to content

Instantly share code, notes, and snippets.

@browny
Created January 4, 2013 09:31
Show Gist options
  • Save browny/4451217 to your computer and use it in GitHub Desktop.
Save browny/4451217 to your computer and use it in GitHub Desktop.
Chap5. BufferQueue 和 Comsumer 的關係
void Layer::onFirstRef()
{
struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
FrameQueuedListener(Layer* layer) : mLayer(layer) { }
private:
wp<Layer> mLayer;
virtual void onFrameAvailable() {
sp<Layer> that(mLayer.promote());
if (that != 0) {
that->onFrameQueued();
}
}
};
// Creates a custom BufferQueue for SurfaceTexture to use
sp<BufferQueue> bq = new SurfaceTextureLayer();
mSurfaceTexture = new SurfaceTexture(mTextureName, true,
GL_TEXTURE_EXTERNAL_OES, false, bq);
/*
SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :
ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue), // -->
mCurrentTransform(0),
*/
// SurfaceTexture 就是(繼承) ConsumerBase
// FrameQueuedListener 上面有定義, 就是 SurfaceTexture::FrameAvailableListener 就是 ConsumerBase::FrameAvailableListener
// 把自己這個 Layer 設成這個 SurfaceTexture 的 FrameAvailableListener
// listen 到之後誰來 handle? 就是 Layer 自己, 定義在 FrameQueuedListener 中
// FrameQueuedListener 繼承 SurfaceTexture::FrameAvailableListener, 並實做其 onFrameAvailable() 如下
// Layer::onFrameQueued -> mFlinger->signalLayerUpdate, 由此通知 SF 開始 rendering
mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue) :
mAbandoned(false),
mBufferQueue(bufferQueue) {
// Choose a name using the PID and a process-unique ID.
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
// Note that we can't create an sp<...>(this) in a ctor that will not keep a
// reference once the ctor ends, as that would cause the refcount of 'this'
// dropping to 0 at the end of the ctor. Since all we need is a wp<...>
// that's what we create.
wp<BufferQueue::ConsumerListener> listener;
sp<BufferQueue::ConsumerListener> proxy;
listener = static_cast<BufferQueue::ConsumerListener*>(this);
proxy = new BufferQueue::ProxyConsumerListener(listener);
status_t err = mBufferQueue->consumerConnect(proxy); // proxy 被設為 BufferQueue 的 mConsumerListener
if (err != NO_ERROR) {
CB_LOGE("SurfaceTexture: error connecting to BufferQueue: %s (%d)",
strerror(-err), err);
} else {
mBufferQueue->setConsumerName(mName);
}
}
// ConsumerBase is a base class for BufferQueue consumer end-points. It
// handles common tasks like management of the connection to the BufferQueue
// and the buffer pool.
class ConsumerBase : public virtual RefBase,
protected BufferQueue::ConsumerListener {
public:
struct FrameAvailableListener : public virtual RefBase {
// onFrameAvailable() is called each time an additional frame becomes
// available for consumption. This means that frames that are queued
// while in asynchronous mode only trigger the callback if no previous
// frames are pending. Frames queued while in synchronous mode always
// trigger the callback.
//
// This is called without any lock held and can be called concurrently
// by multiple threads.
virtual void onFrameAvailable() = 0;
};
void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
/* 回想 ...
void Layer::onFirstRef()
{
// 把自己這個 Layer 設成這個 SurfaceTexture 的 FrameAvailableListener
// listen 到之後誰來 handle? 就是 Layer 自己, 定義在 FrameQueuedListener 中
// FrameQueuedListener 繼承 SurfaceTexture::FrameAvailableListener, 並實做其 onFrameAvailable() 如下
// Layer::onFrameQueued -> mFlinger->signalLayerUpdate, 由此通知 SF 開始 rendering
mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
*/
// mFrameAvailableListener is the listener object that will be called when a
// new frame becomes available. If it is not NULL it will be called from
// queueBuffer.
sp<FrameAvailableListener> mFrameAvailableListener;
// 1. ConsumerListener 是一個介面讓 BufferQueue 通知那些對 BufferQueue 發生的事件有興趣的人,並讓他做反應
// 2. ProxyConsumerListener 是 ConsumerListener 的實做
class BufferQueue : public BnSurfaceTexture {
public:
// ConsumerListener is the interface through which the BufferQueue notifies
// the consumer of events that the consumer may wish to react to.
struct ConsumerListener : public virtual RefBase {
// onFrameAvailable is called from queueBuffer each time an additional
// frame becomes available for consumption.
virtual void onFrameAvailable() = 0;
virtual void onBuffersReleased() = 0;
};
// ProxyConsumerListener is a ConsumerListener implementation that keeps a weak
// reference to the actual consumer object. It forwards all calls to that
// consumer object so long as it exists.
class ProxyConsumerListener : public BufferQueue::ConsumerListener {
public:
ProxyConsumerListener(const wp<BufferQueue::ConsumerListener>& consumerListener);
virtual ~ProxyConsumerListener();
virtual void onFrameAvailable();
virtual void onBuffersReleased();
private:
// mConsumerListener is a weak reference to the ConsumerListener. This is
// the raison d'etre of ProxyConsumerListener.
wp<BufferQueue::ConsumerListener> mConsumerListener;
};
// consumerConnect connects a consumer to the BufferQueue. Only one
// consumer may be connected, and when that consumer disconnects the
// BufferQueue is placed into the "abandoned" state, causing most
// interactions with the BufferQueue by the producer to fail.
status_t consumerConnect(const sp<ConsumerListener>& consumer);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment