1. 创建Activity和SurfaceFlinger之间的联系: SurfaceSession
因为一个ViewRootImple对应一个DecorView. 一个DecorView又对应一个PhoneWindow.
而一个PhoneWindow同时对应一个Activity. 所以一个Activity对应SF端的一个(ISurfaceComposerClient)Client.
![](https://img-blog.csdn.net/20130621141235812?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmlydXMwMjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
frameworks/base/core/java/android/view/ViewRootImpl.java
setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mInputChannel);
}
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets,
InputChannel outInputChannel) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
outContentInsets, outInputChannel);
}
frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Rect outContentInsets, InputChannel outInputChannel) {
win = new WindowState(this, session, client, token,
...
win.attach();
}
frameworks/base/services/java/com/android/server/wm/WindowState.java
void attach() {
mSession.windowAddedLocked();
}
frameworks/base/services/java/com/android/server/wm/Session.java
void windowAddedLocked() {
if (mSurfaceSession == null) {
mSurfaceSession = new SurfaceSession();
mService.mSessions.add(this);
}
mNumWindow++;
}
frameworks/base/core/java/android/view/SurfaceSession.java
/** Create a new connection with the surface flinger. */
public SurfaceSession() {
mNativeClient = nativeCreate();
}
frameworks/base/core/jni/android_view_SurfaceSession.cpp
static jint nativeCreate(JNIEnv* env, jclass clazz) {
SurfaceComposerClient* client = new SurfaceComposerClient();
client->incStrong(clazz);
return reinterpret_cast<jint>(client);
}
frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT), mComposer(Composer::getInstance())
{
}
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
if (sm != 0) {
sp<ISurfaceComposerClient> conn = sm->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
返回的是Client的ISurfaceComposerClient
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
sp<ISurfaceComposerClient> bclient;
sp<Client> client(new Client(this)); // mFlinger(flinger), mNameGenerator(1)
status_t err = client->initCheck(); // return NO_ERROR;
if (err == NO_ERROR) {
bclient = client;
}
return bclient;
}
2. Surface的建立
frameworks/base/core/java/android/view/ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) {
int relayoutResult = mWindowSession.relayout(
mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mWinFrame, mPendingContentInsets, mPendingVisibleInsets,
mPendingConfiguration, mSurface);
}
frameworks/base/services/java/com/android/server/wm/Session.java
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
int flags, Rect outFrame, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, flags,
outFrame, outContentInsets, outVisibleInsets,
outConfig, outSurface);
return res;
}
frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
}
............ 分析中。。
frameworks/base/core/java/android/view/Surface.java
frameworks/base/core/jni/android_view_Surface.cpp
在这里,Surface根据前面创建的SurfaceSession找到在SF端对应的Client对象。通过Client对象创建一个SurfaceControl并它保存在 gSurfaceClassInfo.mNativeSurfaceControl中。
static void nativeCreate(JNIEnv* env, jobject surfaceObj, jobject sessionObj,
jstring nameStr, jint w, jint h, jint format, jint flags) {
...
sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
sp<SurfaceControl> surface = client->createSurface
String8(name.c_str()), w, h, format, flags);
setSurfaceControl(env, surfaceObj, surface);
}
frameworks/base/core/jni/android_view_SurfaceSession.cpp
Client对象保存在gSurfaceSessionClassInfo.mNativeClient中。
sp<SurfaceComposerClient> android_view_SurfaceSession_getClient(
JNIEnv* env, jobject surfaceSessionObj) {
return reinterpret_cast<SurfaceComposerClient*>(
env->GetIntField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient));
}
frameworks/native/libs/gui/SurfaceComposerClient.cpp
将mClient创建的ISurface包裹成一个SurfaceControl. 一个包含ISurface, ISurfaceComposerClient的对象。
sp<SurfaceControl> SurfaceComposerClient::createSurface(
const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags)
{
sp<SurfaceControl> result;
if (mStatus == NO_ERROR) {
ISurfaceComposerClient::surface_data_t data;
sp<ISurface> surface = mClient->createSurface(&data, name,
w, h, format, flags);
if (surface != 0) {
result = new SurfaceControl(this, surface, data);
}
}
return result;
}
SurfaceControl::SurfaceControl(
const sp<SurfaceComposerClient>& client,
const sp<ISurface>& surface,
const ISurfaceComposerClient::surface_data_t& data)
: mClient(client), mSurface(surface),
mToken(data.token), mIdentity(data.identity)
{
}
frameworks/native/services/surfaceflinger/Client.cpp
创建layer
sp<ISurface> Client::createSurface(
ISurfaceComposerClient::surface_data_t* params,
const String8& name,
uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
class MessageCreateLayer : public MessageBase {
...
sp<ISurface> getResult() const { return result; }
virtual bool handler() {
result = flinger->createLayer(params, name, client,
w, h, format, flags);
return true;
}
};
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
params, name, this, w, h, format, flags);
mFlinger->postMessageSync(msg);
return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
创建Layer, 并将这个创建的Layer添加到Client的mLayers中。返回给客户端的是一个ISurface类型的BSurface. BSurface继承BnSurface.
sp<ISurface> SurfaceFlinger::createLayer(
ISurfaceComposerClient::surface_data_t* params,
const String8& name,
const sp<Client>& client,
uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
sp<LayerBaseClient> layer;
sp<ISurface> surfaceHandle;
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal:
layer = createNormalLayer(client, w, h, flags, format);
break;
}
if (layer != 0) {
layer->initStates(w, h, flags); //set mCurrentState of layer in LayerBase, e.g. w, h, flags, sequence...
layer->setName(name);
ssize_t token = addClientLayer(client, layer);
surfaceHandle = layer->getSurface();
if (surfaceHandle != 0) {
params->token = token;
params->identity = layer->getIdentity();
}
setTransactionFlags(eTransactionNeeded);
}
return surfaceHandle;
}
sp<Layer> SurfaceFlinger::createNormalLayer(
const sp<Client>& client,
uint32_t w, uint32_t h, uint32_t flags,
PixelFormat& format)
{
switch (format) {
//PIXEL_FORMAT_RGBA_8888 or PIXEL_FORMAT_RGBX_8888 etc
}
sp<Layer> layer = new Layer(this, client); //上图显示Layer的继承关系
status_t err = layer->setBuffers(w, h, format, flags);
return layer;
}
frameworks/native/services/surfaceflinger/Layer.cpp
Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client)
: LayerBaseClient(flinger, client),
mTextureName(-1U),
mQueuedFrames(0),
mCurrentTransform(0),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mCurrentOpacity(true),
mRefreshPending(false),
mFrameLatencyNeeded(false),
mFrameLatencyOffset(0),
mFormat(PIXEL_FORMAT_NONE),
mGLExtensions(GLExtensions::getInstance()),
mOpaqueLayer(true),
mSecure(false),
mProtectedByApp(false)
{
mCurrentCrop.makeInvalid();
glGenTextures(1, &mTextureName);
}
这里的SurfaceTexutreLayer继承BufferQueue,所以STL就相当于Layer的BufferQueue. 而且SurfaceTexture管理BufferQueue.
BufferQueue有个GrafficBufferAlloc.
void Layer::onFirstRef()
{
LayerBaseClient::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(); //相当于BufferQueue
mSurfaceTexture = new SurfaceTexture(mTextureName, true,
GL_TEXTURE_EXTERNAL_OES, false, bq);
mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
mSurfaceTexture->setSynchronousMode(true);
const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); //get PRIMARY DISPLAY stored in mDisplays[]
updateTransformHint(hw);
}
SurfaceTextureLayer::SurfaceTextureLayer() : BufferQueue(true) {
}//SurfaceTextureLayer is a BufferQueue
frameworks/native/libs/gui/SurfaceTexture.cpp
SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode, GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) : ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue), mCurrentTransform(0), mCurrentTimestamp(0), mFilteringEnabled(true), mTexName(tex), #ifdef USE_FENCE_SYNC mUseFenceSync(useFenceSync), #else mUseFenceSync(false), #endif mTexTarget(texTarget), mEglDisplay(EGL_NO_DISPLAY), mEglContext(EGL_NO_CONTEXT), mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), mAttached(true) { memcpy(mCurrentTransformMatrix, mtxIdentity, sizeof(mCurrentTransformMatrix)); mBufferQueue->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); }
frameworks/native/libs/gui/BufferQueue.cpp
BufferQueue::BufferQueue(bool allowSynchronousMode, const sp<IGraphicBufferAlloc>& allocator) : mDefaultWidth(1), mDefaultHeight(1), mMaxAcquiredBufferCount(1), mDefaultMaxBufferCount(2), mOverrideMaxBufferCount(0), mSynchronousMode(false), mAllowSynchronousMode(allowSynchronousMode), mConnectedApi(NO_CONNECTED_API), mAbandoned(false), mFrameCounter(0), mBufferHasBeenQueued(false), mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888), mConsumerUsageBits(0), mTransformHint(0) { if (allocator == NULL) { sp<ISurfaceComposer> composer(ComposerService::getComposerService()); mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); } else { mGraphicBufferAlloc = allocator; } }
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() { sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); return gba; }
frameworks/native/services/surfaceflinger/GraphicBufferAlloc.cpp
GraphicBufferAlloc::GraphicBufferAlloc() { }
status_t Layer::setBuffers( uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags)
{
// this surfaces pixel format
PixelFormatInfo info;
status_t err = getPixelFormatInfo(format, &info);
mFormat = format;
mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
mCurrentOpacity = getOpacityForFormat(format);
mSurfaceTexture->setDefaultBufferSize(w, h);
mSurfaceTexture->setDefaultBufferFormat(format);
mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
return NO_ERROR;
}
SurfaceTexture.cpp
status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
{
Mutex::Autolock lock(mMutex);
mDefaultWidth = w;
mDefaultHeight = h;
return mBufferQueue->setDefaultBufferSize(w, h);
}
frameworks/native/libs/gui/BufferQueue.cpp
status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h)
{
Mutex::Autolock lock(mMutex);
mDefaultWidth = w;
mDefaultHeight = h;
return OK;
}
ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
const sp<LayerBaseClient>& lbc)
{
// attach this layer to the client
size_t name = client->attachLayer(lbc);
// add this layer to the current state list
Mutex::Autolock _l(mStateLock);
mCurrentState.layersSortedByZ.add(lbc);
return ssize_t(name);
}
// protected by mLock
DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers;
size_t Client::attachLayer(const sp<LayerBaseClient>& layer)
{
Mutex::Autolock _l(mLock);
size_t name = mNameGenerator++;
mLayers.add(name, layer);
return name;
}
sp<ISurface> LayerBaseClient::getSurface()
{
sp<ISurface> s;
Mutex::Autolock _l(mLock);
mHasSurface = true;
s = createSurface();
mClientSurfaceBinder = s->asBinder();
return s;
}
sp<ISurface> LayerBaseClient::createSurface()
{
class BSurface : public BnSurface, public LayerCleaner {
virtual sp<ISurfaceTexture> getSurfaceTexture() const { return 0; }
public:
BSurface(const sp<SurfaceFlinger>& flinger,
const sp<LayerBaseClient>& layer)
: LayerCleaner(flinger, layer) { }
};
sp<ISurface> sur(new BSurface(mFlinger, this));
return sur;
}
3. Surface动作传导到SurfaceFlinger的过程
Surface.openTransaction();
...
surface.setSize(surface.getWidth(), surface.getHeight());
...
Surface.closeTransaction();
/** start a transaction @hide */
public static void openTransaction() {
nativeOpenTransaction();
}
/** @hide */
public void setSize(int w, int h) {
mWidth = w;
mHeight = h;
nativeSetSize(w, h);
}
public static void closeTransaction() {
nativeCloseTransaction();
}
/** start a transaction @hide */
public static void openTransaction() {
nativeOpenTransaction();
}
/** @hide */
public void setSize(int w, int h) {
mWidth = w;
mHeight = h;
nativeSetSize(w, h);
}
public static void closeTransaction() {
nativeCloseTransaction();
}
static void nativeOpenTransaction(JNIEnv* env, jclass clazz) {
SurfaceComposerClient::openGlobalTransaction();
}
static void nativeSetSize(JNIEnv* env, jobject surfaceObj, jint w, jint h) {
sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
if (surface == NULL) return;
status_t err = surface->setSize(w, h);
if (err < 0 && err != NO_INIT) {
doThrowIAE(env);
}
}
static void nativeCloseTransaction(JNIEnv* env, jclass clazz) {
SurfaceComposerClient::closeGlobalTransaction();
}
static void nativeOpenTransaction(JNIEnv* env, jclass clazz) {
SurfaceComposerClient::openGlobalTransaction();
}
status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
return client->setSize(mToken, w, h);
}
frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::openGlobalTransaction() {
// Currently a no-op
}
status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) {
return getComposer().setSize(this, id, w, h);
}
status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
SurfaceID id, uint32_t w, uint32_t h) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= layer_state_t::eSizeChanged;
s->w = w;
s->h = h;
// Resizing a surface makes the transaction synchronous.
mForceSynchronous = true;
return NO_ERROR;
}
layer_state_t* Composer::getLayerStateLocked(
const sp<SurfaceComposerClient>& client, SurfaceID id) {
ComposerState s;
s.client = client->mClient;
s.state.surface = id;
ssize_t index = mComposerStates.indexOf(s);
if (index < 0) {
// we don't have it, add an initialized layer_state to our list
index = mComposerStates.add(s);
}
ComposerState* const out = mComposerStates.editArray();
return &(out[index].state);
}
Surface.setSize()方法将要修改的类型添加到mComposerStates[index].state->what中。接着是closeTransaction方法。
void Composer::closeGlobalTransactionImpl(bool synchronous) {
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
Vector<ComposerState> transaction;
Vector<DisplayState> displayTransaction;
uint32_t flags = 0;
{ // scope for the lock
Mutex::Autolock _l(mLock);
transaction = mComposerStates;
mComposerStates.clear();
displayTransaction = mDisplayStates;
mDisplayStates.clear();
...
}
sm->setTransactionState(transaction, displayTransaction, flags);
}
Server Side: SurfaceFlinger.
void SurfaceFlinger::setTransactionState(
const Vector<ComposerState>& state,
const Vector<DisplayState>& displays,
uint32_t flags)
{
Mutex::Autolock _l(mStateLock);
size_t count = displays.size();
for (size_t i=0 ; i<count ; i++) {
const DisplayState& s(displays[i]);
transactionFlags |= setDisplayStateLocked(s);
}
count = state.size();
for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]);
if (s.client != NULL) {
sp<IBinder> binder = s.client->asBinder();
if (binder != NULL) {
String16 desc(binder->getInterfaceDescriptor());
if (desc == ISurfaceComposerClient::descriptor) {
sp<Client> client( static_cast<Client *>(s.client.get()) );
//返回flags |= eTraversalNeeded;
transactionFlags |= setClientStateLocked(client, s.state);
}
}
}
}
if (transactionFlags) {
// this triggers the transaction
setTransactionFlags(transactionFlags);
...
while (mTransactionPending) {
status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
// just in case something goes wrong in SF, return to the
// called after a few seconds.
ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
mTransactionPending = false;
break;
}
}
}
}
uint32_t SurfaceFlinger::setClientStateLocked(
const sp<Client>& client,
const layer_state_t& s)
{
uint32_t flags = 0;
sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
if (layer != 0) {
const uint32_t what = s.what;
...
if (what & layer_state_t::eSizeChanged) {
if (layer->setSize(s.w, s.h)) {
flags |= eTraversalNeeded;
}
}
...
}
return flags;
}
setTransactionFlags() 给SurfaceFlinger的mTransactionFlags添加eTraversalNeeded标志位。如果mTransactionFlags之前没有被设过这个标志位的话,wake ther server up by signalTransaction()
uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
{
uint32_t old = android_atomic_or(flags, &mTransactionFlags); //更新mTransactionFlags变量, 返回mTransactionFlags在执行android_atomic_or(flags, &mTransactionFlags)之前的值。
if ((old & flags)==0) { // wake the server up
signalTransaction();
}
return old;
}
bool LayerBase::setSize(uint32_t w, uint32_t h) {
if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
return false;
mCurrentState.requested.w = w;
mCurrentState.requested.h = h;
requestTransaction();
return true;
}
bool LayerBase::requestTransaction() {
int32_t old = setTransactionFlags(eTransactionNeeded);
return ((old & eTransactionNeeded) == 0);
}
uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
return android_atomic_or(flags, &mTransactionFlags); //mTransactionFlags变量添加eTransactionNeeded标志位
}
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::signalTransaction() {
mEventQueue.invalidate();
}
mEventQueue is init() in SurfaceFlinger.OnfirstRef() and in SurfaceFlinger.ReadyToRun()
// start the EventThread
mEventThread = new EventThread(this);
mEventQueue.setEventThread(mEventThread);
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
mEventThread = eventThread;
mEvents = eventThread->createEventConnection(); //
mEventTube = mEvents->getDataChannel();
mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,
MessageQueue::cb_eventReceiver, this);
}
/* when INVALIDATE_ON_VSYNC is set, SF only processes
* buffer updates on VSYNC and performs a refresh immediately
* after.
*
* when INVALIDATE_ON_VSYNC is set to false, SF will instead
* perform the buffer updates immediately, but the refresh only
* at the next VSYNC.
* THIS MODE IS BUGGY ON GALAXY NEXUS AND WILL CAUSE HANGS
*/
#define INVALIDATE_ON_VSYNC 1
void MessageQueue::invalidate() {
#if INVALIDATE_ON_VSYNC
mEvents->requestNextVsync();
#else
mHandler->dispatchInvalidate();
#endif
}
EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
: mFlinger(flinger),
mLastVSyncTimestamp(0),
mUseSoftwareVSync(false),
mLastVSyncDisplayType(-1),
mDebugVsyncEnabled(false),
mVsyncDisabled(false){
for (int32_t i=0 ; i<HWC_DISPLAY_TYPES_SUPPORTED ; i++) {
mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mVSyncEvent[i].header.id = 0;
mVSyncEvent[i].header.timestamp = 0;
mVSyncEvent[i].vsync.count = 0;
}
}
void EventThread::onFirstRef() {
...
run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
}
EventThread创建了Connection, 将新建的Connection add 到mDisplayEventConnections;
sp<EventThread::Connection> EventThread::createEventConnection() const {
return new Connection(const_cast<EventThread*>(this));
}
EventThread::Connection::Connection(
const sp<EventThread>& eventThread)
: count(-1), mEventThread(eventThread), mChannel(new BitTube()), mLastRequestTimestamp(0)
{
}
void EventThread::Connection::onFirstRef() {
// NOTE: mEventThread doesn't hold a strong reference on us
mEventThread->registerDisplayEventConnection(this);
}
status_t EventThread::registerDisplayEventConnection( const sp<EventThread::Connection>& connection) { Mutex::Autolock _l(mLock);
.add(connection);mDisplayEventConnections
mCondition.broadcast();
return NO_ERROR;
}
BitTube::BitTube()
: mSendFd(-1), mReceiveFd(-1)
{
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
int size = SOCKET_BUFFER_SIZE;
setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
fcntl(sockets[0], F_SETFL, O_NONBLOCK);
fcntl(sockets[1], F_SETFL, O_NONBLOCK);
mReceiveFd = sockets[0];
mSendFd = sockets[1];
} else {
mReceiveFd = -errno;
ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
}
}
frameworks/native/services/surfaceflinger/EventThread.cpp
void EventThread::Connection::requestNextVsync() {
mEventThread->requestNextVsync(this);
}
void EventThread::requestNextVsync(
const sp<EventThread::Connection>& connection) {
Mutex::Autolock _l(mLock);
if (connection->count < 0) {
connection->count = 0;
connection->mLastRequestTimestamp = systemTime(CLOCK_MONOTONIC);
if(Connection::s_oldestUnreponsedRequestTimestamp == 0) {
//这个时间戳会在waitForEvent()时判断VSYNC是否超时
Connection::s_oldestUnreponsedRequestTimestamp = connection->mLastRequestTimestamp;
}
if (mVsyncDisabled) {
// FIXME: how do we decide which display id the fake
// vsync came from ?
mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mVSyncEvent[0].header.id = HWC_DISPLAY_PRIMARY;
mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
mVSyncEvent[0].vsync.count++;
}
mCondition.broadcast(); //触发等待中的mCondition.wait;
}
}
bool EventThread::threadLoop() {
DisplayEventReceiver::Event event;
Vector< sp<EventThread::Connection> > signalConnections;
signalConnections = waitForEvent(&event);
// dispatch events to listeners...
const size_t count = signalConnections.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Connection>& conn(signalConnections[i]);
// now see if we still need to report this event
status_t err = conn->postEvent(event);
if (err == -EAGAIN || err == -EWOULDBLOCK) {
// The destination doesn't accept events anymore, it's probably
// full. For now, we just drop the events on the floor.
// FIXME: Note that some events cannot be dropped and would have
// to be re-sent later.
// Right-now we don't have the ability to do this.
ALOGW("EventThread: dropping event (%08x) for connection %p",
event.header.type, conn.get());
} else if (err < 0) {
// handle any other error on the pipe as fatal. the only
// reasonable thing to do is to clean-up this connection.
// The most common error we'll get here is -EPIPE.
removeDisplayEventConnection(signalConnections[i]);
}
}
return true;
}
// This will return when (1) a vsync event has been received, and (2) there was
// at least one connection interested in receiving it when we started waiting.
Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
DisplayEventReceiver::Event* event)
{
Mutex::Autolock _l(mLock);
Vector< sp<EventThread::Connection> > signalConnections;
nsecs_t currentVSyncTimestamp = 0;
int currentVSyncDisplayType = -1;
do {
bool eventPending = false;
bool waitForVSync = false;
size_t vsyncCount = 0;
nsecs_t timestamp = 0;
for (int32_t i=0 ; i<HWC_DISPLAY_TYPES_SUPPORTED ; i++) {
timestamp = mVSyncEvent[i].header.timestamp;
if (timestamp) {
//把当前Vsync event的时间戳赋给currentVSyncTimestamp, 并把mVSyncEvent[i]的时间戳清零。
// we have a vsync event to dispatch
currentVSyncTimestamp = timestamp;
currentVSyncDisplayType = i;
*event = mVSyncEvent[i];
mVSyncEvent[i].header.timestamp = 0;
vsyncCount = mVSyncEvent[i].vsync.count;
break;
}
}
...
// find out connections waiting for events
size_t count = mDisplayEventConnections.size();
for (size_t i=0 ; i<count ; i++) {
sp<Connection> connection(mDisplayEventConnections[i].promote());
if (connection != NULL) {
bool added = false;
//connection->count的值在EventThread::requestNextVsync中从初始时的-1变成0
if (connection->count >= 0) {
// we need vsync events because at least
// one connection is waiting for it
waitForVSync = true;
if (timestamp) {
// we consume the event only if it's time
// (ie: we received a vsync event)
//
if (connection->count == 0) {
// fired this time around
connection->count = -1;
signalConnections.add(connection);
added = true;
} else if (connection->count == 1 ||
(vsyncCount % connection->count) == 0) {
// continuous event, and time to report it
signalConnections.add(connection);
added = true;
}
}
}
if (eventPending && !timestamp && !added) {
// we don't have a vsync event to process
// (timestamp==0), but we have some pending
// messages.
signalConnections.add(connection);
}
} else {
// we couldn't promote this reference, the connection has
// died, so clean-up!
mDisplayEventConnections.removeAt(i);
--i; --count;
}
}
// Here we figure out if we need to enable or disable vsyncs
if (timestamp && !waitForVSync) {
// we received a VSYNC but we have no clients
// don't report it, and disable VSYNC events
disableVSyncLocked();
} else if (!timestamp && waitForVSync) {
// we have at least one client, so we want vsync enabled
// (TODO: this function is called right after we finish
// notifying clients of a vsync, so this call will be made
// at the vsync rate, e.g. 60fps. If we can accurately
// track the current state we could avoid making this call
// so often.)
enableVSyncLocked();
}
// note: !timestamp implies signalConnections.isEmpty(), because we
// don't populate signalConnections if there's no vsync pending
if (!timestamp && !eventPending) {
// wait for something to happen
if (waitForVSync) {
// This is where we spend most of our time, waiting
// for vsync events and new client registrations.
//
// If the screen is off, we can't use h/w vsync, so we
// use a 16ms timeout instead. It doesn't need to be
// precise, we just need to keep feeding our clients.
//
// We don't want to stall if there's a driver bug, so we
// use a (long) timeout when waiting for h/w vsync, and
// generate fake events when necessary.
bool softwareSync = mUseSoftwareVSync;
nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);
if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {
if (!softwareSync) {
ALOGW("Timed out waiting for hw vsync; faking it");
}
// FIXME: how do we decide which display id the fake
// vsync came from ?
mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mVSyncEvent[0].header.id = HWC_DISPLAY_PRIMARY;
mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
mVSyncEvent[0].vsync.count++;
}
} else {
// Nobody is interested in vsync, so we just want to sleep.
// h/w vsync should be disabled, so this will wait until we
// get a new connection, or an existing connection becomes
// interested in receiving vsync again.
mCondition.wait(mLock);
}
}
} while (signalConnections.isEmpty());
mLastVSyncTimestamp = currentVSyncTimestamp;
mLastVSyncDisplayType = currentVSyncDisplayType;
//如果Vsync时间超出100ms, 就报warning.
//take care are only single shot request mode
if(Connection::s_oldestUnreponsedRequestTimestamp != 0){
const nsecs_t VSYNC_WARNING_THRESHOLD = 100000000; //100ms
nsecs_t syncResponseinterval = systemTime(CLOCK_MONOTONIC) -
Connection::s_oldestUnreponsedRequestTimestamp;
if( syncResponseinterval > VSYNC_WARNING_THRESHOLD ){
ALOGW(" warning! VSYNC take %lld ms to deliver!" ,syncResponseinterval/1000000);
}
Connection::s_oldestUnreponsedRequestTimestamp = 0;
}
// here we're guaranteed to have a timestamp and some connections to signal
// (The connections might have dropped out of mDisplayEventConnections
// while we were asleep, but we'll still have strong references to them.)
return signalConnections;
}
frameworks/native/services/surfaceflinger/EventThread.cpp
status_t EventThread::Connection::postEvent(
const DisplayEventReceiver::Event& event) {
ssize_t size = DisplayEventReceiver::sendEvents(mChannel, &event, 1);
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
frameworks/native/services/surfaceflinger/DisplayEventReceiver.cpp
ssize_t DisplayEventReceiver::sendEvents(const sp<BitTube>& dataChannel,
Event const* events, size_t count)
{
return BitTube::sendObjects(dataChannel, events, count);
}
BitTube.cpp
ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
void const* events, size_t count, size_t objSize)
{
ssize_t numObjects = 0;
for (size_t i=0 ; i<count ; i++) {
const char* vaddr = reinterpret_cast<const char*>(events) + objSize * i;
ssize_t size = tube->write(vaddr, objSize);
if (size < 0) {
// error occurred
return size;
} else if (size == 0) {
// no more space
break;
}
numObjects++;
}
return numObjects;
}
ssize_t BitTube::write(void const* vaddr, size_t size)
{
ssize_t err, len;
do {
len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
err = len < 0 ? errno : 0;
} while (err == EINTR);
return err == 0 ? len : -err;
}