本文主要是介绍Android—Surface,ViewRootImpl.relayoutWindow,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
绘制UI会从ViewRootImpl会调用performTraversals方法开始,然后performLayout、performMeasure、performDraw。
我们跟进performDraw->draw->drawSoftware
/*** @return true if drawing was successful, false if an error occurred*/private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,boolean scalingRequired, Rect dirty, Rect surfaceInsets) {// Draw with software renderer.final Canvas canvas;// We already have the offset of surfaceInsets in xoff, yoff and dirty region,// therefore we need to add it back when moving the dirty region.int dirtyXOffset = xoff;int dirtyYOffset = yoff;if (surfaceInsets != null) {dirtyXOffset += surfaceInsets.left;dirtyYOffset += surfaceInsets.top;}try {dirty.offset(-dirtyXOffset, -dirtyYOffset);final int left = dirty.left;final int top = dirty.top;final int right = dirty.right;final int bottom = dirty.bottom;canvas = mSurface.lockCanvas(dirty);// TODO: Do this in nativecanvas.setDensity(mDensity);} catch (Surface.OutOfResourcesException e) {handleOutOfResourcesException(e);return false;} catch (IllegalArgumentException e) {Log.e(mTag, "Could not lock surface", e);// Don't assume this is due to out of memory, it could be// something else, and if it is something else then we could// kill stuff (or ourself) for no reason.mLayoutRequested = true; // ask wm for a new surface next time.return false;} finally {dirty.offset(dirtyXOffset, dirtyYOffset); // Reset to the original value.}try {if (DEBUG_ORIENTATION || DEBUG_DRAW) {Log.v(mTag, "Surface " + surface + " drawing to bitmap w="+ canvas.getWidth() + ", h=" + canvas.getHeight());//canvas.drawARGB(255, 255, 0, 0);}// If this bitmap's format includes an alpha channel, we// need to clear it before drawing so that the child will// properly re-composite its drawing on a transparent// background. This automatically respects the clip/dirty region// or// If we are applying an offset, we need to clear the area// where the offset doesn't appear to avoid having garbage// left in the blank areas.if (!canvas.isOpaque() || yoff != 0 || xoff != 0) {canvas.drawColor(0, PorterDuff.Mode.CLEAR);}dirty.setEmpty();mIsAnimating = false;mView.mPrivateFlags |= View.PFLAG_DRAWN;if (DEBUG_DRAW) {Context cxt = mView.getContext();Log.i(mTag, "Drawing: package:" + cxt.getPackageName() +", metrics=" + cxt.getResources().getDisplayMetrics() +", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());}canvas.translate(-xoff, -yoff);if (mTranslator != null) {mTranslator.translateCanvas(canvas);}canvas.setScreenDensity(scalingRequired ? mNoncompatDensity : 0);mView.draw(canvas);drawAccessibilityFocusedDrawableIfNeeded(canvas);} finally {try {surface.unlockCanvasAndPost(canvas);} catch (IllegalArgumentException e) {Log.e(mTag, "Could not unlock surface", e);mLayoutRequested = true; // ask wm for a new surface next time.//noinspection ReturnInsideFinallyBlockreturn false;}if (LOCAL_LOGV) {Log.v(mTag, "Surface " + surface + " unlockCanvasAndPost");}}return true;}
调用了mView.draw(canvas);
@CallSuperpublic void draw(Canvas canvas) {final int privateFlags = mPrivateFlags;mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;/** Draw traversal performs several drawing steps which must be executed* in the appropriate order:** 1. Draw the background* 2. If necessary, save the canvas' layers to prepare for fading* 3. Draw view's content* 4. Draw children* 5. If necessary, draw the fading edges and restore layers* 6. Draw decorations (scrollbars for instance)*/// Step 1, draw the background, if neededint saveCount;drawBackground(canvas);// skip step 2 & 5 if possible (common case)final int viewFlags = mViewFlags;boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;if (!verticalEdges && !horizontalEdges) {// Step 3, draw the contentonDraw(canvas);// Step 4, draw the childrendispatchDraw(canvas);drawAutofilledHighlight(canvas);// Overlay is part of the content and draws beneath Foregroundif (mOverlay != null && !mOverlay.isEmpty()) {mOverlay.getOverlayView().dispatchDraw(canvas);}// Step 6, draw decorations (foreground, scrollbars)onDrawForeground(canvas);// Step 7, draw the default focus highlightdrawDefaultFocusHighlight(canvas);if (debugDraw()) {debugDrawFocus(canvas);}// we're done...return;}
可以看到mView.draw(canvas)就是具体的draw实体了,所有的视图都是作用在这个画布上。那么canvas是哪里来的呢?
回到上面可以看到
canvas = mSurface.lockCanvas(dirty);
在ViewRoot构造时,会创建一个Surface,它使用无参构造函数,这时候他还只是空的实体,代码如下所示:
private final Surface mSurface = new Surface();
在performTraversals方法中,有四个重要的方法:
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
performLayout(lp, mWidth, mHeight);
performDraw();
我们知道performMeasure、performLayout、performDraw就是去测量视图宽高,布局,绘制。
这里主要分析relayoutWindow方法:
frameworks\base\core\java\android\view\ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,boolean insetsPending) throws RemoteException {.....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, frameNumber,mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,mPendingMergedConfiguration, mSurfaceControl, mTempInsets);if (mSurfaceControl.isValid()) {mSurface.copyFrom(mSurfaceControl);} else {destroySurface();}....}
- mWindowSession.relayout(...);
- mSurface.copyFrom(mSurfaceControl);
我们先看mSurface.copyFrom(mSurfaceControl);
frameworks\base\core\java\android\view\Surface.java
public void copyFrom(SurfaceControl other) {....long surfaceControlPtr = other.mNativeObject;long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);....}
frameworks\base\core\jni\android_view_Surface.cpp
static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,jlong nativeObject,jlong surfaceControlNativeObj) {Surface* self(reinterpret_cast<Surface *>(nativeObject));sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));// If the underlying IGBP's are the same, we don't need to do anything.if (self != nullptr &&IInterface::asBinder(self->getIGraphicBufferProducer()) ==IInterface::asBinder(ctrl->getIGraphicBufferProducer())) {return nativeObject;}sp<Surface> surface(ctrl->getSurface());if (surface != NULL) {surface->incStrong(&sRefBaseOwner);}return reinterpret_cast<jlong>(surface.get());
}
frameworks\native\libs\gui\SurfaceControl.cpp
sp<Surface> SurfaceControl::getSurface() const
{Mutex::Autolock _l(mLock);if (mSurfaceData == nullptr) {return generateSurfaceLocked();}return mSurfaceData;
}sp<Surface> SurfaceControl::generateSurfaceLocked() const
{// This surface is always consumed by SurfaceFlinger, so the// producerControlledByApp value doesn't matter; using false.mSurfaceData = new Surface(mGraphicBufferProducer, false);return mSurfaceData;
}
Surface.copyFrom方法可以简单理解为从SurfaceControl对象中获取Surface。
接着分析mWindowSession.relayout(...);
先找一下mWindowSession是哪里初始化的:
IWindowSession mWindowSession = WindowManagerGlobal.getWindowSession();
frameworks\base\core\java\android\view\WindowManagerGlobal.java
public static IWindowSession getWindowSession() {synchronized (WindowManagerGlobal.class) {if (sWindowSession == null) {try {// Emulate the legacy behavior. The global instance of InputMethodManager// was instantiated here.// TODO(b/116157766): Remove this hack after cleaning up @UnsupportedAppUsageInputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary();IWindowManager windowManager = getWindowManagerService();sWindowSession = windowManager.openSession(new IWindowSessionCallback.Stub() {@Overridepublic void onAnimatorScaleChanged(float scale) {ValueAnimator.setDurationScale(scale);}});} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}return sWindowSession;}}public static IWindowManager getWindowManagerService() {synchronized (WindowManagerGlobal.class) {if (sWindowManagerService == null) {sWindowManagerService = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));try {if (sWindowManagerService != null) {ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());}} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}return sWindowManagerService;}}
mWindowSession = WindowManagerGlobal.getWindowSession();中先获取了WMS,然后调用WMS的openSession获取的mWindowSession对象
frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java
@Overridepublic IWindowSession openSession(IWindowSessionCallback callback) {return new Session(this, callback);}
所以mWindowSession是一个Session对象。
从这里我们可以知道ViewRootImpl是通过Session对象来与WMS进行通信的。
知道了他具体是什么对象,我们就能够分析他的relayout了
frameworks\base\services\core\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, long frameNumber,Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets,Rect outStableInsets, Rect outsets, Rect outBackdropFrame,DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,SurfaceControl outSurfaceControl, InsetsState outInsetsState) {int res = mService.relayoutWindow(this, window, seq, attrs,requestedWidth, requestedHeight, viewFlags, flags, frameNumber,outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,outStableInsets, outsets, outBackdropFrame, cutout,mergedConfiguration, outSurfaceControl, outInsetsState);return res;}
这里的mService是WMS。
frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java
public int relayoutWindow(Session session, IWindow client,....) {....synchronized (mGlobalLock) {....if (shouldRelayout) {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");result = win.relayoutVisibleWindow(result, attrChanges);try {result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);} catch (Exception e) {....}} else {....}....return result;}private int createSurfaceControl(SurfaceControl outSurfaceControl, int result, WindowState win,WindowStateAnimator winAnimator) {if (!win.mHasSurface) {result |= RELAYOUT_RES_SURFACE_CHANGED;}WindowSurfaceController surfaceController;try {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}if (surfaceController != null) {surfaceController.getSurfaceControl(outSurfaceControl);if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurfaceControl + ": copied");} else {// For some reason there isn't a surface. Clear the// caller's object so they see the same state.Slog.w(TAG_WM, "Failed to create surface control for " + win);outSurfaceControl.release();}return result;}
- surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
- surfaceController.getSurfaceControl(outSurfaceControl);
我们先看surfaceController.getSurfaceControl(outSurfaceControl);
frameworks\base\services\core\java\com\android\server\wm\WindowSurfaceController.java
void getSurfaceControl(SurfaceControl outSurfaceControl) {outSurfaceControl.copyFrom(mSurfaceControl);}
outSurfaceControl就是复制mSurfaceControl的值,而mSurfaceControl就是在上一步创建的。
先创建了surfaceController,然后再调surfaceController的getSurfaceControl给outSurfaceControl赋值。
接下来只要分析surfaceController是怎么生成的,就能够知道
ViewRootImpl的relayoutWindow方法中,mSurface.copyFrom(mSurfaceControl)的mSurfaceControl是哪个,就知道了mSurface是从哪来的。
frameworks\base\services\core\java\com\android\server\wm\WindowStateAnimator.java
WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {final WindowState w = mWin;...mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,attrs.getTitle().toString(), width, height, format, flags, this,windowType, ownerUid);mSurfaceController.setColorSpaceAgnostic((attrs.privateFlags& WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);setOffsetPositionForStackResize(false);mSurfaceFormat = format;w.setHasSurface(true);....return mSurfaceController;}
frameworks\base\services\core\java\com\android\server\wm\WindowSurfaceController.java
public WindowSurfaceController(SurfaceSession s, String name, int w, int h, int format,int flags, WindowStateAnimator animator, int windowType, int ownerUid) {mAnimator = animator;mSurfaceW = w;mSurfaceH = h;title = name;mService = animator.mService;final WindowState win = animator.mWin;mWindowType = windowType;mWindowSession = win.mSession;Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");final SurfaceControl.Builder b = win.makeSurface().setParent(win.getSurfaceControl()).setName(name).setBufferSize(w, h).setFormat(format).setFlags(flags).setMetadata(METADATA_WINDOW_TYPE, windowType).setMetadata(METADATA_OWNER_UID, ownerUid);mSurfaceControl = b.build();Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}
WindowSurfaceController的构造函数里面采用建造者模式创建了mSurfaceControl。
frameworks\base\core\java\android\view\SurfaceControl.java
public SurfaceControl build() {if (mWidth < 0 || mHeight < 0) {throw new IllegalStateException("width and height must be positive or unset");}if ((mWidth > 0 || mHeight > 0) && (isColorLayerSet() || isContainerLayerSet())) {throw new IllegalStateException("Only buffer layers can set a valid buffer size.");}return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata);}private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,SurfaceControl parent, SparseIntArray metadata)throws OutOfResourcesException, IllegalArgumentException {....mNativeObject = nativeCreate(session, name, w, h, format, flags,parent != null ? parent.mNativeObject : 0, metaParcel);....}
这里的nativeCreate是本地方法,继续跟下去
frameworks\base\core\jni\android_view_SurfaceControl.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,jobject metadataParcel) {ScopedUtfChars name(env, nameStr);sp<SurfaceComposerClient> client;if (sessionObj != NULL) {client = android_view_SurfaceSession_getClient(env, sessionObj);} else {client = SurfaceComposerClient::getDefault();}....sp<SurfaceControl> surface;status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface, flags, parent, std::move(metadata));if (err == NAME_NOT_FOUND) {jniThrowException(env, "java/lang/IllegalArgumentException", NULL);return 0;} else if (err != NO_ERROR) {jniThrowException(env, OutOfResourcesException, NULL);return 0;}surface->incStrong((void *)nativeCreate);return reinterpret_cast<jlong>(surface.get());
}
frameworks\native\libs\gui\SurfaceComposerClient.cpp
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,PixelFormat format,sp<SurfaceControl>* outSurface, uint32_t flags,SurfaceControl* parent,LayerMetadata metadata) {....err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),&handle, &gbp);ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));if (err == NO_ERROR) {*outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);}....return err;
}
- mClient->createSurface(....)
- *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */)
这个mClient是ISurfaceComposerClient对象,目前我们还不知道具体是什么,怎么来的,先放着后面分析。
所以在winAnimator.createSurfaceLocked中去new WindowSurfaceController对象,WindowSurfaceController对象的构造方法中会调用SurfaceControl的本地方法nativeCreate去本地创建一个SurfaceControl返回来。
回到ViewRootImpl的relayoutWindow
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,boolean insetsPending) throws RemoteException {.....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, frameNumber,mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,mPendingMergedConfiguration, mSurfaceControl, mTempInsets);if (mSurfaceControl.isValid()) {mSurface.copyFrom(mSurfaceControl);} else {destroySurface();}....}
所以mSurface来自于WindowSurfaceController构造函数中实例化的mSurfaceControl对象,mSurfaceControl对象来自nativeCreate创建的SurfaceControl。
所以在performTraversals中performMeasure、performLayout、performDraw之前,ViewRootImpl会先调用relayoutWindow去创建SurfaceControl,然后从SurfaceControl中获取Surface。但是在创建SurfaceControl之前,还调用了mClient->createSurface(....)。
Surface我们知道怎么来的了,还有个遗留问题就是mClient->createSurface(....)的mClinet是怎么来的。到setView方法
frameworks\base\core\java\android\view\ViewRootImpl.java:
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {synchronized (this) {if (mView == null) {....requestLayout();try {res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,getHostVisibility(), mDisplay.getDisplayId(), mTmpFrame,mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel,mTempInsets);setFrame(mTmpFrame);}....}}
requestLayout会去执行performTraversals
我们主要分析mWindowSession.addToDisplay
frameworks\base\services\core\java\com\android\server\wm\Session.java
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,InsetsState outInsetsState) {return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel,outInsetsState);}
frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java
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,InsetsState outInsetsState) {....synchronized (mGlobalLock) {....final WindowState win = new WindowState(this, session, client, token, parentWindow,appOp[0], seq, attrs, viewVisibility, session.mUid,session.mCanAddInternalSystemWindow);....win.attach();....} return res;}
addWindow方法内容很多,我们只看重点,这里创建了WindowState对象然后调用了attach方法。
frameworks\base\services\core\java\com\android\server\wm\WindowState.java
void attach() {mSession.windowAddedLocked(mAttrs.packageName);}
又回到了Session
frameworks\base\services\core\java\com\android\server\wm\Session.java
void windowAddedLocked(String packageName) {mPackageName = packageName;mRelayoutTag = "relayoutWindow: " + mPackageName;if (mSurfaceSession == null) {mSurfaceSession = new SurfaceSession();mService.mSessions.add(this);if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {mService.dispatchNewAnimatorScaleLocked(this);}}mNumWindow++;}
在Session里面创建了SurfaceSession,这里的Session是mWindowSession,用来和WMS通信的。现在又多了个SurfaceSession。
frameworks\base\core\java\android\view\SurfaceSession.java:
public SurfaceSession() {mNativeClient = nativeCreate();}
这里又有一个nativeCreate,我们前面见过在SufaceControl里
frameworks\base\core\java\android\view\SurfaceControl.java
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,SurfaceControl parent, SparseIntArray metadata)throws OutOfResourcesException, IllegalArgumentException {....mNativeObject = nativeCreate(session, name, w, h, format, flags,parent != null ? parent.mNativeObject : 0, metaParcel);....}
注意这两个不是同一个函数,我们找到SurfaceSession对应Native层的方法
frameworks\base\core\jni\android_view_SurfaceSession.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz) {SurfaceComposerClient* client = new SurfaceComposerClient();client->incStrong((void*)nativeCreate);return reinterpret_cast<jlong>(client);
}
SurfaceSession里面创建了SurfaceComposerClient,SurfaceComposerClient是一个重要的对象。
incStrong是RefBase的方法,里面会去调用onFirstRef
frameworks\native\libs\gui\SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {sp<ISurfaceComposer> sf(ComposerService::getComposerService());if (sf != nullptr && mStatus == NO_INIT) {sp<ISurfaceComposerClient> conn;conn = sf->createConnection();if (conn != nullptr) {mClient = conn;mStatus = NO_ERROR;}}
}
- ComposerService::getComposerService()
- mClient = conn = sf->createConnection()
sp<ISurfaceComposer> ComposerService::getComposerService() {ComposerService& instance = ComposerService::getInstance();Mutex::Autolock _l(instance.mLock);if (instance.mComposerService == NULL) {ComposerService::getInstance().connectLocked();assert(instance.mComposerService != NULL);ALOGD("ComposerService reconnected");}return instance.mComposerService;
}void ComposerService::connectLocked() {const String16 name("SurfaceFlinger");//按名称查找服务while (getService(name, &mComposerService) != NO_ERROR) {usleep(250000);}....
}template<typename INTERFACE>
status_t getService(const String16& name, sp<INTERFACE>* outService)
{const sp<IServiceManager> sm = defaultServiceManager();//服务管理者if (sm != NULL) {//获取SurfaceFlinger的IBinder,并强转为ISurfaceComposer*outService = interface_cast<INTERFACE>(sm->getService(name));if ((*outService) != NULL) return NO_ERROR;}return NAME_NOT_FOUND;
}
所以ComposerService::getComposerService()就是去获取名为SurfaceFlinger的服务,
这里获取到的是服务代理类是BpSurfaceComposer,为什么是BpSurfaceComposer呢?
class SurfaceFlinger : public BnSurfaceComposer
可以看到 SurfaceFlinger是BnSurfaceComposer的子类。
接下来看mClient = conn = sf->createConnection()
frameworks\native\libs\gui\ISurfaceComposer.cpp
virtual sp<ISurfaceComposerClient> createConnection(){Parcel data, reply;data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);//Binder远程调用return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());}
这里就是Binder通信了,传到BnSurfaceComposer再到SurfaceFlinger的具体方法。
我们直接看SurfaceFlinger的createConnection
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {return initClient(new Client(this));
}Client::Client(const sp<SurfaceFlinger>& flinger): mFlinger(flinger)
{
}static sp<ISurfaceComposerClient> initClient(const sp<Client>& client) {status_t err = client->initCheck();if (err == NO_ERROR) {return client;}return nullptr;
}
捋一下,所以SurfaceSession通过本地方法nativeCreate,创建了SurfaceComposerClient对象,SurfaceComposerClient在初始化onFirstRef的时候会通过SurfaceFlinger服务获取Client对象给自己的mClient复制。
回到之前SurfaceComposerClient类的createSurfaceChecked方法中的mClient->createSurface(....)
frameworks\native\libs\gui\SurfaceComposerClient.cpp
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,PixelFormat format,sp<SurfaceControl>* outSurface, uint32_t flags,SurfaceControl* parent,LayerMetadata metadata) {....err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),&handle, &gbp);ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));if (err == NO_ERROR) {*outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);}....return err;
}
发现这个mClient就是Client:BnSurfaceComposerClient对象。
接下来我们就能分析createSurface了
frameworks\native\services\surfaceflinger\Client.cpp
status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,uint32_t flags, const sp<IBinder>& parentHandle,LayerMetadata metadata, sp<IBinder>* handle,sp<IGraphicBufferProducer>* gbp) {// We rely on createLayer to check permissions.return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,parentHandle);
}
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,uint32_t h, PixelFormat format, uint32_t flags,LayerMetadata metadata, sp<IBinder>* handle,sp<IGraphicBufferProducer>* gbp,const sp<IBinder>& parentHandle,const sp<Layer>& parentLayer) {....switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {case ISurfaceComposerClient::eFXSurfaceBufferQueue:result = createBufferQueueLayer(client, uniqueName, w, h, flags, std::move(metadata),format, handle, gbp, &layer);break;case ISurfaceComposerClient::eFXSurfaceBufferState:result = createBufferStateLayer(client, uniqueName, w, h, flags, std::move(metadata),handle, &layer);break;case ISurfaceComposerClient::eFXSurfaceColor:// check if buffer size is set for color layer.if (w > 0 || h > 0) {ALOGE("createLayer() failed, w or h cannot be set for color layer (w=%d, h=%d)",int(w), int(h));return BAD_VALUE;}result = createColorLayer(client, uniqueName, w, h, flags, std::move(metadata), handle,&layer);break;case ISurfaceComposerClient::eFXSurfaceContainer:// check if buffer size is set for container layer.if (w > 0 || h > 0) {ALOGE("createLayer() failed, w or h cannot be set for container layer (w=%d, h=%d)",int(w), int(h));return BAD_VALUE;}result = createContainerLayer(client, uniqueName, w, h, flags, std::move(metadata),handle, &layer);break;default:result = BAD_VALUE;break;}....return result;
}
这里有很多Layer,我们只看第一个
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, const String8& name,uint32_t w, uint32_t h, uint32_t flags,LayerMetadata metadata, PixelFormat& format,sp<IBinder>* handle,sp<IGraphicBufferProducer>* gbp,sp<Layer>* outLayer) {....sp<BufferQueueLayer> layer = getFactory().createBufferQueueLayer(LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)));status_t err = layer->setDefaultBufferProperties(w, h, format);if (err == NO_ERROR) {*handle = layer->getHandle();*gbp = layer->getProducer();*outLayer = layer;}return err;
}
frameworks\native\services\surfaceflinger\SurfaceFlingerFactory.cpp
sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) override {return new BufferQueueLayer(args);}
BufferQueueLayer里面重写了onFirstRef方法
frameworks\native\services\surfaceflinger\BufferQueueLayer.cpp
BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {}void BufferQueueLayer::onFirstRef() {BufferLayer::onFirstRef();// Creates a custom BufferQueue for SurfaceFlingerConsumer to usesp<IGraphicBufferProducer> producer;sp<IGraphicBufferConsumer> consumer;BufferQueue::createBufferQueue(&producer, &consumer, true);mProducer = new MonitoredProducer(producer, mFlinger, this);{// Grab the SF state lock during this since it's the only safe way to access RenderEngineMutex::Autolock lock(mFlinger->mStateLock);mConsumer =new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this);}mConsumer->setConsumerUsageBits(getEffectiveUsage(0));mConsumer->setContentsChangedListener(this);mConsumer->setName(mName);// BufferQueueCore::mMaxDequeuedBufferCount is default to 1if (!mFlinger->isLayerTripleBufferingDisabled()) {mProducer->setMaxDequeuedBufferCount(2);}if (const auto display = mFlinger->getDefaultDisplayDevice()) {updateTransformHint(display);}
}
frameworks\native\libs\gui\BufferQueue.cpp
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,sp<IGraphicBufferConsumer>* outConsumer,bool consumerIsSurfaceFlinger) {sp<BufferQueueCore> core(new BufferQueueCore());sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger))sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));*outProducer = producer;*outConsumer = consumer;
}
- 创建BufferQueueCore
- 创建BufferQueueProducer
- 创建BufferQueueConsumer
BufferQueueCore
frameworks\native\libs\gui\include\gui\BufferQueueCore.h
BufferQueueDefs::SlotsType mSlots;// mQueue is a FIFO of queued buffers used in synchronous mode.Fifo mQueue;// mFreeSlots contains all of the slots which are FREE and do not currently// have a buffer attached.std::set<int> mFreeSlots;// mFreeBuffers contains all of the slots which are FREE and currently have// a buffer attached.std::list<int> mFreeBuffers;// mUnusedSlots contains all slots that are currently unused. They should be// free and not have a buffer attached.std::list<int> mUnusedSlots;// mActiveBuffers contains all slots which have a non-FREE buffer attached.std::set<int> mActiveBuffers;
BufferQueueCore除了持有BufferQueueProducer,BufferQueueConsumer和mSlots,还持有mQueue,mFreeSlots,mFreeBuffers等很多队列。
frameworks\native\libs\gui\include\gui\BufferQueueDefs.h
namespace android {class BufferQueueCore;namespace BufferQueueDefs {typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];} // namespace BufferQueueDefs
} // namespace android
NUM_BUFFER_SLOTS是64,所以mSlots最大数是64
BufferQueueProducer
BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core,bool consumerIsSurfaceFlinger) :mCore(core),mSlots(core->mSlots),.... {}
BufferQueueProducer会持有BufferQueueCore和mSlots队列的引用。
BufferQueueConsumer
BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :mCore(core),mSlots(core->mSlots),mConsumerName() {}
BufferQueueConsumer同样持有BufferQueueCore和mSlots队列的引用。
总结:在performTraversals中执行performMeasure、performLayout、performDraw之前,ViewRootImpl会先调用relayoutWindow去创建SurfaceControl,然后从SurfaceControl中获取Surface。但是在创建SurfaceControl之前,还调用了在WindowState.attach中初始化创建的mClient的createSurface方法,调用Flinger服务的createLayer生成了BufferQueueLayer,一个Layer对应一个Surface,Layer持有BufferQueueCore、BufferQueueProducer和BufferQueueConsumer,并把其中的handle和gbp赋给了SurfaceControl。
这篇关于Android—Surface,ViewRootImpl.relayoutWindow的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!