本篇文章主要想介绍surface在创建过程中,所涉及到的native部分的代码,本篇以及上一篇介绍View的启动的源码都是基于android 7.0的源码进行解析的。
android sdk中的源码只是java部分的,阅读c++的代码可以在这个网站上进行查阅。
前言讲到这里,我们开始进入正题:
我们在之前已经了解了view在framework层中java方法的调用流程,现在接着WindowManagerService.java中的relayoutWindow方法看起
WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,
Configuration outConfig, Surface outSurface) {
···
synchronized(mWindowMap) {
WindowState win = windowForClientLocked(session, client, false);
if (win == null) {
return 0;
}
WindowStateAnimator winAnimator = win.mWinAnimator;
if (viewVisibility != View.GONE) {
win.setRequestedSize(requestedWidth, requestedHeight);//设置系统请求所要设置的高度和宽度
}
···
if (viewVisibility == View.VISIBLE &&
(win.mAppToken == null || !win.mAppToken.clientHidden)) {
···
try {
result = createSurfaceControl(outSurface, result, win, winAnimator);//当窗口可见时为其创建一个Surface绘图表面
} catch (Exception e) {
···
}
···
} else {
···
}
···
return result;
}
这里的createSurfaceControl()是为ViewRootImpl创建一个SurfaceControl对象,SurfaceControl这个类起到了连接java层与native层的作用,在native层创建Surface对象返回java层进行显示画面。先来看下SufaceControl这个对象的构造方法:
SurfaceControl.java
private static native long nativeCreate(SurfaceSession session, String name,
int w, int h, int format, int flags)
throws OutOfResourcesException;
public SurfaceControl(SurfaceSession session,
String name, int w, int h, int format, int flags)
throws OutOfResourcesException {
···
mName = name;
mNativeObject = nativeCreate(session, name, w, h, format, flags);//这里调用了native层的一个方法来构造这个对象,我们接着去c++代码中看一下这个方法是用来干什么的
···
}
首先在这里先简单说一下jni方法的命名规则。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));//TAG1
sp<SurfaceControl> surface = client->createSurface(
String8(name.c_str()), w, h, format, flags);//TAG2
if (surface == NULL) {
jniThrowException(env, OutOfResourcesException, NULL);
return 0;
}
surface->incStrong((void *)nativeCreate);
}
这里通过由上层传下来的SurfaceSession获取SurfaceComposerClient对象,咱们来看一下SurfaceSession是在哪里创建的。
ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
···
requestLayout();//这里是在另外一个线程中进行设置用于展示界面的窗口,与具体画面的绘制
if ((mWindowAttributes.inputFeatures
& WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
mInputChannel = new InputChannel();
}
mForceDecorViewVisibility = (mWindowAttributes.privateFlags
& PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);//这里与requestLayout()中的内容代码其实是并行执行的,在这个语句中主要用来创建与surfaceflinger会话。
} catch (RemoteException e) {
mAdded = false;
mView = null;
mAttachInfo.mRootView = null;
mInputChannel = null;
mFallbackEventHandler.setView(null);
unscheduleTraversals();
setAccessibilityFocus(null, null);
throw new RuntimeException("Adding window failed", e);
} finally {
if (restore) {
attrs.restore();
}
}
···
}
}
}
Session.java
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets,
Rect outOutsets, InputChannel outInputChannel) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
outContentInsets, outStableInsets, outOutsets, outInputChannel);
}
WindowManagerService.java
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
InputChannel outInputChannel) {
···
synchronized(mWindowMap) {
···
WindowState win = new WindowState(this, session, client, token,
attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
···
win.attach();
···
return res;
}
在这一步中,将ViewRootImpl中的Session对象封装到一个WindowState对象中,在 requestLayout()函数内部会调用到这个对象,用来在native层构建一个SurfaceControl对象。
WindowState.java
void attach() {
if (WindowManagerService.localLOGV) Slog.v(
TAG, "Attaching " + this + " token=" + mToken
+ ", list=" + mToken.windows);
mSession.windowAddedLocked();/
}
这里的mSession对象就是ViewRootImpl里面的Session对象,这里调用的这个方法创建了一个SurfaceSession对象,用来native层的连接SurfaceFlinger
SufaceSession.java
public SurfaceSession() {
mNativeClient = nativeCreate();
}
/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);
}
在native层中创建SurfaceSession其实创建的是一个SurfaceComposerClient对象,咱们在反过头来看TAG1,第一步所调用的sp client(android_view_SurfaceSession_getClient(env, sessionObj));
sp<SurfaceComposerClient> android_view_SurfaceSession_getClient(
3 JNIEnv* env, jobject surfaceSessionObj) {
return reinterpret_cast<SurfaceComposerClient*>(
env->GetLongField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient));
}
这个函数就是通过SurfaceSession返回一个SurfaceComposerClient对象,在SurfaceComposerClient的构造函数中他连接了native层中的SurfaceFlinger
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT), mComposer(Composer::getInstance())
{
}
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
if (sm != 0) {
sp<ISurfaceComposerClient> conn = sm->createConnection();//TAG3
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
ComposerService::ComposerService()
: Singleton<ComposerService>() {
Mutex::Autolock _l(mLock);
connectLocked();
}
void ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
```
mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
}
由于SurfaceFlinger是一个独立的进程,所以connectLocked执行的时候就是通过binder将SurfaceComposerClient与SurfaceFlinger两个类联系起来。我们接着来看TAG3,既然我们已经知道sm是一个对于SurfaceFlinger的一个binder对象,那么他所调用的就是SurfaceFlinger得createConnection()方法。
xref: /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
sp<ISurfaceComposerClient> bclient;
sp<Client> client(new Client(this));
status_t err = client->initCheck();
if (err == NO_ERROR) {
bclient = client;
}
return bclient;
}
看到这里!我们终于看到了他的本体!Client!因为一个android系统可能存在多个app来请求SurfaceFlinger的业务,而一个app又可能存在多个surface,而这些surface对象如果分散起来其实是不好管理的,所以android系统为他们构建了一个Client类来负责与SurfaceFlinger来交互,并用来管理自身的Surface对象。那我们回过头来看这个TAG2这部分,他是用Client来创建Surface的
xref: /frameworks/native/services/surfaceflinger/Client.cpp
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
{
/*
* createSurface must be called from the GL thread so that it can
* have access to the GL context.
*/
class MessageCreateLayer : public MessageBase {
SurfaceFlinger* flinger;
Client* client;
sp<IBinder>* handle;
sp<IGraphicBufferProducer>* gbp;
status_t result;
const String8& name;
uint32_t w, h;
PixelFormat format;
uint32_t flags;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name, Client* client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
: flinger(flinger), client(client),
handle(handle), gbp(gbp), result(NO_ERROR),
name(name), w(w), h(h), format(format), flags(flags) {
}
status_t getResult() const { return result; }
virtual bool handler() {
result = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
return true;
}
};
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}
这里,我们可以看到,创建surface时先是创建了一个MessageCreateLayer对象,他是MessageBase类的一个子类,MessageBase类在构造方法中先会调用handler()方法,此时就会通知SurfaceFlinger去创建Layer用来储存每一层画面的信息
status_t SurfaceFlinger::createLayer(
const String8& name,
const sp<Client>& client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
{
···
sp<Layer> layer;
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal:
result = createNormalLayer(client,
name, w, h, flags, format,
handle, gbp, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceDim:
result = createDimLayer(client,
name, w, h, flags,
handle, gbp, &layer);
break;
default:
result = BAD_VALUE;
break;
}
if (result != NO_ERROR) {
return result;
}
result = addClientLayer(client, *handle, *gbp, layer);
if (result != NO_ERROR) {
return result;
}
setTransactionFlags(eTransactionNeeded);
return result;
}
status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
{
···
*outLayer = new Layer(this, client, name, w, h, flags);
status_t err = (*outLayer)->setBuffers(w, h, format, flags);
if (err == NO_ERROR) {
*handle = (*outLayer)->getHandle();
*gbp = (*outLayer)->getProducer();
}
ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
return err;
}
status_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
{
*outLayer = new LayerDim(this, client, name, w, h, flags);
*handle = (*outLayer)->getHandle();
*gbp = (*outLayer)->getProducer();
return NO_ERROR;
}
从上面的代码可以看到,两种创建Layer的方式都是为将新建的这个Layer对象的binder和gbp存储在上面的client对象中
DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;
我们可以看到在Client的头文件中有着这样的定义,他是通过键值对来管理Layer的,这样client对象就能够与之通信并且管理这个layer了。
sp<IGraphicBufferProducer> getProducer() const;
在Layer的头文件中,我们可以查阅到getProducer返回的是一个IGraphicBufferProducer对象,所以gbp就是一个IGraphicBufferProducer对象,这个对象主要用来管理buffer,这里IGraphicBufferProducer就是app和BufferQueue重要桥梁,GraphicBufferProducer承担着单个应用进程中的UI显示需求,与BufferQueue打交道的就是它。
到这里,一个surface就基本创建完成。接着还有一部分就是在绘制view时,所调用的
private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty)
throws OutOfResourcesException;
方法。这个方法就是锁定了一个要更新的区域,然后返回他的画布,
xref: /frameworks/base/core/jni/android_view_Surface.cpp
291 static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
292 jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
293 sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
294
···
302
311 ANativeWindow_Buffer outBuffer;
312 status_t err = surface->lock(&outBuffer, dirtyRectPtr);
···
320
321
322 SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
323 convertPixelFormat(outBuffer.format),
324 outBuffer.format == PIXEL_FORMAT_RGBX_8888 ?
325 kOpaque_SkAlphaType : kPremul_SkAlphaType);
326
327 SkBitmap bitmap;
328 ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
329 bitmap.setInfo(info, bpr);
330 if (outBuffer.width > 0 && outBuffer.height > 0) {
331 bitmap.setPixels(outBuffer.bits);
332 } else {
333 // be safe with an empty bitmap.
334 bitmap.setPixels(NULL);
335 }
336
337 Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
338 nativeCanvas->setBitmap(bitmap);
339
···
357 return (jlong) lockedSurface.get();
358}
xref: /frameworks/native/libs/gui/Surface.cpp
1159 status_t Surface::lock(
1160 ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
1161{
```
1178 status_t err = dequeueBuffer(&out, &fenceFd);
1179 ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
1180 if (err == NO_ERROR) {
```
1250 return err;
1251}
231 int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
232 ATRACE_CALL();
233 ALOGV("Surface::dequeueBuffer");
234
235 uint32_t reqWidth;
236 uint32_t reqHeight;
237 PixelFormat reqFormat;
238 uint32_t reqUsage;
239
240 {
```
262 status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
263 reqWidth, reqHeight, reqFormat, reqUsage);
264
````
313
314 return OK;
315 }
在锁定画布之后,就只有他自己可以使用,别人无法使用,锁定时由先前Client创建的GraphicBufferProducer对象来申请buffer进行绘制使用。
总结一下,SurfaceConrtrol是一个用来存储Surface的对象,关联Java层和native层,SurfaceSession用来创建SurfaceComposerClient,利用binder连接SurfaceFlinger,SurfaceFlinger作为一个单独的进程,靠Client来管理每个app的Surface,一个app只存在一个Client,一个Client可以通过binder管理多个Layer,Layer在创建时会构造一个IGraphicBufferProducer对象,用于后面在Surface上绘制时来申请Buffer