画面更新流程
从底层的显示硬件,SOC和DDIC的接口,linux和Userspace的图形接口以及APP与SurfaceFlinger,HWC service三者关系,了解了帧数据流动所经过的关键节点,并重点讨论了帧buffer是如何管理的,以及在流动过程中是如何做到同步的。接下来我们将从应用侧角度从山到下看一下应用所绘制的画面是如何使用到我们上面所设计的流程的。
画布的申请
从5.4的讨论可知,应用侧对图层的操作是以Surface为接口的,其定义如下,它包含了一些更新画面相关的核心api, 比如dequeueBuffer/queueBuffer/connect/disconnect等等。
Surface.h (frameworks\native\libs\gui\include\gui)
class Surface
: public ANativeObjectBase<ANativeWindow, Surface, RefBase>
{
......
protected:
virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd);
virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd);
virtual int perform(int operation, va_list args);
......
virtual int connect(int api);
......
public:
virtual int disconnect(int api,
IGraphicBufferProducer::DisconnectMode mode =
IGraphicBufferProducer::DisconnectMode::Api);
}
那么应用要想画出它的画面,第一个要解决的问题就是应用侧的Surface对象是如何创建? 它又是如何与SurfaceFlinger建立联系的?下面我们将从代码逻辑中找寻到它的建立过程。
在Android系统中每个Activity都有一个独立的画布(在应用侧称为Surface,在SurfaceFlinger侧称为Layer), 无论这个Activity安排了多么复杂的view结构,它们最终都是被画在了所属Activity的这块画布上,当然也有一个例外,SurfaceView是有自已独立的画布的,但此处我们先只讨论Activity画布的建立过程。
首先每个应用都会创建有自已的Activity, 进而Android会为Activity创建一个ViewRootImpl, 并调用到它的performTraversals这个函数
该函数里会调用到relayoutWindow函数:
frameworks/base/core/java/android/view/ViewRootImpl.java
private void performTraversals() {
......
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
......
}
relayoutWindow函数里会调用到WindowSession的relayout函数,这个函数是一个跨进程调用,mWindowSession可以看作是WMS在应用侧的代表:
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, mTmpRect, mTmpRect, mTmpRect, mPendingBackDropFrame,
mPendingDisplayCutout, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
mTempControls, mSurfaceSize, mBlastSurfaceControl);
......
}
//frameworks/base/core/java/android/XXX/Session.java
final class Session extends IWindowSession.Stub
implements IBinder.DeathRecipient {
......
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Configuration
outConfig,
Surface outSurface) {
if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED relayout from "
+ Binder.getCallingPid());
int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, flags,
outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
outStableInsets, outsets, outConfig, outSurface);
if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
return res;
}
......
}
随着代码的执行让我们把视角切换到system_server进程(WMS的relayoutWindow函数),这里会调用createSurfaceControl去创建一个SurfaceControl:
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags,
long frameNumber, Rect outFrame, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Rect outBackdropFrame,
DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Point outSurfaceSize,
SurfaceControl outBLASTSurfaceControl) {
......
try {
result = createSurfaceControl(outSurfaceControl, outBLASTSurfaceControl,
result, win, winAnimator);
} catch (Exception e) {
......
}
SurfaceControl的创建过程,注意这里创建工作是调用winAnimator来完成的,注意下面那句surfaceController.getSurfaceControl会把创建出来的SurfaceControl通过形参outSurfaceControl传出去:
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
private int createSurfaceControl(SurfaceControl outSurfaceControl,
SurfaceControl outBLASTSurfaceControl, int result,
WindowState win, WindowStateAnimator winAnimator) {
......
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);
......
}
......
}
我们先看下创建过程,创建了一个WindowSurfaceController,进而再创建SurfaceControll:
frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java文章来源:https://www.toymoban.com/news/detail-539312.html
WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
......
/*WindowSurfaceController mSurfaceController;*/
mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
height, format, flags, this, windowType, ownerUid);
......
}
WindowSurfaceController.java (frameworks\base\services\core\java\com\android\server\wm)文章来源地址https://www.toymoban.com/news/detail-539312.html
WindowSurfaceController(String name, int w, int h, int format,
int flags, WindowStateAnimator animator, int windowType, int
到了这里,关于Android 画面显示流程三的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!