基于Android 9.0源碼分析
類圖
- DecorView
- Android窗口的頂級View
- PhoneWindow
- 代表Android窗口
- WindowManagerImpl
- 應(yīng)用通過該類與系統(tǒng)窗口管理服務(wù)通信,關(guān)聯(lián)特定的窗口
- WindowManagerGlobal
- 進(jìn)程全局對象,實現(xiàn)WindowManagerImpl與系統(tǒng)窗口管理服務(wù)的通信
- ViewRootImpl
- 實現(xiàn)了View與窗口管理之間的協(xié)議
- Choreographer
- Choreographer收到顯示子系統(tǒng)發(fā)送的Vsync信號后毒租,協(xié)調(diào)下一幀渲染中的動畫、輸入和繪制過程
- FrameDisplayEventReceiver
- 在應(yīng)用內(nèi)請求是整、接收顯示事件(Vsync信號等)
- ISurfaceComposer
- 定義訪問SurfaceFlinger的Binder IPC接口
- BitTube
- Socket的封裝,用于進(jìn)程間通信民假,可跨進(jìn)程傳遞
Android應(yīng)用與SurfaceFlinger建立連接的過程
Android應(yīng)用在執(zhí)行完Activity的onResume()
后會建立與SurfaceFlinger的連接浮入,以便接受SurfaceFlinger發(fā)送的Vsync信號,下面從ActivityThread
的handleResumeActivity()
開始分析羊异。
public void handleResumeActivity(IBinder token, boolean finalStateRequest, booleanisForward,
String reason) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
// TODO Push resumeArgs into the activity for consideration
// 調(diào)用Activity的onResume的方法
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r == null) {
// We didn't actually resume the activity, so skipping any follow-up actions.
return;
}
......
if (r.window == null && !a.mFinished && willBeVisible) {
// PhoneWindow對象
r.window = r.activity.getWindow();
// DecorView對象
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
// wm為WindowManagerImpl對象
ViewManager wm = a.getWindowManager();
// 窗口布局參數(shù)
WindowManager.LayoutParams l = r.window.getAttributes();
// 設(shè)置Activity的DecorView
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
// Normally the ViewRoot sets up callbacks with the Activity
// in addView->ViewRootImpl#setView. If we are instead reusing
// the decor view we have to notify the view root that the
// callbacks may have changed.
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
// 通常mVisibleFromClient為true
if (a.mVisibleFromClient) {
// mWindowAdded這里為false
if (!a.mWindowAdded) {
a.mWindowAdded = true;
// 設(shè)置DecorView的LayoutParams事秀,添加DecorView到Window
wm.addView(decor, l);
} else {
// The activity will get a callback for this {@link LayoutParams} change
// earlier. However, at that time the decor will not be set (this is set
// in this method), so no action will be taken. This call ensures the
// callback occurs with the decor set.
a.onWindowAttributesChanged(l);
}
}
// If the window has already been added, but during resume
// we started another activity, then don't yet make the
// window visible.
} else if (!willBeVisible) {
if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}
......
}
下面看WindowManagerImpl
的addView()
的實現(xiàn)
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
// 設(shè)置params的token
applyDefaultToken(params);
// 調(diào)用WindowManagerGlobal的addView
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
// view為DecorView
// params為DecorView關(guān)聯(lián)的LayoutParams
// parentWindow為PhoneWindow
if (view == null) {
throw new IllegalArgumentException("view must not be null");
}
if (display == null) {
throw new IllegalArgumentException("display must not be null");
}
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
}
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
if (parentWindow != null) {
// 設(shè)置LayoutParams的token、Title和包名等
parentWindow.adjustLayoutParamsForSubWindow(wparams);
} else {
// If there's no parent, then hardware acceleration for this view is
// set from the application's hardware acceleration setting.
final Context context = view.getContext();
if (context != null
&& (context.getApplicationInfo().flags
& ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
}
synchronized (mLock) {
// Start watching for system property changes.
// 監(jiān)聽系統(tǒng)屬性的改變野舶,觀察者模式
if (mSystemPropertyUpdater == null) {
mSystemPropertyUpdater = new Runnable() {
@Override public void run() {
synchronized (mLock) {
for (int i = mRoots.size() - 1; i >= 0; --i) {
mRoots.get(i).loadSystemProperties();
}
}
}
};
SystemProperties.addChangeCallback(mSystemPropertyUpdater);
}
// 查找DecorView
int index = findViewLocked(view, false);
if (index >= 0) {
if (mDyingViews.contains(view)) {
// Don't wait for MSG_DIE to make it's way through root's queue.
mRoots.get(index).doDie();
} else {
throw new IllegalStateException("View " + view
+ " has already been added to the window manager.");
}
// The previous removeView() had not completed executing. Now it has.
}
// If this is a panel window, then find the window it is being
// attached to for future reference.
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
final int count = mViews.size();
for (int i = 0; i < count; i++) {
if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
panelParentView = mViews.get(i);
}
}
}
// 創(chuàng)建ViewRootImpl
root = new ViewRootImpl(view.getContext(), display);
// 設(shè)置View布局參數(shù)
view.setLayoutParams(wparams);
// DecorView/ViewRootImpl/LayoutParams添加到WindowManagerGlobal
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
// do this last because it fires off messages to start doing things
try {
// 調(diào)用ViewRootImpl的setView()
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}
在ViewRootImpl
的構(gòu)造方法中建立與SurfaceFlinger的連接易迹,下面看ViewRootImpl
的構(gòu)造方法
public ViewRootImpl(Context context, Display display) {
mContext = context;
// mWindowSession為IWindowSession.Stub.Proxy對象,單例模式
mWindowSession = WindowManagerGlobal.getWindowSession();
mDisplay = display;
mBasePackageName = context.getBasePackageName();
mThread = Thread.currentThread();
mLocation = new WindowLeaked(null);
mLocation.fillInStackTrace();
mWidth = -1;
mHeight = -1;
mDirty = new Rect();
mTempRect = new Rect();
mVisRect = new Rect();
mWinFrame = new Rect();
// 創(chuàng)建W對象平道,Binder服務(wù)對象
// 用于接收WindowManager發(fā)送的應(yīng)用窗口感興趣的事件
mWindow = new W(this);
mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
mViewVisibility = View.GONE;
mTransparentRegion = new Region();
mPreviousTransparentRegion = new Region();
mFirst = true; // true for the first time the view is added
mAdded = false;
// 創(chuàng)建View.AttachInfo記錄添加到窗口的View的信息
mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this,
context);
mAccessibilityManager = AccessibilityManager.getInstance(context);
mAccessibilityManager.addAccessibilityStateChangeListener(
mAccessibilityInteractionConnectionManager, mHandler);
mHighContrastTextManager = new HighContrastTextManager();
mAccessibilityManager.addHighTextContrastStateChangeListener(
mHighContrastTextManager, mHandler);
mViewConfiguration = ViewConfiguration.get(context);
mDensity = context.getResources().getDisplayMetrics().densityDpi;
mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
mFallbackEventHandler = new PhoneFallbackEventHandler(context);
// 獲取Choreographer對象赴蝇,在Choreographer構(gòu)造函數(shù)中建立與SurfaceFlinger的連接
mChoreographer = Choreographer.getInstance();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
if (!sCompatibilityDone) {
sAlwaysAssignFocus = mTargetSdkVersion < Build.VERSION_CODES.P;
sCompatibilityDone = true;
}
loadSystemProperties();
}
下面看Choreographer
的getInstance()
的實現(xiàn)
// Choreographer為ThreadLocal對象,關(guān)聯(lián)的線程必須有l(wèi)ooper
public static Choreographer getInstance() {
// 調(diào)用initialValue()創(chuàng)建Choreographer
return sThreadInstance.get();
}
private static final ThreadLocal<Choreographer> sThreadInstance =
new ThreadLocal<Choreographer>() {
@Override
protected Choreographer initialValue() {
Looper looper = Looper.myLooper();
if (looper == null) {
throw new IllegalStateException("The current thread must have a looper!");
}
Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
if (looper == Looper.getMainLooper()) {
mMainInstance = choreographer;
}
return choreographer;
}
};
private Choreographer(Looper looper, int vsyncSource) {
mLooper = looper;
mHandler = new FrameHandler(looper);
// 創(chuàng)建FrameDisplayEventReceiver巢掺,用于接收SurfaceFlinger發(fā)給應(yīng)用的Vsync信號
mDisplayEventReceiver = USE_VSYNC
? new FrameDisplayEventReceiver(looper, vsyncSource)
: null;
mLastFrameTimeNanos = Long.MIN_VALUE;
mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());
// 創(chuàng)建CallbackQueue
mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
for (int i = 0; i <= CALLBACK_LAST; i++) {
mCallbackQueues[i] = new CallbackQueue();
}
// b/68769804: For low FPS experiments.
setFPSDivisor(SystemProperties.getInt(ThreadedRenderer.DEBUG_FPS_DIVISOR, 1));
}
mCallbackQueues
是一個CallbackQueue
數(shù)組句伶,包含四個鏈表
- CALLBACK_INPUT
- 輸入回調(diào),當(dāng)接收到Vsync信號時首先運行陆淀,如處理Move事件
- CALLBACK_ANIMATION
- 動畫回調(diào)考余,在TRAVERSAL之前運行
- CALLBACK_TRAVERSAL
- TRAVERSAL回調(diào),執(zhí)行Measure/Layout/Draw
- CALLBACK_COMMIT
- COMMIT回調(diào)轧苫,處理幀繪制完成后的操作楚堤,如應(yīng)用整理內(nèi)存等
FrameDisplayEventReceiver
繼承自DisplayEventReceiver
,下面分析它構(gòu)造方法
public DisplayEventReceiver(Looper looper, int vsyncSource) {
if (looper == null) {
throw new IllegalArgumentException("looper must not be null");
}
// Looper關(guān)聯(lián)的MessageQueue
mMessageQueue = looper.getQueue();
// Native層的DisplayEventReceiver初始化
mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
vsyncSource);
// CloseGuard用于當(dāng)DisplayEventReceiver被回收時含懊,釋放資源
mCloseGuard.open("dispose");
}
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
jobject messageQueueObj, jint vsyncSource) {
// 所在線程的MessageQueue
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
// 創(chuàng)建NativeDisplayEventReceiver身冬,與SurfaceFlinger建立連接
// 獲取顯示事件socket接收端
sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env,
receiverWeak, messageQueue, vsyncSource);
// 監(jiān)聽顯示事件socket接收端
status_t status = receiver->initialize();
if (status) {
String8 message;
message.appendFormat("Failed to initialize display event receiver. status=%d", status);
jniThrowRuntimeException(env, message.string());
return 0;
}
receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object
return reinterpret_cast<jlong>(receiver.get());
}
下面看NativeDisplayEventReceiver
的構(gòu)造方法
NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env,
jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource) :
// 創(chuàng)建DisplayEventDispatcher
DisplayEventDispatcher(messageQueue->getLooper(),
static_cast<ISurfaceComposer::VsyncSource>(vsyncSource)),
// Java層DisplayEventReceiver弱引用的JNI全局引用保存在mReceiverWeakGlobal中
// 用于后續(xù)向Java層DisplayEventReceiver傳遞顯示事件(Vsync/Hotplug)
mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
mMessageQueue(messageQueue) {
ALOGV("receiver %p ~ Initializing display event receiver.", this);
}
// 成員子對象mReceiver為DisplayEventReceiver對象
DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper,
ISurfaceComposer::VsyncSource vsyncSource) :
mLooper(looper), mReceiver(vsyncSource), mWaitingForVsync(false) {
ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
}
DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource) {
// sf是BpSurfaceComposer對象的強(qiáng)指針(對象)
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != NULL) {
// mEventConnection為BpDisplayEventConnection的強(qiáng)指針
// 為客戶端創(chuàng)建顯示事件連接,通過該連接可以請求SurfaceFlinger發(fā)送Vsync以及接收
// SurfaceFlinger發(fā)送的顯示事件
mEventConnection = sf->createDisplayEventConnection(vsyncSource);
if (mEventConnection != NULL) {
// 創(chuàng)建BitTube
mDataChannel = std::make_unique<gui::BitTube>();
// 通過Binder IPC獲取對應(yīng)的Connection的socket接收端
mEventConnection->stealReceiveChannel(mDataChannel.get());
}
}
}
createDisplayEventConnection()
是一個Binder IPC岔乔,它的實現(xiàn)在ISurfaceComposer中酥筝。
virtual sp<IDisplayEventConnection> createDisplayEventConnection(VsyncSourcevsyncSource)
{
Parcel data, reply;
sp<IDisplayEventConnection> result;
// 接口描述字符串寫入Parcel中
int err = data.writeInterfaceToken(
ISurfaceComposer::getInterfaceDescriptor());
if (err != NO_ERROR) {
return result;
}
// vsyncSource寫入Parcel中
data.writeInt32(static_cast<int32_t>(vsyncSource));
// 請求SurfaceFlinger處理CREATE_DISPLAY_EVENT_CONNECTION
err = remote()->transact(
BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,
data, &reply);
if (err != NO_ERROR) {
ALOGE("ISurfaceComposer::createDisplayEventConnection: error performing "
"transaction: %s (%d)", strerror(-err), -err);
return result;
}
// 在應(yīng)用端reply.readStrongBinder()返回BpBinder的強(qiáng)指針
// interface_case是模板方法
// result為BpDisplayEventConnection的強(qiáng)指針
result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder());
return result;
}
下面看SurfaceFlinger
處理CREATE_DISPLAY_EVENT_CONNECTION
請求。
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
......
case CREATE_DISPLAY_EVENT_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
// 為客戶端創(chuàng)建連接
sp<IDisplayEventConnection> connection(createDisplayEventConnection(
static_cast<ISurfaceComposer::VsyncSource>(data.readInt32())));
// connection寫入reply Parcel中
reply->writeStrongBinder(IInterface::asBinder(connection));
return NO_ERROR;
}
......
}
}
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
ISurfaceComposer::VsyncSource vsyncSource) {
if (vsyncSource == eVsyncSourceSurfaceFlinger) {
return mSFEventThread->createEventConnection();
} else {
// 調(diào)用EventThread的createEventConnection()
return mEventThread->createEventConnection();
}
}
sp<BnDisplayEventConnection> EventThread::createEventConnection() const {
// 創(chuàng)建Connection
return new Connection(const_cast<EventThread*>(this));
}
Connection
是一個Binder服務(wù)類雏门,繼承自BnDisplayEventConnection嘿歌,它的作用
- 處理客戶端應(yīng)用的Vsync請求
- 向客戶端應(yīng)用發(fā)送顯示事件(Vsync/Hotplug)
下面看Connection
的構(gòu)造方法
EventThread::Connection::Connection(EventThread* eventThread)
// 創(chuàng)建BitTube
: count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}
BitTube::BitTube(size_t bufsize) {
// 創(chuàng)建socket pair,用于發(fā)送顯示事件
init(bufsize, bufsize);
}
void BitTube::init(size_t rcvbuf, size_t sndbuf) {
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
size_t size = DEFAULT_SOCKET_BUFFER_SIZE;
// 設(shè)置socket buffer
setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
// since we don't use the "return channel", we keep it small...
setsockopt(sockets[0], 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);
// socket[0]用于接收端茁影,最終通過Binder IPC返回給客戶端應(yīng)用
mReceiveFd.reset(sockets[0]);
// socket[1]用于發(fā)送端
mSendFd.reset(sockets[1]);
} else {
mReceiveFd.reset();
ALOGE("BitTube: pipe creation failed (%s)", strerror(errno));
}
}
BitTube
的作用主要有
- 封裝用于顯示事件的socket通信
- 跨進(jìn)程傳遞socket文件描述符
回到createEventConnection()
方法中宙帝,由于返回Connection
的強(qiáng)指針,在sp
的構(gòu)造函數(shù)中會增加強(qiáng)引用計數(shù)從而調(diào)用Connection
的onFirstRef()
方法募闲。
void EventThread::Connection::onFirstRef() {
// NOTE: mEventThread doesn't hold a strong reference on us
// 向EventThread注冊連接
mEventThread->registerDisplayEventConnection(this);
}
status_t EventThread::registerDisplayEventConnection(
const sp<EventThread::Connection>& connection) {
std::lock_guard<std::mutex> lock(mMutex);
// Connection添加到mDisplayEventConnections中
mDisplayEventConnections.add(connection);
mCondition.notify_all();
return NO_ERROR;
}
Connection
與EventThread
采用觀察者模式步脓,當(dāng)有顯示事件發(fā)生時,EventThread
向Connection
傳遞事件浩螺。至此靴患,createDisplayEventConnection()
的實現(xiàn)就分析完了,下面看stealReceiveChannel()
的實現(xiàn)
status_t stealReceiveChannel(gui::BitTube* outChannel) override {
// callRemote是一個模板方法年扩,用于實現(xiàn)同步Binder IPC
return callRemote<decltype(
&IDisplayEventConnection::stealReceiveChannel)>(Tag::STEAL_RECEIVE_CHANNEL,
outChannel);
}
下面看Connection
處理STEAL_RECEIVE_CHANNEL
請求
status_t BnDisplayEventConnection::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) {
if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
return BBinder::onTransact(code, data, reply, flags);
}
auto tag = static_cast<Tag>(code);
switch (tag) {
case Tag::STEAL_RECEIVE_CHANNEL:
// 調(diào)用stealReceiveChannel處理請求
// 最終通過BitTube(outChannel)的writeToParcel將socket接收端文件描述符寫入reply
return callLocal(data, reply, &IDisplayEventConnection::stealReceiveChannel);
......
}
}
status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {
// 設(shè)置socket接收端文件描述符
outChannel->setReceiveFd(mChannel.moveReceiveFd());
return NO_ERROR;
}
最終蚁廓,客戶端應(yīng)用通過BitTube
的readFromParcel()
獲取來自SurfaceFlinger的socket文件描述符。這樣客戶端就可以接收SurfaceFlinger發(fā)送的顯示事件了厨幻∠嗲叮回到nativeInit()
中,繼續(xù)看監(jiān)聽socket接收端文件描述符的過程况脆。
status_t DisplayEventDispatcher::initialize() {
status_t result = mReceiver.initCheck();
if (result) {
ALOGW("Failed to initialize display event receiver, status=%d", result);
return result;
}
// Looper監(jiān)聽socket文件描述符
int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,
this, NULL);
if (rc < 0) {
return UNKNOWN_ERROR;
}
return OK;
}
DisplayEventDispatcher
繼承自LooperCallback
饭宾,當(dāng)有顯示事件到來時,Looper關(guān)聯(lián)的線程將調(diào)用DisplayEventDispatcher
的handleEvent()
處理事件格了。這樣Android應(yīng)用與SurfaceFlinger就建立了連接看铆,可以接收SurfaceFlinger發(fā)送的顯示事件了。
為了后續(xù)分析盛末,下面繼續(xù)分析ViewRootImpl
的setView()
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView {
synchronized (this) {
if (mView == null) {
mView = view;
mAttachInfo.mDisplayState = mDisplay.getState();
mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
mViewLayoutDirectionInitial = mView.getRawLayoutDirection();
mFallbackEventHandler.setView(view);
mWindowAttributes.copyFrom(attrs);
if (mWindowAttributes.packageName == null) {
mWindowAttributes.packageName = mBasePackageName;
}
attrs = mWindowAttributes;
setTag();
......
// If the application owns the surface, don't enable hardware acceleration
// 如果應(yīng)用有自己的Surface弹惦,不使能硬件加速
if (mSurfaceHolder == null) {
// While this is supposed to enable only, it can effectively disable
// the acceleration too.
// 使能硬件加速否淤,也可以禁止
enableHardwareAcceleration(attrs);
final boolean useMTRenderer = MT_RENDERER_AVAILABLE
&& mAttachInfo.mThreadedRenderer != null;
if (mUseMTRenderer != useMTRenderer) {
// Shouldn't be resizing, as it's done only in window setup,
// but end just in case.
endDragResizing();
mUseMTRenderer = useMTRenderer;
}
}
......
// Schedule the first layout -before- adding to the window
// manager, to make sure we do the relayout before receiving
// any other events from the system.
// 調(diào)度首次layout, 請求SurfaceFlinger發(fā)送Vsync
requestLayout();
......
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
// 窗口注冊到WindowManagerService
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
} catch (RemoteException e) {
mAdded = false;
mView = null;
mAttachInfo.mRootView = null;
mInputChannel = null;
mFallbackEventHandler.setView(null);
unscheduleTraversals();
setAccessibilityFocus(null, null);
throw new RuntimeException("Adding window failed", e);
} finally {
if (restore) {
attrs.restore();
}
}
......
}
}
}
下面重點分析上述方法中的以下三個過程
- 使能硬件加速的過程
- 調(diào)度首次layout的過程
- 窗口注冊到WindowManagerService的過程
使能硬件加速的過程
下面從enableHardwareAcceleration()
開始分析棠隐。
private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
mAttachInfo.mHardwareAccelerated = false;
mAttachInfo.mHardwareAccelerationRequested = false;
// Don't enable hardware acceleration when the application is in compatibility mode
if (mTranslator != null) return;
// Try to enable hardware acceleration if requested
// 默認(rèn)hardwareAccelerated為true
// 在低端設(shè)備上隐解,Persistent進(jìn)程(包括system進(jìn)程)不應(yīng)該使用hardwareAccelerated岩臣,因為hardwareAccelerated消耗更多的資源叼耙,比如內(nèi)存
final boolean hardwareAccelerated =
(attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
if (hardwareAccelerated) {
if (!ThreadedRenderer.isAvailable()) {
return;
}
......
// 對于startingWindow端铛,設(shè)置窗口的FLAG_HARDWARE_ACCELERATED及PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED使得繪制與應(yīng)用窗口繪制相似(并非真正的hardwareAccelerated)
final boolean fakeHwAccelerated = (attrs.privateFlags &
WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED) != 0;
// 用于在system進(jìn)程中骨稿,某些UI繪制強(qiáng)制使用hardwareAccelerated
final boolean forceHwAccelerated = (attrs.privateFlags &
WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED) != 0;
if (fakeHwAccelerated) {
// This is exclusively for the preview windows the window manager
// shows for launching applications, so they will look more like
// the app being launched.
mAttachInfo.mHardwareAccelerationRequested = true;
} else if (!ThreadedRenderer.sRendererDisabled
|| (ThreadedRenderer.sSystemRendererDisabled && forceHwAccelerated)) {
// 使能硬件加速
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mThreadedRenderer.destroy();
}
final Rect insets = attrs.surfaceInsets;
final boolean hasSurfaceInsets = insets.left != 0 || insets.right != 0
|| insets.top != 0 || insets.bottom != 0;
// 是否透明
final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
final boolean wideGamut =
mContext.getResources().getConfiguration().isScreenWideColorGamut()
&& attrs.getColorMode() == ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT;
// 創(chuàng)建ThreadedRenderer
mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
attrs.getTitle().toString());
mAttachInfo.mThreadedRenderer.setWideGamut(wideGamut);
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mHardwareAccelerated =
mAttachInfo.mHardwareAccelerationRequested = true;
}
}
}
}
- ThreaderedRenderer用于將渲染工作委托給RenderThread
下面看ThreaderedRenderer
的create()
方法
public static ThreadedRenderer create(Context context, boolean translucent, Stringname) {
ThreadedRenderer renderer = null;
if (isAvailable()) {
// 檢查是否支持Threaded rendering
// 舊版本的模擬器可能不支持
renderer = new ThreadedRenderer(context, translucent, name);
}
return renderer;
}
ThreadedRenderer(Context context, boolean translucent, String name) {
final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
mAmbientShadowAlpha =
(int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
a.recycle();
// 創(chuàng)建Native RootRenderNode對象丑慎,rootNodePtr為對象的地址
long rootNodePtr = nCreateRootRenderNode();
// 產(chǎn)生一個Java RenderNode關(guān)聯(lián)Native RenderNode
mRootNode = RenderNode.adopt(rootNodePtr);
mRootNode.setClipToBounds(false);
mIsOpaque = !translucent;
// 創(chuàng)建RenderProxy及RenderThread
mNativeProxy = nCreateProxy(translucent, rootNodePtr);
nSetName(mNativeProxy, name);
// 1) 設(shè)置RenderThread的調(diào)度信息
// 2) 請求系統(tǒng)GraphicsStatsService創(chuàng)建匿名共享內(nèi)存弧烤,用于存儲應(yīng)用渲染信息(dumpsys gfxinfo)
ProcessInitializer.sInstance.init(context, mNativeProxy);
// 加載渲染所需的系統(tǒng)屬性
loadSystemProperties();
}
- RenderNode
- 存儲記錄的畫布命令熊榛,以及View/ViewGroup的顯示屬性
- RenderProxy
- 創(chuàng)建以及管理RenderThread中的CanvasContext
- RenderThread
- 真正的渲染線程
下面首先看RootRenderNode的創(chuàng)建疯攒,然后分析RenderProxy及RenderThread会喝。
- 真正的渲染線程
static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) {
// 創(chuàng)建RootRenderNode
RootRenderNode* node = new RootRenderNode(env);
node->incStrong(0);
node->setName("RootRenderNode");
return reinterpret_cast<jlong>(node);
}
explicit RootRenderNode(JNIEnv* env) : RenderNode() {
// 獲取調(diào)用線程關(guān)聯(lián)的Looper
mLooper = Looper::getForThread();
LOG_ALWAYS_FATAL_IF(!mLooper.get(),
"Must create RootRenderNode on a thread with a looper!");
// 返回JavaVM
env->GetJavaVM(&mVm);
}
這里只是簡單的創(chuàng)建RootRenderNode末秃,下面看RenderProxy及RenderThread的創(chuàng)建概页。
static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,
jboolean translucent, jlong rootRenderNodePtr) {
RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr);
// 創(chuàng)建ContextFactoryImpl
ContextFactoryImpl factory(rootRenderNode);
// 創(chuàng)建RenderProxy
return (jlong) new RenderProxy(translucent, rootRenderNode, &factory);
}
RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode,
IContextFactory* contextFactory)
// 創(chuàng)建啟動RenderThread線程
: mRenderThread(RenderThread::getInstance()), mContext(nullptr) {
// 匿名函數(shù)創(chuàng)建CanvasContext
mContext = mRenderThread.queue().runSync([&]() -> CanvasContext* {
return CanvasContext::create(mRenderThread, translucent, rootRenderNode, contextFactory);
});
設(shè)置DrawFrameTask關(guān)聯(lián)的RenderThread、CanvasContext练慕、RootRenderNode
mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode);
}
RenderThread& RenderThread::getInstance() {
// This is a pointer because otherwise __cxa_finalize
// will try to delete it like a Good Citizen but that causes us to crash
// because we don't want to delete the RenderThread normally.
static RenderThread* sInstance = new RenderThread();
gHasRenderThreadInstance = true;
return *sInstance;
}
RenderThread::RenderThread()
: ThreadBase()
, mVsyncSource(nullptr)
, mVsyncRequested(false)
, mFrameCallbackTaskPending(false)
, mRenderState(nullptr)
, mEglManager(nullptr)
, mVkManager(nullptr) {
Properties::load();
// 啟動線程惰匙,最終執(zhí)行RenderThread的threadLoop方法
start("RenderThread");
}
bool RenderThread::threadLoop() {
// 設(shè)置RenderThread的優(yōu)先級
setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY);
if (gOnStartHook) {
gOnStartHook();
}
// 與SurfaceFlinger建立連接
// 設(shè)置EglManager、RenderState铃将、VulkanManager等
initThreadLocals();
while (true) {
// 等待工作
waitForWork();
// 處理工作項
processQueue();
if (mPendingRegistrationFrameCallbacks.size() && !mFrameCallbackTaskPending) {
drainDisplayEventQueue();
mFrameCallbacks.insert(mPendingRegistrationFrameCallbacks.begin(),
mPendingRegistrationFrameCallbacks.end());
mPendingRegistrationFrameCallbacks.clear();
requestVsync();
}
if (!mFrameCallbackTaskPending && !mVsyncRequested && mFrameCallbacks.size()) {
// TODO: Clean this up. This is working around an issue where a combination
// of bad timing and slow drawing can result in dropping a stale vsync
// on the floor (correct!) but fails to schedule to listen for the
// next vsync (oops), so none of the callbacks are run.
requestVsync();
}
}
return false;
}
RenderThread啟動后项鬼,RenderProxy向RenderThread發(fā)送創(chuàng)建CanvasContext
的同步請求。下面看CanvasContext
的創(chuàng)建劲阎。
CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent,
RenderNode* rootRenderNode, IContextFactory* contextFactory) {
// 獲取RenderPipeline類型绘盟,默認(rèn)是SkiaGL
auto renderType = Properties::getRenderPipelineType();
switch (renderType) {
case RenderPipelineType::OpenGL:
return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
std::make_unique<OpenGLPipeline>(thread));
case RenderPipelineType::SkiaGL:
// 根據(jù)renderType創(chuàng)建CanvasContext
return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
std::make_unique<skiapipeline::SkiaOpenGLPipeline>(thread));
case RenderPipelineType::SkiaVulkan:
return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
std::make_unique<skiapipeline::SkiaVulkanPipeline>(thread));
default:
LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
break;
}
return nullptr;
}
調(diào)度首次layout的過程
下面從requestLayout()
開始分析。
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
// 向Looper關(guān)聯(lián)的消息隊列中投遞SyncBarrier
// 下一次執(zhí)行performTraversal時移除SyncBarrier
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
// 添加CALLBACK_TRAVERSAL回調(diào),當(dāng)下一幀(Vsync)到來時執(zhí)行繪制
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
// 通知ThreadedRenderer下一幀很快到來
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
關(guān)于synchronization barrier(target為null的特殊消息), 一般的龄毡,消息隊列中的消息為同步消息吠卷,按照時間先后進(jìn)行處理。當(dāng)synchronization barrier進(jìn)入消息隊列中稚虎,隊列中的同步消息被掛起(異步消息可以處理)撤嫩,直到synchronization barrier從消息隊列中移除。盡管postAtFrontOfQueue()可以使同步消息不被掛起蠢终,請不要濫用。
下面看Choreographer
的postCallback()
的實現(xiàn)茴她。
public void postCallback(int callbackType, Runnable action, Object token) {
postCallbackDelayed(callbackType, action, token, 0);
}
public void postCallbackDelayed(int callbackType,
Runnable action, Object token, long delayMillis) {
......
postCallbackDelayedInternal(callbackType, action, token, delayMillis);
}
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {
......
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
// 添加到CALLBACK_TRAVERSAL類型的CallbackQueue中
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
if (dueTime <= now) {
// 請求Vsync信號
scheduleFrameLocked(now);
} else {
......
}
}
}
下面看scheduleFrameLocked()
的實現(xiàn)
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
if (USE_VSYNC) {
if (DEBUG_FRAMES) {
Log.d(TAG, "Scheduling next frame on vsync.");
}
// If running on the Looper thread, then schedule the vsync immediately,
// otherwise post a message to schedule the vsync from the UI thread
// as soon as possible.
if (isRunningOnLooperThreadLocked()) {
// 立即請求Vsync
scheduleVsyncLocked();
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
......
}
}
}
private void scheduleVsyncLocked() {
// 調(diào)用FrameDisplayEventReceiver的scheduleVsync()
mDisplayEventReceiver.scheduleVsync();
}
public void scheduleVsync() {
if (mReceiverPtr == 0) {
Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event "
+ "receiver has already been disposed.");
} else {
// 當(dāng)下一幀到來時請求SurfaceFlinger發(fā)送Vsync
nativeScheduleVsync(mReceiverPtr);
}
}
static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
sp<NativeDisplayEventReceiver> receiver =
reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
// 調(diào)用NativeDisplayEventReceiver的scheduleVsync()
status_t status = receiver->scheduleVsync();
......
}
NativeDisplayEventReceiver
繼承自DisplayEventDispatcher
寻拂,下面scheduleVsync()
的實現(xiàn)
status_t DisplayEventDispatcher::scheduleVsync() {
if (!mWaitingForVsync) {
ALOGV("dispatcher %p ~ Scheduling vsync.", this);
// Drain all pending events.
nsecs_t vsyncTimestamp;
int32_t vsyncDisplayId;
uint32_t vsyncCount;
// 如果有待處理的事件(Vsync/Hotplug),丟棄
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "",
this, ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));
}
// 調(diào)用DisplayEventReceiver的requestNextVsync()丈牢,請求SurfaceFlinger發(fā)送Vsync
status_t status = mReceiver.requestNextVsync();
if (status) {
ALOGW("Failed to request next vsync, status=%d", status);
return status;
}
mWaitingForVsync = true;
}
return OK;
}
status_t DisplayEventReceiver::requestNextVsync() {
if (mEventConnection != NULL) {
// mEventConnection是BpDisplayEventConnection的強(qiáng)指針
mEventConnection->requestNextVsync();
return NO_ERROR;
}
return NO_INIT;
}
requestNextVsync()
是一個異步Binder IPC祭钉,它的實現(xiàn)在IDisplayEventConnection中,下面直接看Binder服務(wù)端Connection
處理REQUEST_NEXT_VSYNC
請求己沛。
void EventThread::Connection::requestNextVsync() {
// 調(diào)用EventThread的requestNextVsync處理客戶端Vsync請求
mEventThread->requestNextVsync(this);
}
void EventThread::requestNextVsync(const sp<EventThread::Connection>& connection) {
std::lock_guard<std::mutex> lock(mMutex);
......
// 修改連接狀態(tài)
if (connection->count < 0) {
connection->count = 0;
mCondition.notify_all();
}
}
客戶端請求Vsync的過程相對簡單慌核,主要是修改Connection
的狀態(tài)。當(dāng)EventThread收到Vsync時申尼,根據(jù)Connection
的狀態(tài)決定是否向Connection
發(fā)送Vsync垮卓。
使用dumpsys SurfaceFlinger命令可以查看所有Connection的狀態(tài)
****chn:/ $ dumpsys SurfaceFlinger
......
VSYNC state: enabled
soft-vsync: disabled
numListeners=43,
events-delivered: 11406
0x7b3a052300: count=-1
0x7b3a052360: count=-1
0x7b3a0523c0: count=-1
0x7b3a052420: count=-1
0x7b3a0524e0: count=-1
0x7b3a052960: count=-1
0x7b3a0529c0: count=-1
......
0x7b3abfe200: count=1
......
其中,numListeners表示連接數(shù)量师幕,count的值表示狀態(tài)
- count >= 1
- 連續(xù)的Vsync請求
- count = 0
- 單次Vsync請求(還沒有收到Vsync)
- count = -1
- 單次Vsync請求(已經(jīng)收到Vsync)或者不請求Vsync
窗口注冊到WindowManagerService的過程
下面從addToDisplay()
開始分析粟按,addToDisplay()
是一個Binder IPC,對應(yīng)的服務(wù)端的實現(xiàn)在Session
中霹粥。
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets,
Rect outStableInsets, Rect outOutsets,
DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
// 調(diào)用WindowManagerService的addWindow
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,
outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel);
}
public int addWindow(Session session, IWindow client, int seq,
LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
// client為IWindow.Stub.Proxy對象
......
boolean reportNewConfig = false;
WindowState parentWindow = null;
long origId;
final int callingUid = Binder.getCallingUid();
final int type = attrs.type;
synchronized(mWindowMap) {
if (!mDisplayReady) {
throw new IllegalStateException("Display has not been initialialized");
}
// DisplayContent用于記錄特定屏幕的WindowStates以及相關(guān)的內(nèi)容
final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
......
// 檢查應(yīng)用是否有權(quán)限向特定屏幕添加窗口
if (!displayContent.hasAccess(session.mUid)
&& !mDisplayManagerInternal.isUidPresentOnDisplay(session.mUid, displayId)) {
Slog.w(TAG_WM, "Attempted to add window to a display for which the application "
+ "does not have access: " + displayId + ". Aborting.");
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
}
......
// 檢查窗口是否已經(jīng)添加
// mWindowMap為IWindow IBinder(BinderProxy)到WindowState的映射
if (mWindowMap.containsKey(client.asBinder())) {
Slog.w(TAG_WM, "Window " + client + " is already added");
return WindowManagerGlobal.ADD_DUPLICATE_ADD;
}
......
AppWindowToken atoken = null;
final boolean hasParent = parentWindow != null;
// Use existing parent window token for child windows since they go in the same token
// as there parent window so we can apply the same policy on them.
// 對于Activity窗口灭将,根據(jù)token(IApplicationToken.Stub)查找對應(yīng)的AppWindowToken
// AppWindowToken是在之前Activity啟動時創(chuàng)建
WindowToken token = displayContent.getWindowToken(
hasParent ? parentWindow.mAttrs.token : attrs.token);
// If this is a child window, we want to apply the same type checking rules as the
// parent window type.
final int rootType = hasParent ? parentWindow.mAttrs.type : type;
boolean addToastWindowRequiresToken = false;
......
// 創(chuàng)建WindowState用于描述一個窗口
final WindowState win = new WindowState(this, session, client, token, parentWindow,
appOp[0], seq, attrs, viewVisibility, session.mUid,
session.mCanAddInternalSystemWindow);
......
// 根據(jù)窗口類型調(diào)整布局參數(shù)
mPolicy.adjustWindowParamsLw(win, win.mAttrs, hasStatusBarServicePermission);
win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
// 窗口添加到系統(tǒng)前的檢查
res = mPolicy.prepareAddWindowLw(win, attrs);
......
// 創(chuàng)建SurfaceSession,添加Session到WindowManagerService
win.attach();
// WindowState添加到mWindowMap
mWindowMap.put(client.asBinder(), win);
win.initAppOpsState();
......
// 窗口WindowState添加到系統(tǒng)
win.mToken.addWindow(win);
......
// 這里WindowState的Parent為AppWindowToken
win.getParent().assignChildLayers();
}
}
下面重點分析WindowState
的attach()
方法
void attach() {
if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
// 調(diào)用Session的windowAddedLocked
mSession.windowAddedLocked(mAttrs.packageName);
}
void windowAddedLocked(String packageName) {
mPackageName = packageName;
mRelayoutTag = "relayoutWindow: " + mPackageName;
if (mSurfaceSession == null) {
if (WindowManagerService.localLOGV) Slog.v(
TAG_WM, "First window added to " + this + ", creating SurfaceSession");
// SurfaceSession代表一個到SurfaceFlinger的連接
// 可以有一個或多個參與合成的Surface
mSurfaceSession = new SurfaceSession();
if (SHOW_TRANSACTIONS) Slog.i(
TAG_WM, " NEW SURFACE SESSION " + mSurfaceSession);
// Session添加到WindowManagerService的mSessions中
mService.mSessions.add(this);
if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
mService.dispatchNewAnimatorScaleLocked(this);
}
}
mNumWindow++;
}
下面看SurfaceSession
的構(gòu)造方法。
public SurfaceSession() {
mNativeClient = nativeCreate();
}
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
// 創(chuàng)建SurfaceComposerClient
SurfaceComposerClient* client = new SurfaceComposerClient();
// SurfaceComposerClient繼承自RefBase,增加強(qiáng)引用計數(shù)后控,會調(diào)用onFirstRef
client->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(client);
}
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != 0 && mStatus == NO_INIT) {
// 這里rootProducer為nullptr
auto rootProducer = mParent.promote();
sp<ISurfaceComposerClient> conn;
// 請求SurfaceFlinger為客戶端創(chuàng)建連接
// conn為BpSurfaceComposerClient對象的智能指針
conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
sf->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
createConnection()
是一個Binder IPC庙曙,下面直接看SurfaceFlinger處理CREATE_CONNECTION
請求。
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
return initClient(new Client(this));
}
Client
為參與合成的客戶端在SurfaceFlinger
側(cè)的代表浩淘,是一個Binder服務(wù)對象,通過Binder IPC傳遞后捌朴,在客戶端得到BpSurfaceComposerClient
對象。