关于图形显示部分能够参考官网:Graphicsjava
Linux
一般使用Framebuffer
来用做显示输出(Framebuffer
知识详解在这里),Framebuffer
就是一块内存区域,它一般是显示驱动的内部缓冲区在内存中的映射。android
一旦用户进程把图像数据复制到Framebuffer
中,显示驱动会一个像素一个像素地扫描整个Framebuffer
,并根据其中的值更新屏幕上像素点的颜色。api
驱动中这个更新屏幕的动做是固定的,它的周期就是咱们常说的刷新率
数组
Android
关于图像渲染显示的架构图以下:
缓存
结合这张图,咱们须要重点关注的是:markdown
Native Framework
中的Surface
session
API
,一切内容都会渲染到Surface
上Surface
中会关联一个BufferQueue
用于提供图像数据缓存OpenGL ES
或Vulkan
渲染到Surface
Canvas
渲染到Surface
Image Stream Producer
的定义是可以生成图形缓冲区以供消耗的任何对象。每一个Producer
都会关联一个Surface
,例如数据结构
Canvas 2D
:Java
层主要是经过View
中建立的Surface
对象来进行操做
Surface
对象会与SurfaceFlinger
进行关联,并经过lockCanavas()
接口获取Canvas
对象lockCanvas()
会将CPU渲染程序
链接到BufferQueue
的生产方,直到Surface
被销毁时才会断开链接mediaserver视频解码器
:经过MediaPlayer
的setSurfaceHolder()
接口与SurfaceView
中的Surface
进行绑定对于Image Stream Consumer
来讲,主要是SurfaceFlinger
,该系统服务会消耗当前可见的Surface
,并使用WindowManager
中提供的信息将它们合成到显示部分。架构
SurfaceFlinger
是能够修改所显示部份内容的惟一服务。SurfaceFlinger
使用OpenGL
和Hardware Composer
来合成一组Surface
。WindowManager
请求缓冲区。而后,WindowManager
会从SurfaceFlinger
请求layer
。
layer
是surface
(包含BufferQueue
)和SurfaceControl
(包含屏幕框架等层元数据)的组合。SurfaceFlinger
建立layer
并将其发送至WindowManager
。WindowManager
将Surface
发送至应用,但会保留SurfaceControl
来操控应用在屏幕上的外观。Window Positioning
中的WindowManager
主要是用来控制Window
对象app
Window
对象是用来存放View
对象的容器,每一个Window
对象都会关联Surface
对象WindowManager
监视Window
对象的生命周期、输入和焦点事件、屏幕方向、转换、动画、位置、变换、z顺序等Window
元数据发送给SurfaceFlinger
,SurfaceFlinger
利用这些元数据把本身管理的全部Surface
组合成layer
Hardware Composer
作进一步处理HAL
层中的Hardware Composer(HWC)
会根据当前硬件来进一步进行缓冲区的组合,它的具体实现依赖于特定的显示设备
HWC
的数据流以下:SurfaceFlinger
做为client
向HWC
提供一个完整的layer
列表,而后询问HWC
计划如何处理HWC
会将这些layer
标记为client合成
或者device合成
并告知SurfaceFlinger
SurfaceFlinger
将处理标记为client合成
的layer
,而后经过BufferQueue
传递给HWC
layer
由HWC
自行处理网上一篇颇有趣的渲染总结(文中有些错误,但瑕不掩瑜):Android渲染原理
前面提到Linux
使用Framebuffer
来用做显示输出。可是,若是在屏幕更新到一半时,用户进程更新了Framebuffer
中的数据,将致使屏幕上画面的上半部分是前一帧的画面,下半部分变成了新的画面。固然这种异常会在下次刷新时纠正过来,可是在用户感知上画面会出现闪烁感
双缓冲机制
,双缓冲就是提供两块Framebuffer
,一块用于显示,另外一块用于数据更新,数据准备好后,经过ioctl
操做告诉显示设备切换用于显示的Framebuffer
,这样图像就能快速的显示出来了ioctl
操做完成后缓冲区没有切换,应用就不能肯定什么时候能够再使用缓存区,只能经过ioctl
不停地查询缓冲区状态,直到切换完成。这种CPU
主动查询的方式很低效为此Android
让底层固定地发送信号给用户进程,通知进程切换的时机,这样就避免了用户进程主动查询的操做。而这个信号就是VSYNC
信号
官方传送门:
VSYNC
官方描述以下:VSYNC
信号用来同步整个显示流程(Display Pipeline)
。显示流程
包括app
渲染、SurfaceFlinger
合成、HWC
(硬件渲染)组成
(这部分感受原文更容易理解)VSYNC synchronizes the time apps wake up to start rendering, the time SurfaceFlinger wakes up to composite the screen, and the display refresh cycle.
VSYNC
信号应该由显示驱动产生,这样才能达到最佳效果。可是Android
为了能运行在不支持VSYNC
机制的设备上,也提供了用软件来模拟产生VSYNC
信号的手段
官网描述:经过
HWC
来产生VSYNC
信号,并经过接口回调将事件进行发送(主要是SurfaceFlinger
进行事件接收)
基础知识铺垫完成,咱们先来看看Surface
官网对
Surface
的描述是:A surface is an interface for a producer to exchange buffers with a consumer.
上面描述的是一种生产者-消费者
的模式,而Surface
充当了中间衔接的角色。
以Activity
中UI
显示为例:
生产者
的任务就是把图形绘制在Surface
对象上
SurfaceView
组件了SurfaceFlinger
做为消费者
会把全部Surface
对应的图像层混合在一块儿
最后消费者
将其输出到FrameBuffer
中,这样在屏幕上就看到最后合成的图像了
下面咱们从Java层
开始分析Surface
Surface
的建立过程应用开发中不多直接使用Surface
,由于每一个Activity
中都已经建立好了各自的Surface
对象,一般只有一些特殊的应用才须要在Activity
以外再去建立Surface
,例如相机、视频播放应用。
不过,一般这些应用也是经过建立SurfaceView
来使用Surface
须要注意的是,在应用中不能直接去建立一个可用的Surface
对象(也能够说直接建立出的对象没什么实际用途),由于这样建立出的Surface
对象和SurfaceFlinger
之间没有任何关联。
该如何创见一个可用的Surface
对象呢?
咱们看下Surface
类的定义:
public class Surface implements Parcelable {
long mNativeObject;
// 一个无参构造,空实现
public Surface() {
}
public Surface(SurfaceTexture surfaceTexture) {
if (surfaceTexture == null) {
throw new IllegalArgumentException("surfaceTexture must not be null");
}
mIsSingleBuffered = surfaceTexture.isSingleBuffered();
synchronized (mLock) {
mName = surfaceTexture.toString();
setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
}
}
}
复制代码
Surface
类对外有两个构造方法:
一个是无参构造,实现也是空的
readFromParcel()
反序列化用的readFromParcel()
方法public void readFromParcel(Parcel source) {
if (source == null) {
throw new IllegalArgumentException("source must not be null");
}
synchronized (mLock) {
mName = source.readString();
mIsSingleBuffered = source.readInt() != 0;
setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
}
}
复制代码
另外一个须要传递SurfaceTexture
对象做为参数
SurfaceTexture
对象聪明的咱们会发现,readFromParcel()
和new Surface(SurfaceTexture surfaceTexture)
都会执行一个setNativeObjectLocked()
方法,咱们看下方法实现:
private void setNativeObjectLocked(long ptr) {
if (mNativeObject != ptr) {
...
mNativeObject = ptr;
...
}
}
复制代码
setNativeObjectLocked()
方法很简单,只是更新了mNativeObject
变量的数值,重点就是参数了:
setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
这两个setNativeObjectLocked()
方法的调用从参数的命名来看是针对不一样数据来源的处理。
看来要看下native
的实现了,以nativeReadFromParcel()
为例来看下:
static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jlong nativeObject, jobject parcelObj) {
Parcel* parcel = parcelForJavaObject(env, parcelObj);
...
android::view::Surface surfaceShim;
// 解析 Parcel 数据,并填充到 native层 的 Surface对象 surfaceShim
surfaceShim.readFromParcel(parcel, /*nameAlreadyRead*/true);
// 将传入的指针转换为 native层 的 Surface对象 self
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
// 比对 surfaceShim 和 self 中的 Binder 对象 IGraphicBufferProducer
if (self != nullptr
&& (IInterface::asBinder(self->getIGraphicBufferProducer()) ==
IInterface::asBinder(surfaceShim.graphicBufferProducer))) {
// 判断是同一个 IGraphicBufferProducer ,直接返回当前指针
return jlong(self.get());
}
sp<Surface> sur;
if (surfaceShim.graphicBufferProducer != nullptr) {
// IGraphicBufferProducer 不一样
// 且 surfaceShim 的 IGraphicBufferProducer 不为空
// 建立一个新的 Surface 对象 sur
sur = new Surface(surfaceShim.graphicBufferProducer, true);
sur->incStrong(&sRefBaseOwner);
}
...
// 将 sur 的指针返回给 Java 层
return jlong(sur.get());
}
复制代码
到这里咱们不难看出
Java层
的Surface
对象最重要的数据是mNativeObject
变量
mNativeObject
是一个指针,指向的native
层的Surface
对象native
层在判断是否新建Surface
对象的逻辑依赖的是IGraphicBufferProducer
对象
IGraphicBufferProducer
对象是一个Binder
引用对象那么接下来咱们重点就是这个IGraphicBufferProducer
了。
咱们先看下native层
中Surface
类的继承关系:
class Surface : public ANativeObjectBase<ANativeWindow, Surface, RefBase>
复制代码
ANativeObjectBase
的定义以下:
template <typename NATIVE_TYPE, typename TYPE, typename REF,
typename NATIVE_BASE = android_native_base_t>
class ANativeObjectBase : public NATIVE_TYPE, public REF
{...}
复制代码
整理成继承关系图就是:
再看下Surface
的构造方法:
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp)
: mGraphicBufferProducer(bufferProducer),
mCrop(Rect::EMPTY_RECT),
mBufferAge(0),
...
mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) {
... // 初始化各类成员变量
}
复制代码
从构造函数的参数能够看到,native层
的Surface
将IGraphicBufferProducer
对象保存到了mGraphicBufferProducer
变量中。
暂时仍是不清楚mGraphicBufferProducer
哪里来的,咱们去WMS
中看看
WMS
中Surface
的建立过程此处要从Activity
的onResume()
生命周期提及
onResume()
到WMS.relayoutWindow()
咱们已经知道,当AMS
触发onResume()
生命周期时会调用到ActivityThread
类的handleResumeActivity()
方法,代码以下:
public void handleResumeActivity(...) {
...
// 此处会触发 onResume 声明周期回调
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
...
ViewManager wm = a.getWindowManager();
...// 省略不少 Window 处理逻辑
wm.addView(decor, l);
...
}
复制代码
从方法中能够看到,执行完onResume()
后调用了ViewManager
的addView(decor, l)
方法
知识点:在
onResume
方法调用后才真正进行View
的添加
ViewManager
是一个接口类,真正的实现类是WindowManagerImpl
,addView()
方法实现也很简单:
public void addView(...) {
applyDefaultToken(params);
mGlobal.addView(...);
}
复制代码
调用了mGlobal
的addView()
方法方法,mGlobal
的类型是WindowManagerGlobal
,代码以下:
public void addView(...) {
...
ViewRootImpl root;
synchronized (mLock) {
...
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try {
root.setView(view, wparams, panelParentView);
}
...
}
}
复制代码
WindowManagerGlobal
类的addView()
先是建立了一个新的ViewRootImpl
对象,而后调用了ViewRootImpl
对象的setView()
方法。
ViewRootImpl
类中setView()
调用流程以下:
class ViewRootImpl{
/** * 这里也是直接 new 出来的对象 Surface * 前面已经介绍过,这个对象须要和 native层进行绑定后才能正常使用 */
public final Surface mSurface = new Surface();
ViewRootImpl(Context context, Display display){
...
// 此方法会建立 Session 对象
mWindowSession = WindowManagerGlobal.getWindowSession();
...
}
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
...
// 内部方法调用
requestLayout();
...
// 此方法会建立 SurfaceSession
res = mWindowSession.addToDisplay(...);
...
}
}
}
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
...
scheduleTraversals();
}
}
void scheduleTraversals() {
if (!mTraversalScheduled) {
...
// 异步执行 mTraversalRunnable
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
...
}
}
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
void doTraversal() {
if (mTraversalScheduled) {
...
performTraversals();
...
}
}
private void performTraversals() {
...
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
...
}
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException {
...
// 调用 mWindowSession 的 relayout 方法,并将 mSurface 对象传递过去
int relayoutResult = mWindowSession.relayout(..., mSurface);
...
return relayoutResult;
}
}
复制代码
setView()
方法最后调用的是mWindowSession
的relayout()
方法。
mWindowSession
类型是IWindowSession
,是一个Binder
引用对象。真正的Binder
服务实现是com.android.server.wm.Session
类:
class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
public Session(WindowManagerService service, ...) {
mService = service;
...
}
public int relayout(..., Surface outSurface) {
...
int res = mService.relayoutWindow(..., outSurface);
...
return res;
}
}
复制代码
终于走到了WMS
中,调用的是WMS
的relayoutWindow()
方法
WMS.relayoutWindow()
到SurfaceControl.nativeCreate()
和Surface
相关的调用关系以下:
class WindowManagerService{
public int relayoutWindow(..., Surface outSurface) {
...
result = createSurfaceControl(outSurface, ...);
...
return result;
}
private int createSurfaceControl(Surface outSurface, ...) {
...
WindowSurfaceController surfaceController;
...
surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
...
if (surfaceController != null) {
surfaceController.getSurface(outSurface);
} else {
...
outSurface.release();
}
return result;
}
}
class WindowSurfaceController{
public WindowSurfaceController(...) {
...
final SurfaceControl.Builder b = win.makeSurface()
...
.setMetadata(windowType, ownerUid);
mSurfaceControl = b.build();
}
void getSurface(Surface outSurface) {
outSurface.copyFrom(mSurfaceControl);
}
}
class Surface{
public void copyFrom(SurfaceControl other) {
if (other == null) {
throw new IllegalArgumentException("other must not be null");
}
long surfaceControlPtr = other.mNativeObject;
if (surfaceControlPtr == 0) {
throw new NullPointerException(
"null SurfaceControl native object. Are you using a released SurfaceControl?");
}
long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);
synchronized (mLock) {
if (mNativeObject != 0) {
nativeRelease(mNativeObject);
}
setNativeObjectLocked(newNativeObject);
}
}
}
复制代码
在上面的relayoutWindow()
方法中
WMS
先经过winAnimator
的createSurfaceLocked()
方法获得了一个WindowSurfaceController
对象
WindowSurfaceController
对象封装了SurfaceControl
对象WMS
调用WindowSurfaceController
对象的getSurface()
方法来对Surface
对象进行填充
getSurface()
对象只是利用自身保存的mSurfaceControl
对象Surface
的copyFrom()
方法对Surface
对象进行填充处理copyFrom()
方法
nativeGetFromSurfaceControl()
方法获得一个native
层的Surface
对象指针setNativeObjectLocked()
方法将指针保存到成员变量mNativeObject
中关键点又回到了native
层的nativeGetFromSurfaceControl()
方法,它的代码以下:
static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {
sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
sp<Surface> surface(ctrl->getSurface());
if (surface != NULL) {
surface->incStrong(&sRefBaseOwner);
}
return reinterpret_cast<jlong>(surface.get());
}
复制代码
nativeGetFromSurfaceControl()
方法是经过native
层的SurfaceControl
的getSurface()
方法来获取Surface
对象。咱们再看下getSurface()
方法:
sp<Surface> SurfaceControl::getSurface() const {
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
return generateSurfaceLocked();
}
return mSurfaceData;
}
sp<Surface> SurfaceControl::generateSurfaceLocked() const {
mSurfaceData = new Surface(mGraphicBufferProducer, false);
return mSurfaceData;
}
复制代码
在SurfaceControl
的getSurface()
方法中
mSurfaceData
指针为空时才会经过generateSurfaceLocked()
方法建立一个新的Surface
对象
Surface
对象中很关键的IGraphicBufferProducer
在这里传入的是SurfaceControl
的成员变量mGraphicBufferProducer
mSurfaceData
指针从getSurface()
方法的逻辑中咱们不难看出,SurfaceControl
对象和Surface
对象是关联在一块儿的,一对一的关系
更关键的是构造Surface
对象的核心参数居然是SurfaceControl
中的成员变量。。。。。。。。
没办法,要先搞定SurfaceControl
的建立过程才能够
前面已经讲过,WMS
经过winAnimator.createSurfaceLocked()
方法建立了WindowSurfaceController
对象,WindowSurfaceController
对象初始化时就会建立SurfaceControl
,咱们看下建立过程:
class WindowStateAnimator{
WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
...
// mSession 的类型就是前面提到的 Session 类,IWindowSession Binder服务类
mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession, ...);
...
return mSurfaceController;
}
}
class WindowSurfaceController{
public WindowSurfaceController(SurfaceSession s, ...) {
...
final SurfaceControl.Builder b = win.makeSurface()
...
.setMetadata(windowType, ownerUid);
// 经过 Builder 模式建立的
mSurfaceControl = b.build();
}
}
class SurfaceControl{
public static class Builder {
...
public SurfaceControl build() {
...
// 调用私有构造方法
return new SurfaceControl(mSession, ...);
}
...
}
private SurfaceControl(SurfaceSession session, ...) throws OutOfResourcesException, IllegalArgumentException {
...
mNativeObject = nativeCreate(session, ...);
if (mNativeObject == 0) {
throw new OutOfResourcesException(
"Couldn't allocate SurfaceControl native object");
}
...
}
}
复制代码
能够看到
SurfaceControl
对象的全程都携带着一个SurfaceSession
对象。SurfaceSession
对象在SurfaceControl
的构造方法中经过nativeCreate()
传递到了native层
,用来建立native层
的对象Java层
的Surface
对象同样,SurfaceControl
对象也会将native层
对象的指针保存到mNativeObject
中关键仍是在nativeCreate()
方法,咱们继续。。
nativeCreate()
方法以下:
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj, ...) {
ScopedUtfChars name(env, nameStr);
sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
...
sp<SurfaceControl> surface;
status_t err = client->createSurfaceChecked(
String8(name.c_str()), w, h, format, &surface, flags, parent, windowType, ownerUid);
...
return reinterpret_cast<jlong>(surface.get());
}
复制代码
nativeCreate()
方法中又出现了一个新的类型SurfaceComposerClient
,并且native层
的SurfaceControl
对象就是经过它的createSurfaceChecked()
来建立的
耐心、耐心、耐心。。。。 崩溃的时候多说几回
上面方法中的SurfaceComposerClient
对象是经过android_view_SurfaceSession_getClient()
方法获得的,看JNI
的命名格式能够推算它和SurfaceSession
类也有关系,内容以下:
sp<SurfaceComposerClient> android_view_SurfaceSession_getClient( JNIEnv* env, jobject surfaceSessionObj) {
return reinterpret_cast<SurfaceComposerClient*>(
env->GetLongField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient));
}
复制代码
android_view_SurfaceSession_getClient()
方法中的参数surfaceSessionObj
是在Java层
调用nativeCreate()
方法时传递的参数,类型是SurfaceSession
。
这里其实是将
SurfaceSession
对象中成员变量mNativeClient
的值取出来后,转换为SurfaceComposerClient
对象返回
这说明SurfaceComposerClient
对象和SurfaceSession
对象也是一块儿建立出来的,咱们继续看下SurfaceSession
和SurfaceComposerClient
的建立过程
SurfaceControl.nativeCreate
到ComposerService
须要知道的一个重要前提:每一个用户进程在
WMS
中都有且只有一个对应的Session
对象,前面已经介绍Session
是一个实现了IWindowSession
接口的Binder
服务类
Session
的成员变量mSurfaceSession
是在Session
对象初始化时建立的,那么Session
对象在何时建立的呢?
跟踪代码发现流程以下:
ViewRootImpl
初始化时会调用WindowManagerGlobal.getWindowSession()
方法WindowManagerGlobal.getWindowSession()
会调用WMS
的openSession()
方法openSession()
方法中便会在WMS
中建立一个新的Session
对象对于SurfaceSession
的初始化,是在Session
对象的windowAddedLocked()
方法中,那么windowAddedLocked()
方法又是在哪里调用的呢?
一样,咱们跟踪下方法调用:
ViewRootImpl
的setView()
方法中会调用mWindowSession.addToDisplay(...)
方法mWindowSession.addToDisplay(...)
方法会调用WMS
的addWindow()
方法WMS
的addWindow()
方法会调用WindowState
的attach()
方法attach()
方法会调用Session
的windowAddedLocked()
方法这样就串起来了,如今咱们能够继续学习SurfaceSession
的构造方法了:
/** Create a new connection with the surface flinger. */
public SurfaceSession() {
mNativeClient = nativeCreate();
}
复制代码
很简洁,源码注释也很关键。咱们看下SurfaceSession
的nativeCreate()
方法:
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
SurfaceComposerClient* client = new SurfaceComposerClient();
// 请注意此方法的调用
// 该方法会触发 onFirstRef() 的执行
client->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(client);
}
复制代码
nativeCreate()
直接建立了一个SurfaceComposerClient
对象,也没有参数。不过SurfaceComposerClient
类是从RefBase
类派生出来的,咱们看下它的构造函数和onFirstRef
函数:
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT)
{
}
// onFirstRef() 是 RefBase 提供的回调接口
// 当首次调用 incStrong() 方法时便会执行此方法
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != 0 && mStatus == NO_INIT) {
// 此处 rootProducer 应该为 null
auto rootProducer = mParent.promote();
sp<ISurfaceComposerClient> conn;
// 因此在此处执行的是 sf->createConnection() 方法
conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
sf->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
复制代码
构造方法很简单,只是将mStatus
设置为NO_INIT
。
重点是在onFirstRef()
方法中
ComposerService
的getComposerService()
方法来获得一个ISurfaceComposer
的指针createConnection()
方法建立一个ISurfaceComposerClient
对象mClient
指向这个ISurfaceComposerClient
对象咳咳咳,按照上面的调用流程咱们尚未找到关于
IGraphicBufferProducer
的信息,如今又多出来了一个ISurfaceComposerClient
。。。
好吧好吧,梳理下这部分关系先
WMS
中Surface
关系总结上面介绍的WMS
中涉及和Surface
有关的类关系以下:
看上去就挺复杂的:
SurfaceControl
和Surface
是成对建立的,考虑到绘制等需求,它们的数量会比较多Session
、SurfaceSession
和SurfaceComposerClient
对象是和链接WMS
的用户进程的数量相同SurfaceComposerClient
的做用是建立Surface
SurfaceControl
经过SurfaceComposerClient
来获取Surface
SurfaceComposerClient
是ComposerService
的具体实现类ComposerService
再到SurfaceFlinger
ComposerService
是一个单例模式的普通类,定义以下:
class ComposerService : public Singleton<ComposerService>
{
sp<ISurfaceComposer> mComposerService;
sp<IBinder::DeathRecipient> mDeathObserver;
Mutex mLock;
ComposerService();
void connectLocked();
void composerServiceDied();
friend class Singleton<ComposerService>;
public:
static sp<ISurfaceComposer> getComposerService();
};
复制代码
前面的onFirstRef()
方法中调用了ComposerService
类的静态方法getComposerService()
,咱们看下它的实现:
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
ComposerService& instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComposerService == NULL) {
ComposerService::getInstance().connectLocked();
...
}
return instance.mComposerService;
}
复制代码
getComposerService()
经过调用父类Singleton
的getInstance()
方法来取得实例对象,而后调用ComposerService
的connectLocked()
方法:
void ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
...
}
复制代码
connectLocked()
方法中链接了SurfaceFlinger
服务对象,而后把对象指针保存到mComposerService
中。
ComposerService
其实只是SurfaceFlinger
的代理,它把SurfaceFlinger
服务接口包装了起来
getComposerService()
返回的就是mComposerService
对象指针,也就是SurfaceFlinger
的Binder
对象。
前面提到,SurfaceComposerClient
对象的onFirstRef()
方法中
ComposerService::getComposerService()
得到了mComposerService
指针后mComposerService
对象的createConnection()
方法。SurfaceFlinger
服务的相关函数接口。SurfaceFlinger
中接口实现以下:
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
return initClient(new Client(this));
}
static sp<ISurfaceComposerClient> initClient(const sp<Client>& client) {
status_t err = client->initCheck();
if (err == NO_ERROR) {
return client;
}
return nullptr;
}
复制代码
createConnection()
函数中建立了一个Client
类型对象,而后将其返回给调用者,关于Client
类的定义以下:
class Client : public BnSurfaceComposerClient
复制代码
Client
是一个Binder
服务类,虽然叫Client
。而mComposerService
保存的也就是这个服务对象的指针
咱们再回到SurfaceControl
的建立过程
nativeCreate()
方法中调用了SurfaceComposerClient
的createSurfaceChecked()
方法status_t SurfaceComposerClient::createSurfaceChecked(...) {
sp<SurfaceControl> sur;
status_t err = mStatus;
if (mStatus == NO_ERROR) {
sp<IBinder> handle;
sp<IBinder> parentHandle;
sp<IGraphicBufferProducer> gbp;
if (parent != nullptr) {
parentHandle = parent->getHandle();
}
err = mClient->createSurface(name, w, h, format, flags, parentHandle,
windowType, ownerUid, &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;
}
复制代码
createSurfaceChecked()
方法
SurfaceFlinger::Client
对象的createSurface()
方法去进行建立操做
handle
、gbp
、parentHandle
都是Binder
对象
sp<IGraphicBufferProducer> gbp
就是咱们找寻已久的参数。。。。SurfaceFlinger
中进行设置SurfaceFlinger::Client
对象的createSurface()
执行完成没有错误,建立SurfaceControl
对象SurfaceFlinger
中建立Surface
SurfaceFlinger::Client
对象的createSurface()
方法以下:
status_t Client::createSurface(..., sp<IGraphicBufferProducer>* gbp) {
...
return mFlinger->createLayer(..., gbp, &parent);
}
复制代码
调用的是SurfaceFlinger
的createLayer()
方法,代码以下:
status_t SurfaceFlinger::createLayer(..., sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent) {
...
status_t result = NO_ERROR;
sp<Layer> layer;
String8 uniqueName = getUniqueLayerName(name);
// 这里分红了两种建立模式:Normal 和 Color
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal: // normal
result = createBufferLayer(client,
uniqueName, w, h, flags, format,
handle, gbp, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceColor: // color
result = createColorLayer(client,
uniqueName, w, h, flags,
handle, &layer);
break;
default:
result = BAD_VALUE;
break;
}
...
return result;
}
复制代码
createLayer()
方法按照两种模式进行建立
一种是eFXSurfaceNormal
模式,经过createBufferLayer()
方法建立,方法以下:
status_t SurfaceFlinger::createBufferLayer(..., sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) {
// initialize the surfaces
switch (format) {
case PIXEL_FORMAT_TRANSPARENT:
case PIXEL_FORMAT_TRANSLUCENT:
// 透明或半透明设置格式为 RGBA
format = PIXEL_FORMAT_RGBA_8888;
break;
case PIXEL_FORMAT_OPAQUE:
// 不透明设置格式为 RGBX
format = PIXEL_FORMAT_RGBX_8888;
break;
}
sp<BufferLayer> layer = new BufferLayer(this, client, name, w, h, flags);
status_t err = layer->setBuffers(w, h, format, flags);
if (err == NO_ERROR) {
*handle = layer->getHandle();
// 咱们关注的 IGraphicBufferProducer 在这里赋值了
*gbp = layer->getProducer();
*outLayer = layer;
}
return err;
}
复制代码
BufferLayer
对象,调用对象的setBuffers()
设置宽高和像素格式Surface
中重要的gdp
等参数也会在这里进行设置一种是eFXSurfaceColor
模式,经过createColorLayer()
方法建立:看参数传入和gdp
没啥关系,不用太过关注
status_t SurfaceFlinger::createColorLayer(...,
sp<IBinder>* handle, sp<Layer>* outLayer)
{
*outLayer = new ColorLayer(this, client, name, w, h, flags);
*handle = (*outLayer)->getHandle();
return NO_ERROR;
}
复制代码
ColorLayer
对象,也没有setBuffers()
等操做咱们重点关注eFXSurfaceNormal
模式的建立逻辑
终于,咱们找到了
sp<IGraphicBufferProducer>* gbp
的来源,是经过layer->getProducer()
方法
layer->getProducer()
方法以下:
sp<IGraphicBufferProducer> BufferLayer::getProducer() const {
return mProducer;
}
复制代码
layer->getProducer()
方法比较简单,只是返回了一个mProducer
对象的指针
mProducer
对象的建立是在BufferLayer::onFirstRef()
方法中
void BufferLayer::onFirstRef() {
Layer::onFirstRef();
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
// 经过 BufferQueue 的 createBufferQueue 方法建立 producer 和 consumer
BufferQueue::createBufferQueue(&producer, &consumer, true);
// 建立 mProducer
mProducer = new MonitoredProducer(producer, mFlinger, this);
...
}
复制代码
onFirstRef()
方法中
BufferQueue::createBufferQueue()
方法建立producer
和consumer
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;
}
复制代码
producer
对象建立MonitoredProducer
对象MonitoredProducer
头文件定义以下:
class MonitoredProducer : public BnGraphicBufferProducer {
public:
MonitoredProducer(const sp<IGraphicBufferProducer>& producer,
const sp<SurfaceFlinger>& flinger,
const wp<Layer>& layer);
virtual ~MonitoredProducer();
...
private:
// 在 BufferLayer 的 onFirstRef() 中经过 BufferQueue::createBufferQueue() 建立
sp<IGraphicBufferProducer> mProducer;
sp<SurfaceFlinger> mFlinger;
wp<Layer> mLayer;
}
复制代码
虽然MonitoredProducer
是一个Binder
实体对象,但从业务上来说它仅仅是个代理
真正管理图像缓冲区的是经过
BufferQueue::createBufferQueue()
方法建立的BufferQueueProducer producer
对象
终于接近IGraphicBufferProducer
的本质了,到这里咱们其实能够结束WMS
中Surface
的建立流程了。先回顾下整个建立流程:
上图分了三部分
Surface
和Session
的初始化ViewRootImpl
的setView()
中执行performTraversals()
SurfaceControl
对象Surface
对象进行填充scheduleTraversals()
调用流程来看,这是一个异步过程ViewRootImpl
的setView()
中执行session.addToDisplay()
SurfaceSession
对象native
层建立SurfaceComposerClient
对象须要注意的一点是SurfaceControl
对象的建立须要SurfaceSession
对象做为参数。但setView()
方法中SurfaceSession
对象的建立放在了SurfaceControl
对象的后面
一开始其实挺疑惑的,核心仍是在scheduleTraversals()
的异步调用过程,感兴趣的同窗能够参考:scheduleTraversals
到底作了什么
IGraphicBufferProducer
咱们一直强调Surface
中最重要的对象是IGraphicBufferProducer
,最后咱们也找到了它对应的Binder
实体对象MonitoredProducer
对象
MonitoredProducer
对象来讲,它又关联了一个sp<IGraphicBufferProducer>
对象mProducer
mProducer
对象具体的实现类是BufferQueueProducer
前面说Surface
像一张画布,那么Surface
为何要和BufferQueue
关联呢?
24帧
画面才能造成比较真实的动画效果
CPU
解码获得的,准备它们须要时间Surface
中Surface
须要缓冲区来临时保存数据BufferQueue
操做官方图解以下:
从前面的BufferQueue::createBufferQueue()
中能够看出:
MonitoredProducer
对象也只是一个代理,真正的业务处理对象是在createBufferQueue()
方法中建立的BufferQueueProducer
对象BufferQueueCore
和BufferQueueConsumer
对象的建立BufferQueue
-Core|Producer|Consumer
前面已经介绍,在BufferLayer
的onFirstRef()
方法中经过BufferQueue::createBufferQueue()
方法建立了三个对象:BufferQueueCore
、BufferQueueConsumer
和BufferQueueProducer
其中
BufferQueueCore
是核心,把BufferQueueConsumer
和BufferQueueProducer
对象链接在了一块儿
关于BufferQueue
的工做方式,官网有个比较直观的叙述,翻译以下:
Consumer
建立并拥有BufferQueue
数据结构,而且可存在于与其Producer
不一样的进程中Producer
须要缓冲区时,它会经过调用dequeueBuffer()
从BufferQueue
请求一个可用的缓冲区,并指定缓冲区的宽度、高度、像素格式和用法标志。Producer
填充缓冲区并经过调用queueBuffer()
将缓冲区返回到队列Consumer
经过acquireBuffer()
获取该缓冲区并使用该缓冲区的内容Consumer
操做完成后,它会经过调用releaseBuffer()
将该缓冲区返回到队列流程较为清晰,咱们从源码层面再看下,首先是BufferQueueCore
中的关键定义:
class BufferQueueCore : public virtual RefBase {
friend class BufferQueueProducer;
friend class BufferQueueConsumer;
...
private:
BufferQueueDefs::SlotsType mSlots;
}
复制代码
C++
中的friend
在这里用来使Producer
和Consumer
能够访问Core
中的成员变量。mSlots
是一个64
长度的BufferSlot
数组,稍后细讲
再看下BufferQueueProducer
类的定义:
class BufferQueueProducer : public BnGraphicBufferProducer,
private IBinder::DeathRecipient {
...
private:
sp<BufferQueueCore> mCore;
}
复制代码
再看看BufferQueueConsumer
类的定义:
class BufferQueueConsumer : public BnGraphicBufferConsumer {
...
private:
sp<BufferQueueCore> mCore;
}
复制代码
不难看出,Producer
对象和Consumer
对象经过mCore
对象链接在一块儿,查看Producer
和Consumer
这两个对象的具体方法咱们就会发现,不少操做都是直接经过mCore
对象的函数来实现的。
Consumer
和Producer
的接口定义继续看下BufferQueueConsumer
和BufferQueueProducer
的基类,分别是BnGraphicBufferProducer
和BnGraphicBufferConsumer
,定义以下:
class BnGraphicBufferProducer : public BnInterface<IGraphicBufferProducer>
class BnGraphicBufferConsumer : public SafeBnInterface<IGraphicBufferConsumer>
复制代码
它们主要是实现了两套IGraphicBufferProducer
和IGraphicBufferConsumer
的Binder
接口,主要都是操做BufferQueue
的相关接口,定义以下:
IGraphicBufferProducer
class IGraphicBufferProducer : public IInterface
{
public:
...
virtual status_t dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w, uint32_t h, PixelFormat format, uint64_t usage, uint64_t* outBufferAge, FrameEventHistoryDelta* outTimestamps) = 0;
...
virtual status_t queueBuffer(int slot, const QueueBufferInput& input, QueueBufferOutput* output) = 0;
...
virtual status_t connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp, QueueBufferOutput* output) = 0;
virtual status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) = 0;
...
};
复制代码
BufferQueueProducer
类是IGraphicBufferProducer
的实现Producer
相关功能时须要先经过connect()
方法创建链接Producer
使用完毕后须要调用disconnect()
断开链接IGraphicBufferConsumer
class IGraphicBufferConsumer : public IInterface {
public:
...
virtual status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen, uint64_t maxFrameNumber = 0) = 0;
virtual status_t detachBuffer(int slot) = 0;
virtual status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer) = 0;
virtual status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, EGLSyncKHR fence, const sp<Fence>& releaseFence) = 0;
virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) = 0;
virtual status_t consumerDisconnect() = 0;
...
};
复制代码
BufferQueueConsumer
是接口IGraphicBufferConsumer
的实现Consumer
相关功能时,需经过consumerConnect()
方法创建链接
IConsumerListener
对象,这是一个回调接口onFrameAvailable()
函数来通知Consumer
来取数据acquireBuffer()
releaseBuffer()
来把缓冲区归还给BufferQueueCore
BufferQueue
的状态转换前面提到BufferQueueCore
类中定义了一个64项
的数组mSlots
:
static constexpr int NUM_BUFFER_SLOTS = 64;
namespace BufferQueueDefs {
typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];
}
BufferQueueDefs::SlotsType mSlots;
复制代码
mSlots
数组元素类型是BufferSlot
,关键定义以下:
struct BufferSlot {
...
sp<GraphicBuffer> mGraphicBuffer;
...
BufferState mBufferState;
...
};
复制代码
mGraphicBuffer
指向图像缓冲区GraphicBuffer
的指针
GraphicBuffer
对应的即是真正的图像缓存数据mBufferState
表示图像缓冲区的状态BufferState
定义以下:
struct BufferState {
uint32_t mDequeueCount;
uint32_t mQueueCount;
uint32_t mAcquireCount;
bool mShared;
}
复制代码
BufferState
中4个变量对应的状态以下:
状态\变量 | mShared | mDequeueCount | mQueueCount | mAcquireCount |
---|---|---|---|---|
FREE |
false | 0 | 0 | 0 |
DEQUEUED |
false | 1 | 0 | 0 |
QUEUED |
false | 0 | 1 | 0 |
ACQUIRED |
false | 0 | 0 | 1 |
SHARED |
true | any | any | any |
状态之间的转换关系以下:
结合前面提到的接口,咱们看下整个状态转换过程的时序图:
到这里,咱们已经大致了解了从Surface
到SurfaceFlinger
的数据通道,dequeueBuffer()
等方法的细节就不深刻分析了,其中会涉及GraphicBuffer
的初始化过程,不影响咱们对总体的掌握(主要是太难了。。。。。),不过如下几点须要注意:
GraphicBuffer
初始化时便会执行Gralloc
模块的allocate()
方法申请共享内存缓冲区FrameBuffer
缓冲区的状况下,申请到的就是FrameBuffer
的缓冲区显示原理和Surface
相关的内容到此结束了,还有不少不完善的地方,后面再来找补吧(又挖一坑)
关于Android
图形显示的学习还剩下SurfaceFlinger
和图像输出过程两部分,但愿清明节前搞定,(ง •̀_•́)ง