Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl
Posted 薛瑄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl相关的知识,希望对你有一定的参考价值。
前言
上一篇我们分析了,app与SurfaceFlinger建立连接的过程,现在我们就可以继续往下分析,看下创建Surface的过程。
我们可以将Surface理解为一个绘图表面,android应用程序负责往这个绘图表面上填内容,而SurfaceFlinger服务负责将这个绘图表面的内容取出来,并且渲染在显示屏上。
Android 图形架构 之一 ——概述
Android 图形架构 之二—— SurfaceFlinger 启动和连接
Android 图形架构 之三—— 创建Layer、Surface、SurfaceControl
Android 图形架构 之四——图形缓冲区的申请和消费流程及核心类
Android 图形架构 之五——深入分析addView所发生的的一切
Android 图形架构 之六——深入分析draw()是如何工作的
Android 图形架构 之七——Choreographer 源码分析
Android图形架构 之八——硬件VSync、VSync-app、Vsync-sf
概述
在Android中,Window与Surface一一对应。 如果说Window关心的是层次和布局,是从设计者角度定义的类,Surface则从实现角度出发,是工程师关系和考虑的类。Window的内容是变化 的,Surface需要有空间来记录每个时刻Window的内容。
在Android的SurfaceFlinger实现里,使用了三缓冲,保证了界面更新的稳定性和低延时。可参考这篇文章 了解更多
SurfaceFlinger 是运行在独立进程的Service, 它接收所有Window的Surface作为输入,根据Z-Order, 透明度,大小,位置等参数,计算出每个Surface在最终合成图像中的位置,然后交由HWComposer或OpenGL生成最终的显示Buffer, 然后显示到特定的显示设备上。SurfaceFlinger的会定期检查所有Layer的参数更新(LayerStack等),计算新的DirtyRegion,然后将结果推送给底层显示驱动进行显示。
在SurfaceFlinger服务中,绘图使用Layer类来描述。Layer是SurfaceFlinger 进行合成的基本操作单元。当应用创建Surface的时候在SurfaceFlinger内部创建Layer,因此一个Surface对应一个 Layer, 但注意,Surface不一定对应于Window,Android中有些Surface并不跟某个Window相关,而是有程序直接创建,比如说 StrictMode, 一块红色的背景,用于提示示Java代码中的一些异常, 还有SurfaceView, 用于显示有硬件输出的视频内容等。
Each Layer has:
- Z order
- Alpha value from 0 to 255
- visibleRegion
- crop region
- transformation: rotate 0, 90, 180, 270: flip H, V: scale
当多个Layer进行合成的时候,并不是整个Layer的空间都会被完全显示,根据这个Layer最终的显示效果,一个Layer可以被划分成很多的Region, Android SurfaceFlinger 定义了以下一些Region类型:
- TransparantRegion: 完全透明的区域,在它之下的区域将被显示出来。
- OpaqueRegion: 完全不透明的区域,是否显示取决于它上面是否有遮挡或是否透明。
- VisibleRegion: 可见区域,包括完全不透明无遮挡区域或半透明区域。 visibleRegion = Region - above OpaqueRegion.
- CoveredRegion: 被遮挡区域,在它之上,有不透明或半透明区域。
- DirtyRegion: 可见部分改变区域,包括新的被遮挡区域,和新的露出区域。
Android 系统支持多种显示设备,比如说,输出到手机屏幕,或者通过WiFi 投射到电视屏幕。Android用DisplayDevice类来表示这样的设备。不是所有的Layer都会输出到所有的Display, 比如说,我们可以只将Video Layer投射到电视, 而非整个屏幕。LayerStack 就是为此设计,LayerStack 是一个Display 对象的一个数值, 而类Layer里成员State结构体也有成员变量mLayerStack, 只有两者的mLayerStack 值相同,Layer才会被输出到给该Display设备。所以LayerStack 决定了每个Display设备上可以显示的Layer数目。
上面描述的几个概念,均是针对于显示这个层面,更多是涉及到中下层模块,应用层并不参与也无需关心。对于应用而言,它关心的是如何将内容画出来。Canvas 是Java层定义的一个类,它对应与Surface上的某个区域并提供了很多的2D绘制函数(借助于底层的Skia或OpenGL)。应用只需通过 LockCanvas() 来获取一个Canvas对象,并调用它的绘画方法,然后 unLockCanvasAndPost()来通知底层将更新内容进行显示。当然,并不是所有应用程序都需要直接操作Canva, 事实上只有少量应用需要直接操作Canvas, Android提供了很多封装好的控件 Widget,应用只需提供素材,如文字,图片,属性等等,这些控件会调用Canvas提供的接口帮用户完成绘制工作。
一、App进程中 相关 过程分析
下图是主要函数的时序图,接下来我们分析,如何调用和获取 SurfaceFlinger、SurfaceControl、Surface。也就是从下图中的第8步,开始分析, 在后续的文章会分析第8步之前的流程
和Native 层创建Surface 一样,通过 SurfaceFlinger,先创建一个SurfaceControl,然后利用SurfaceControl创建Surface。下面就来具体看看在Java层是如何实现的,其实都是通过jni 调用对应的Native函数
1.1、创建SurfaceSession
代码位于frameworks/base/core/java/android/view/SurfaceSession.java:
代码一:
public final class SurfaceSession
// Note: This field is accessed by native code.
private long mNativeClient; // SurfaceComposerClient*
private static native long nativeCreate();
/** Create a new connection with the surface flinger. */
public SurfaceSession()
mNativeClient = nativeCreate();
nativeCreate 是一个JNI调用,来看看对应代码frameworks/base/core/jni/android_view_SurfaceSession.cpp:
代码二:
static jlong nativeCreate(JNIEnv* env, jclass clazz)
//SurfaceComposerClient专门用来和surfaceflinger建立connection(ISurfaceComposerClient)
SurfaceComposerClient* client = new SurfaceComposerClient();
client->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(client);
在文章Android 图形架构 之二—— SurfaceFlinger 启动和连接介绍过,SurfaceFlinger 进行通信的就是通过SurfaceComposerClient,他们是进程间通信,在SurfaceComposerClient中有对应的Binder代理对象mClient,对应 SurfaceFlinger 的Binder本地 Client 对象。
在SurfaceSession中获取到了SurfaceComposerClient对象,接下来就可以与SurfaceFlinger 进行通信了。
1.2、创建SurfaceControl
在App进程中,每一个界面都用一个Surface对象来描述,每一个Surface对象都是由一个SurfaceControl对象来创建的。Surface类和SurfaceControl类的关系以及实现如图所示:
位于frameworks/native/libs/gui/SurfaceControl.java:
代码三:
public SurfaceControl(SurfaceSession session,
String name, int w, int h, int format, int flags)
throws OutOfResourcesException
......
mName = name;
//调用nativeCreate本地方法
mNativeObject = nativeCreate(session, name, w, h, format, flags);
......
private final String mName;
long mNativeObject; // package visibility only for Surface.java access
private static native long nativeCreate(SurfaceSession session, String name,
int w, int h, int format, int flags)
throws OutOfResourcesException;
nativeCreate 是一个JNI调用,来看看对应代码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)
ScopedUtfChars name(env, nameStr);
sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
//调用SurfaceComposerClient的createSurface,就会调用到代码五的createSurfaceChecked,在Native层,
//createSurface 返回是的 SurfaceControl 对象
sp<SurfaceControl> surface = client->createSurface(
String8(name.c_str()), w, h, format, flags);
。。。
surface->incStrong((void *)nativeCreate);
return reinterpret_cast<jlong>(surface.get());
调用到SurfaceComposerClient类的createSurfaceChecked,创建Layer(到SurfaceFling进程中)和Surface(在App进程中)
代码五:
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)
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();
// 这里是创建Layer,使用mClient 进程间通信,最终在Client类中进行具体操作
err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
&handle, &gbp);
if (err == NO_ERROR)
//创建一个SurfaceControl,使用它创建surface
*outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);
return err;
该函数的流程图如下
在文章Android 图形架构 之二—— SurfaceFlinger 启动和连接分析过,SurfaceComposerClient中的mClient 是通过SurfaceFling进程返回的,用于进程间通信。所以mClient->createSurface
会调用到SurfaceFling进程中。
下面先分析 new SurfaceControl
流程(上图第11步之后)。后面章节再分析SurfaceFling进程的mClient->createSurface
流程(上图第2步之后)
SurfaceControl的构造函数也比较简单,位于frameworks/native/libs/gui/SurfaceControl.cpp中:
代码六:
SurfaceControl::SurfaceControl(
const sp<SurfaceComposerClient>& client,
const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbp,
bool owned)
: mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned)
-
SurfaceControl类的成员变量mClient是一个类型为SurfaceComposerClient对象,Android应用程序主要就是通过SurfaceComposerClient来和SurfaceFlinger服务建立连接的
-
SurfaceControl类的成员变量mHandle是指向创建Layer时,将Layer和SurfaceFlinger作为构造函数的参数创建一个Handle对象,这个Handle是一个Binder的实现,就是标识Surface的全局唯一性。
-
SurfaceControl类的成员变量mGraphicBufferProducer是指向Layer中的gbp参数,
-
SurfaceControl类的成员变量mSurfaceData是一个类型为Surface的强指针,它指向了一个Surface对象。
1.3、 创建Surface
从SurfaceControl获取Surface信息。位于frameworks/base/core/java/android/view/Surface.java:
代码七:
public void copyFrom(SurfaceControl other)
。。。
long surfaceControlPtr = other.mNativeObject;
。。。
//在Native层创建surface,并返回给newNativeObject
//代码八分析
long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
synchronized (mLock)
if (mNativeObject != 0)
nativeRelease(mNativeObject);
//把Native的surface 句柄 ,赋值给java层的surface 的成员变量
//代码十一分析
setNativeObjectLocked(newNativeObject);
nativeCreateFromSurfaceControl 是jni调用
对应的代码 位于 frameworks/base/core/jni/android_view_Surface.cpp:
代码八:
static jlong nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz,
jlong surfaceControlNativeObj)
sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
//调用SurfaceControl的getSurface函数,最终会调用代码九 generateSurfaceLocked,创建了Native层的surface,
sp<Surface> surface(ctrl->getSurface());
if (surface != NULL)
surface->incStrong(&sRefBaseOwner);
return reinterpret_cast<jlong>(surface.get());
最终调用到SurfaceControl的generateSurfaceLocked() ,来创建一个Surface
代码九:
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;
参数 mGraphicBufferProducer 是Layer中的gbp 参数,它是一个sp< IGraphicBufferProducer > 类型的对象,MonitoredProducer只是一个代理类,真正的实现是producer参数。
Android系统是通过OpenGL库来绘制UI的。OpenGL库在绘制UI的时候,需要底层的系统提供一个本地窗口给它,以便它可以将UI绘制在这个本地窗口上。Android系统为OpenGL库定提供的本地窗口是ANativeWindow,Surface类通过ANativeObjectBase类间接地继承了ANativeWindow类,因此,Surface类就是一个本地窗口。因此可以将Surface类看作OpenGL库与Android的UI系统之间的一个桥梁。
看看Surface的构造函数,位于frameworks/native/libs/gui/Surface.cpp:
代码十:
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp)
: mGraphicBufferProducer(bufferProducer),
mCrop(Rect::EMPTY_RECT),
mBufferAge(0),
mGenerationNumber(0),
mSharedBufferMode(false),
mAutoRefresh(false),
mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
mSharedBufferHasBeenQueued(false),
mQueriedSupportedTimestamps(false),
mFrameTimestampsSupportsPresent(false),
mEnableFrameTimestamps(false),
mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>())
// Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval = hook_setSwapInterval;
ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
ANativeWindow::cancelBuffer = hook_cancelBuffer;
ANativeWindow::queueBuffer = hook_queueBuffer;
ANativeWindow::query = hook_query;
ANativeWindow::perform = hook_perform;
ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
mReqWidth = 0;
mReqHeight = 0;
mReqFormat = 0;
mReqUsage = 0;
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
mDataSpace = Dataspace::UNKNOWN;
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
mStickyTransform = 0;
mDefaultWidth = 0;
mDefaultHeight = 0;
mUserWidth = 0;
mUserHeight = 0;
mTransformHint = 0;
mConsumerRunningBehind = false;
mConnectedToCpu = false;
mProducerControlledByApp = controlledByApp;
mSwapIntervalZero = false;
主要是设置了一些钩子方法,用于创建GraphicBuffer等等。还有一些变量的初始化。所以重点应该在这些钩子方法当中。
Surface 创建完成了,回到代码七,继续执行 setNativeObjectLocked()
代码十一:
private void setNativeObjectLocked(long ptr)
//句柄值,是否与上一次的一样
if (mNativeObject != ptr)
if (mNativeObject == 0 && ptr != 0)
mCloseGuard.open("release");
else if (mNativeObject != 0 && ptr == 0)
mCloseGuard.close();
//赋值句柄值,到surface 的成员变量mNativeObject
mNativeObject = ptr;
mGenerationId += 1;
if (mHwuiContext != null)
mHwuiContext.updateSurface();
到此,Layer、Surface、SurfaceControl 的创建过程,分析完了,但是前后的流程还不完整。
例如:? -> java 层surface -> native 层 surface ,谁来调用java层的,也就是这个? 是什么样的逻辑,实现什么功能。在文章Android 图形架构 之五—— 深入分析addView所发生的的一切进行了详细分析
下面我们接着上面代码五的流程分析 mClient->createSurface
,进入到SurfaceFlinger进程中
二、 SurfaceFlinger进程中创建Layer
Android应用程序主要就是通过SurfaceComposerClient来和SurfaceFlinger服务建立连接,建立完成后,会得到一个Client的Binder代理对象,保存变量mClient中。(这个过程查看 Android 图形架构 之二—— SurfaceFlinger 启动和连接)
2.1、 Layer创建
因为mClient 是Client 的代理对象,所以会执行到 SurfaceFling进程中 Client的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.
//这个mFlinger 就是SurfaceFlinger对象
return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
parentHandle);
下面来看看SurfaceFlinger的createLayer函数
代码十三:
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;
。。。省略代码,这里是有多种Layer的,由于时间和能力有限、暂不分析其他的Layer,和本系列文章关系最紧要的就是BufferQueueLayer。。。
default:
result = BAD_VALUE;
break;
if (result != NO_ERROR)
return result;
if (primaryDisplayOnly)
layer->setPrimaryDisplayOnly();
bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();
result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
addToCurrentState);
if (result != NO_ERROR)
return result;
mInterceptor->saveSurfaceCreation(layer);
setTransactionFlags(eTransactionNeeded);
return result;
下面来看看createBufferQueueLayer
代码十四:
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)
// initialize the surfaces
switch (format)
case PIXEL_FORMAT_TRANSPARENT:
case PIXEL_FORMAT_TRANSLUCENT:
format = PIXEL_FORMAT_RGBA_8888;
break;
case PIXEL_FORMAT_OPAQUE:
format = PIXEL_FORMAT_RGBX_8888;
break;
//使用工厂模式,创建BufferQueueLayer,
sp<BufferQueueLayer> layer = getFactory().createBufferQueueLayer(
LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)));
//设置layer的缓冲区默认属性
status_t err = layer->setDefaultBufferProperties(w, h, format);
if (err == NO_ERROR)
//参数handle 和 gbp,在创建应用端 的surface 使用到了,下面会分析
*handle = layer->getHandle();
*gbp = layer->getProducer();
*outLayer = layer;
ALOGE_IF(err, "createBufferQueueLayer() failed (%s)", strerror(-err));
return err;
BufferQueueLayer 继承了BufferLayer,后者继承了Layer,主要是在Layer构造函数中进行了一些初始化的工作,宽高、z轴、透明度等(其实很多值 的含义,我还不知道)
代码十五:
BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args)
对象第一次被赋值给强指针会调用onFirstRef函数:
代码十六:
void BufferQueueLayer::onFirstRef()
BufferLayer::onFirstRef();
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
//创建了生产者和消费者缓冲区,这两个缓冲区将来会存放UI的内容数据
//这里是重点,会面会有文章详细分析
sp<IGraphicBufferProducer> producer;
sp<IGraphicB以上是关于Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl的主要内容,如果未能解决你的问题,请参考以下文章
Android 图形架构 之二—— SurfaceFlinger 启动和连接
Android 图形架构 之二—— SurfaceFlinger 启动和连接
Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl
Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl