Created
January 4, 2013 09:31
-
-
Save browny/4451217 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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