Android 图形系统详解
Posted xyTianZhao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 图形系统详解相关的知识,希望对你有一定的参考价值。
概述
一个页面(Activity)显示到屏幕上主要经过一下几个流程:
启动 Activity → 创建 Window → WMS 注册 Window → SurfaceFlinger 创建 Surface → 合成 layer → 显示
主要涉及三个进程:App进程、System_server进程、SurfaceFlinger进程
- App 进程:负责发起 Surface 创建的请求。同时触发对控件的测量、布局、绘制以及输入事件的派发处理,主要在 ViewRootImpl中 触发( AMS 作用是统一调度所有 App 的 Activity )
- System_server 进程:主要是 WindowManagerService,负责接收 App 请求,同时和 SurfaceFlinger 建立连接,向 SF 发起具体请求创建 Surface,并且创建 Surace 的辅助管理类 SurfaceControl(与 window 一一对应)
- SurfaceFlinger:为 App 创建具体的 Surface,在 SurfaceFlinger 对应 Layer,然后负责管理、合成所有图层,最终显示在屏幕上
应用层可通过两种方式将图像绘制到屏幕上:使用 Canvas 或 OpenGL
- android.graphics.Canvas 是一个 2D 图形 API,从 4.0 开始通过 OpenGLRenderer 的绘制库实现硬件加速,将Canvas 运算转换为 OpenGL 运算,以便它们可以在 GPU 上执行,提升效率
- OpenGL ES 直接渲染到 Surface ,Android 在 Android.opengl 软件包中提供了 OpenGL ES 接口
下图是 view 绘制到 display 展示的整体流程,我们主要看左上角虚线框部分,整体分为 App 进程和系统进程两个部分
App 进程
概念解释
- Activity: 一个 Activity 对应创建一个 Surface,每个 Surface 对应 SurfaceFlinger 中的一个 Layer
- Window:每个 Activity 包含一个 Window 对象(抽象类,提供绘制窗口的通用API),由 PhoneWindow 实现。是 Activity 和整个 View 系统交互的接口。
- PhoneWindow: 继承于 Window,是 Window 类的具体实现。该类内部包含了一个 DecorView 对象,该对象是所有应用窗口(Activity 界面)的根 View。把一个 FrameLayout 类,即 DecorView 对象进行一定的包装,将他作为应用窗口的根 View,并提供一组通用的窗口操作接口。
- DecorView:PhoneWindow setContentView 函数中创建,继承 FrameLayout,是所有应用窗口的根 View。
- WindowManager :继承 ViewManager ,操作 UI 的接口,具备添加、删除和更新View,具体却委托给了WindowsManagerGlobal来进行实现
- WindowManagerImpl: 实现了 WindowManager,并持有 WindowManagerGlobal 的对象
- WindowManagerGlobal:单例模式,每个进程只有一个。持有 ViewRootImpl 的对象
- ViewRootImpl:所有 View 的根,作为 View 与后台各种服务的桥梁。用户输入系统(接收用户按键,触摸屏输入)、窗口系统(复杂窗口的布局,刷新,动画)、显示合成系统(包括定时器Choreograph, SurfaceFlinger)等
- Surface:app 层用于绘制的对象
流程分析
源码分析
ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent)
......
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
......
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
r.assistToken, r.shareableActivityToken);
......
mInstrumentation.callActivityOnCreate(activity, r.state);
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
boolean isForward, String reason)
......
wm.addView(decor, l);
......
Activity.java
private Window mWindow;
final void attach(......)
......
mWindow = new PhoneWindow(this, window, activityConfigCallback);
......
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
......
protected void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity);
public void setContentView(@LayoutRes int layoutResID)
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
Window.java
private WindowManager mWindowManager;
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
boolean hardwareAccelerated)
......
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
......
PhoneWindow.java
private DecorView mDecor;
public void setContentView(View view, ViewGroup.LayoutParams params)
......
installDecor();
......
private void installDecor()
......
mDecor = generateDecor(-1);
......
protected DecorView generateDecor(int featureId)
......
return new DecorView(context, featureId, this, getAttributes());
WindowManagerImpl.java
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
public WindowManagerImpl createLocalWindowManager(Window parentWindow)
return new WindowManagerImpl(mContext, parentWindow, mWindowContextToken);
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params)
......
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
mContext.getUserId());
WindowManagerGlobal.java
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow, int userId)
......
ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
......
root = new ViewRootImpl(view.getContext(), display);
......
mRoots.add(root);
......
root.setView(view, wparams, panelParentView, userId);
......
ViewRootImpl.java
View mView;//DecorView
public final Surface mSurface = new Surface();
private final SurfaceControl mSurfaceControl = new SurfaceControl();
// 接收显示系统的时间脉冲(垂直同步信号- VSync 信号)
// 同 Vsync 机制配合,控制同步处理输入(Input)、动画(Animation)、绘制(Draw)三个UI操作
final Choreographer mChoreographer;
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
int userId)
......
mView = view;
......
mWindowSession.addToDisplayAsUser()
......
requestLayout();
......
public void requestLayout()
......
scheduleTraversals();
......
final class TraversalRunnable implements Runnable
@Override
public void run()
doTraversal();
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
void scheduleTraversals()
......
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
......
void doTraversal()
......
performTraversals();
......
private void performTraversals()
......
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
......
performLayout(lp, mWidth, mHeight);
......
performDraw()
......
private boolean performDraw()
......
draw(fullRedrawNeeded, usingAsyncReport && mSyncBuffer);
......
private boolean draw(boolean fullRedrawNeeded, boolean forceDraw)
......
drawSoftware(surface, mAttachInfo, xOffset, yOffset,
scalingRequired, dirty, surfaceInsets);
......
private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
boolean scalingRequired, Rect dirty, Rect surfaceInsets)
......
canvas = mSurface.lockCanvas(dirty);
......
//DecorView
mView.draw(canvas);
......
surface.unlockCanvasAndPost(canvas);
System 进程
概念解释
-
WindowToken:将同一应用组件(Activity、InputMethod、Wallpaper或者Dream)的窗口组织到一起
-
WindowState:表示一个窗口的所有属性,是 WMS 事实上的窗口
-
WindowManagerService:为所有窗口分配 Surface、负责 Surface 的显示顺序(Z序)以及大小尺寸、控制窗口动画,并且还是输入系统的中转站
-
Surface:native 层用于处理窗口的大小位置裁剪等操作
-
SurfaceComposerClient:与 SurfaceFlinger 进行通信,代理对象 mClient,对应 SurfaceFlinger 的 Binder 本地 Client 对象
-
SurfaceControl: app 层 surface 向 native 层提交的 buffer 的控制逻辑
-
BufferQueue:数据的生产者(Surface、BufferQueueProducer)与消费者 (SurfaceFlinger、BufferQueueConsumer)
-
Layer:SurfaceFlinger 进行合成的基本操作单元,当应用创建 Surface 的时候在 SurfaceFlinger 内部创建Layer,因此一个 Surface 对应一个 Layer。
-
SurfaceFlinger:运行在独立进程的 Service, 接收所有 Window 的 Surface 作为输入,根据 Z-Order, 透明度,大小,位置等参数,计算出每个 Surface 在最终合成图像中的位置,然后交由 HWComposer 或 OpenGL 生成最终的显示 Buffer, 然后显示到设备上
对应关系:
Activity -> Window -> DecorView -> ViewRootImpl -> WindowState -> Surface -> Layer 是一一对应的。
流程分析
源码分析
SurfaceFlinger 启动
main_surfaceflinger.cpp
int main(int, char**)
......
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
......
flinger->init();
......
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
......
// run surface flinger in this thread
flinger->run();
SurfaceFlinger.cpp
void SurfaceFlinger::onFirstRef()
......
mEventQueue.init(this);
......
void SurfaceFlinger::init()
......
// 初始化OpenGL 图形库相关配置
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
......
// 创建显示设备的抽象代表,负责和显示设备打交道
mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));
......
// app的VSync信号,也就是Systrace中的VSync-app,它最终是发往到choreographer,
// 主要处理三件事情INPUT、ANIMATION、TRAVERSAL
// start the EventThread
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc);
......
void SurfaceFlinger::run()
do
//运行线程,等待数据
waitForEvent();
while (true);
void SurfaceFlinger::waitForEvent()
mEventQueue.waitMessage();
// 发送数据
status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
nsecs_t reltime, uint32_t /* flags */)
status_t res = mEventQueue.postMessage(msg, reltime);
if (res == NO_ERROR)
msg->wait();
return res;
MessageQueue.cpp
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
status_t MessageQueue::postMessage(const sp<MessageBase>& messageHandler, nsecs_t relTime)
const Message dummyMessage;
if (relTime > 0)
mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
else
mLooper->sendMessage(messageHandler, dummyMessage);
return NO_ERROR;
创建 Native 层 Surface 以及 SurfaceFlinger 的 Layer
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<以上是关于Android 图形系统详解的主要内容,如果未能解决你的问题,请参考以下文章
Android Drawable - Shape Drawable使用详解(附图)