Surface的理解
Posted 小图包
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Surface的理解相关的知识,希望对你有一定的参考价值。
1 Surface創建
既然requestLayout
内部是通过给主线程Handler发送任务消息并在Vsync同步信号返回后执行Runable
。那我们就继续看看Runable
内部执行的
// ========== android.view.ViewRootImpl ===========
void doTraversal()
if (mTraversalScheduled)
mTraversalScheduled = false;
//移除同步屏障,已经开始执行View绘制任务,允许后续继续执行同步消息
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
...
//执行遍历视图树操作
performTraversals();
...
private void performTraversals()
//实际上就是最顶层的DecorView
final View host = mView;
...
//关键代码,检查Surface图像缓冲区队列建立连接
relayoutResult = relayoutWindow(...);
...
//window的宽高
if (mWidth != frame.width() || mHeight != frame.height())
mWidth = frame.width();
mHeight = frame.height();
...
// 最外层的测量宽高
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
//测量尺寸,内部执行View.measure()方法
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
//布局排版,内部执行View.layout()方法
performLayout(lp, mWidth, mHeight);
...
//开始绘制View,内部执行View.draw()方法
performDraw();
...
doTraversal
方法做了些什么。视图绘制请求最终都在performTraversals
方法内,依次执行measure
,layout
,draw
等方法。而在这些操作调用之前,会最先调用了一个relayoutWindow
方法,这里先以此展开继续分析。
java层 SurfaceControl创建
// ============== android.view.ViewRootImpl ================
final IWindowSession mWindowSession;
//Surface的句柄类,默认构造为空对象,只是一个指针,没有实际引用
private final SurfaceControl mSurfaceControl = new SurfaceControl();
private SurfaceControl mBlastSurfaceControl = new SurfaceControl();
//默认构造函数是个空对象,只是一个指针,没有实际引用
public final Surface mSurface = new Surface();
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,...)...
...
//跨进程Binder代理调用,内部创建了native的SurfaceControl,并赋值给jave层内部变量对象引用地址
int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
..., mSurfaceControl, mSurfaceSize, mBlastSurfaceControl);
...
if (mSurfaceControl.isValid())
//此时mSurfaceControl已经有实际引用
...
//从SurfaceControl拷贝native Surface对象引用
mSurface.copyFrom(mSurfaceControl);
...
// ============ android.view.SurfaceControl =================
public final class SurfaceControl implements Parcelable
// native层的SurfaceControl 的对象引用地址
public long mNativeObject;
// 默认实现为空对象
public SurfaceControl()
public boolean isValid()
return mNativeObject != 0;
// android.view.Surface
public class Surface implements Parcelable
//默认为空对象
public Surface()
relayoutWindow
内部通过Binder机制跨进程调用了system_service进程内的Session.relayout
方法,并传入了mSurfaceControl
对象。
紧接着就开始判断该对象内部的mNativeObject
变量不为0,然后让mSurface
从该对象内拷贝赋值。
但mSurfaceControl
默认构造函数又为空实现
// ============== com.android.server.wm.Session =======================
class Session extends IWindowSession.Stub implements IBinder.DeathRecipient
@Override
public int relayout(IWindow window, ...
SurfaceControl outSurfaceControl, ... , Point outSurfaceSize
SurfaceControl outBLASTSurfaceControl)
1
int res = mService.relayoutWindow(this, window, ... ,
outSurfaceControl, outSurfaceSize,
outBLASTSurfaceControl);
...
return res;
//================== com.android.server.wm.WindowManagerService ===================
public int relayoutWindow(Session session, IWindow client, ... ,
SurfaceControl outSurfaceControl, ... , Point outSurfaceSize,
SurfaceControl outBLASTSurfaceControl)
...
//获取addWindow时创建的WindowState对象
final WindowState win = windowForClientLocked(session, client, false);
...
WindowStateAnimator winAnimator = win.mWinAnimator;
...
int result = 0;
...
//判断是否需要重新建立关联的SurfaceControl
final boolean shouldRelayout = viewVisibility == View.VISIBLE &&
(win.mActivityRecord == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
|| win.mActivityRecord.isClientVisible());
...
//窗口内第一次启动
if(shouldRelayout)
2 //创建native的SurfaceControl
result = createSurfaceControl(outSurfaceControl, outBLASTSurfaceControl,
result, win, winAnimator);
else
...
...
return result
final WindowState windowForClientLocked(Session session, IBinder client, boolean throwOnError)
//获取当前App进程的View与system_service进程关联,addWindow时创建的WindowState,
//其持有与SurfaceFLinger连接的Client
WindowState win = mWindowMap.get(client);
...
return win;
总结 1 Session
作为一个中间类,会转交给WindowManagerService.relayoutWindow
处理。
而且在relayoutWindow
中,传入了一个outSurfaceControl
参数
2调用了createSurfaceControl
方法
//================== com.android.server.wm.WindowManagerService ===================
private int createSurfaceControl(SurfaceControl outSurfaceControl,
SurfaceControl outBLASTSurfaceControl, int result,
WindowState win, WindowStateAnimator winAnimator)
...
WindowSurfaceController surfaceController =
winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
...
//内部调用copyFrom方法,即拷贝到outSurfaceControl
surfaceController.getSurfaceControl(outSurfaceControl);
surfaceController.getBLASTSurfaceControl(outBLASTSurfaceControl);
看getSurfaceControl
方法
// ============ com.android.server.wm.WindowSurfaceController ====================
class WindowSurfaceController
SurfaceControl mSurfaceControl;
WindowSurfaceController(String name, int w, int h, ...,
WindowStateAnimator animator,...)
final WindowState win = animator.mWin;
...
//暂且忽略这一串Builder参数,Window请求Surface
final SurfaceControl.Builder b = win.makeSurface()
.setParent(win.getSurfaceControl())
.setName(name)
.setBufferSize(w, h)
.setFormat(format)
.setFlags(flags)
.setMetadata(METADATA_WINDOW_TYPE, windowType)
.setMetadata(METADATA_OWNER_UID, ownerUid)
.setCallsite("WindowSurfaceController");
...
mSurfaceControl = b.build();
...
void getSurfaceControl(SurfaceControl outSurfaceControl)
outSurfaceControl.copyFrom(mSurfaceControl, "WindowSurfaceController.getSurfaceControl");
void getBLASTSurfaceControl(SurfaceControl outSurfaceControl)
if (mBLASTSurfaceControl != null)
outSurfaceControl.copyFrom(mBLASTSurfaceControl, "WindowSurfaceController.getBLASTSurfaceControl");
getSurfaceControl
实际上就是从WindowSurfaceController
内部拷贝了一份SurfaceControl
,并赋值给传入的outSurfaceControl
。
而且在WindowSurfaceController
的构造函数内,通过SurfaceControl.Builder.build
方法请求并创建了这个原始SurfaceControl
。
// ============ android.view.SurfaceControl ====================
public final class SurfaceControl implements Parcelable
public static class Builder
private SurfaceSession mSession;
public SurfaceControl build()
return new SurfaceControl(mSession, mName, mWidth, mHeight,...);
//native 的 SurfaceControl 对象引用地址
public long mNativeObject;
//空实现
public SurfaceControl()
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
String callsite) ...
...
//关键代码
mNativeObject = nativeCreate(session, name, w, h, format, flags,
parent != null ? parent.mNativeObject : 0, metaParcel);
...
//native方法,实际创建了native层的Surface
private static native long nativeCreate(SurfaceSession session, ... ) ...;
private static native long nativeCopyFromSurfaceControl(long nativeObject);
private static native long nativeGetHandle(long nativeObject);
public void copyFrom(@NonNull SurfaceControl other, String callsite)
...
//实际是复制了这个mNativeObject对象引用
assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite);
private void assignNativeObject(long nativeObject, String callsite)
...
mNativeObject = nativeObject;
mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0;
native层 SurfaceControl创建
// ========== 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, jlong parentObject,
jobject metadataParcel)
...
sp<SurfaceComposerClient> client;
if (sessionObj != NULL)
//SurfaceSession不为空的情况,也就是前面建立连接时创建的SurfaceComposerClient
client = android_view_SurfaceSession_getClient(env, sessionObj);
else
client = SurfaceComposerClient::getDefault();
SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
sp<SurfaceControl> surface;
LayerMetadata metadata;
Parcel* parcel = parcelForJavaObject(env, metadataParcel);
if (parcel && !parcel->objectsCount())
status_t err = metadata.readFromParcel(parcel);
...
//通过SurfaceComposerClient创建native SurfaceControl
status_t err = client->createSurfaceChecked(
String8(name.c_str()), w, h, format, &surface, flags, parent, std::move(metadata));
...
surface->incStrong((void *)nativeCreate);
return reinterpret_cast<jlong>(surface.get());
// =========== frameworks/base/core/jni/android_view_SurfaceSession.cpp =================
sp<SurfaceComposerClient> android_view_SurfaceSession_getClient(
JNIEnv* env, jobject surfaceSessionObj)
return reinterpret_cast<SurfaceComposerClient*>(
env->GetLongField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient));
其内部是返回了一个native的SurfaceControl
对象引用地址。
随后通过SurfaceComposerClient.createSurfaceChecked
创建这个native层的SurfaceControl
对象
// ================= frameworks/native/libs/gui/SurfaceComposerClient.cpp ===================
sp<ISurfaceComposerClient> mClient;
status_t SurfaceComposerClient::createSurfaceChecked(...,
sp<SurfaceControl>* outSurface, ...,
SurfaceControl* parent, LayerMetadata metadata,
...)
sp<SurfaceControl> sur;
status_t err = mStatus;
...
if (mStatus == NO_ERROR)
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
...
// 跨进程Binder代理调用Client的createSurface方法,
// 内部并最终调用到SurfaceFlinger.createLayer,创建Layer
// 传入了两个代理类对象引用
err = mClient->createSurface(...&handle,&gbp,...);
if (outTransformHint)
*outTransformHint = transformHint;
...
if (err == NO_ERROR)
//创建一个新的SurfaceControl对象,并将引用赋值给外部传入的SurfaceControl
*outSurface = new SurfaceControl(this, handle, gbp, transformHint);
return err;
Client.createSurface
最终会调用到SurfaceFlinger.createLayer
方法创建Layer
。Layer
是SurfaceFlinger
的基本操作单元。
// =========== frameworks/native/services/surfaceflinger/Client.cpp ==================
sp<SurfaceFlinger> mFlinger;
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, uint32_t* outTransformHint)
// We rely on createLayer to check permissions.
return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
parentHandle, nullptr, outTransformHint);
// ================== frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp ==================
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,
uint32_t* outTransformHint)
status_t result = NO_ERROR;
sp<Layer> layer;
//根据flags创建不同的Layer
switch (flags & ISurfaceComposerClient::eFXSurfaceMask)
case ISurfaceComposerClient::eFXSurfaceBufferQueue:
//常用的BufferQueueLayer
result = createBufferQueueLayer(client, std::move(uniqueName), w, h, flags,
std::move(metadata), format, handle, gbp, &layer);
break;
//还有好几种Layer
...
...
//保存新创建的Layer
mInterceptor->saveSurfaceCreation(layer);
return result;
// ================ frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp ==================
status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, std::string name,
uint32_t w, uint32_t h, uint32_t flags,
LayerMetadata metadata, PixelFormat& format,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp,
sp<Layer>* outLayer)
sp<BufferQueueLayer> layer;
...
//通过工厂模式创建BufferQueueLayer
layer = getFactory().createBufferQueueLayer(args);
...
//设置一些Layer内部的属性
status_t err = layer->setDefaultBufferProperties(w, h, format);
if (err == NO_ERROR)
// 注意这两个对象引用,是会传到外部SurfaceControl构造函数的
*handle = layer->getHandle();
*gbp = layer->getProducer();
*outLayer = layer;
return err;
在SurfaceFlinger
创建出Layer
后,引出了 IGraphicBufferProducer
和IBinder
的代理类,并传入到SurfaceControl
的构造函数。
// =========== frameworks/native/libs/gui/SurfaceControl.cpp ===============
SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbp,
uint32_t transform)
: mClient(client),
mHandle(handle),
mGraphicBufferProducer(gbp),
mTransformHint(transform)
也就是说SurfaceFlinger
中创建的Layer
是通过其内部的Producer代理对象和Handle代理对象,与SurfaceControl
进行关联。
就以此为切入点,来看下getProducer
和getHandle
究竟获取到了什么?
// ========= frameworks/native/services/surfaceflinger/Layer.cpp =================
sp<IBinder> Layer::getHandle()
...
return new Handle(mFlinger, this);
class Handle : public BBinder, public LayerCleaner
public:
Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
: LayerCleaner(flinger, layer), owner(layer)
wp<Layer> owner;
;
// ============== frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp =================
sp<IGraphicBufferProducer> BufferQueueLayer::getProducer() const
return mProducer;
getHandle
是新创建了一个Handle
对象,属于BBinder
实现类,内部包含了SurfaceFlinger
和Layer
的引用,作为Surface
操作Layer
句柄类。
那getProducer
返回的内部对象引用又是什么呢?我们继续来看其构造函数
BufferQueueLayer
是继承自BufferLayer
,BufferLayer
继承自Layer
。Layer
又是继承自RefBase
。
// ============= frameworks/native/services/surfaceflinger/BufferQueueLayer.h ==============
class BufferQueueLayer : public BufferLayer
private
sp<IGraphicBufferProducer> mProducer;
...
// ============== frameworks/native/services/surfaceflinger/BufferLayer.h ============
class BufferLayer : public Layer
...
// ============== frameworks/native/services/surfaceflinger/Layer.h ================
class Layer : public virtual RefBase, compositionengine::LayerFE
...
// ============== frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp ================
void BufferQueueLayer::onFirstRef()
BufferLayer::onFirstRef();
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
//创建了一个生产者和消费者模型,
sp<IGraphicBufferProducer> producer; //生产者缓冲区
sp<IGraphicBufferConsumer> consumer; //消费者缓冲区
//创建了一个BufferQueueCore管理BufferQueue队列,并以此为核心创建赋值生产者与消费者
mFlinger->getFactory().createBufferQueue(&producer, &consumer, true);
mProducer = mFlinger->getFactory().createMonitoredProducer(producer, mFlinger, this);
mConsumer = mFlinger->getFactory().createBufferLayerConsumer(consumer, mFlinger->getRenderEngine(),
mTextureName, this);
...
// BufferQueueCore::mMaxDequeuedBufferCount is default to 1
if (!mFlinger->isLayerTripleBufferingDisabled())
//如果没有开启3级缓冲区,则设置为2级缓冲区
mProducer->setMaxDequeuedBufferCount(2);
既然是RefBase
的子类,在第一次获取到强引用时就会触发onFirstRef
方法,其在内部创建了一个基于BufferQueue
的生产者与消费者模型。
而通过getProducer
方法获取到的正是其作为生产者BufferQueueProducer
,用于从BufferQueueCore
中获取图像缓冲区buffer
对象,交由客户端写入显示内容。
// ============ frameworks/native/libs/gui/BufferQueue.cpp ===============
// getFactory().createBufferQueue
// 最终会调用到BufferQueue.createBufferQueue方法
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
bool consumerIsSurfaceFlinger)
LOG_ALWAYS_FATAL_IF(outProducer == nullptr,
"BufferQueue: outProducer must not be NULL");
LOG_ALWAYS_FATAL_IF(outConsumer == nullptr,
"BufferQueue: outConsumer must not be NULL");
//图形缓冲区队列的中枢类
sp<BufferQueueCore> core(new BufferQueueCore());
...
//用core类创建生产者,用于从队列中获取缓冲区并写入绘制内容
//返回为Binder代理类
sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));
...
//用core类创建消费者,用于从队列中获取缓冲区数据,并交由Surfaceflinger处理
//返回为Binder代理类
sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
...
*outProducer = producer;
*outConsumer = consumer;
至此,native层SurfaceControl
创建就出来了,通过BufferQueueProducer
的Binder代理类,和SurfaceFlinger
创建的Layer
进行关联。
并最终将native层的SurfaceControl
对象引用,赋值给java层的SurfaceControl
。
java层 Surface创建
接下来就是通过Surface.copyFrom
对这个新的SurfaceControl
拷贝出可用的Surface
了。
// ============= android.view.Surface ================
public class Surface implements Parcelable
long mNativeObject; // package scope only for SurfaceControl access
private static native long nativeGetFromSurfaceControl(long surfaceObject,
long surfaceControlNativeObject);
private static native void nativeRelease(long nativeObject);
public void copyFrom(SurfaceControl other)
...
long surfaceControlPtr = other.mNativeObject;
...
//从SurfaceControl内创建Surface
long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
synchronized (mLock)
if (newNativeObject == mNativeObject)
return;
if (mNativeObject != 0)
nativeRelease(mNativeObject);
setNativeObjectLocked(newNativeObject);
private void setNativeObjectLocked(long ptr)
if (mNativeObject != ptr)
...
mNativeObject = ptr;
mGenerationId += 1;
if (mHwuiContext != null)
mHwuiContext.updateSurface();
native层 Surface创建
在Surface.copyFrom
方法内,同样也是通过native方法,赋值native对象引用地址。
通过调用native层的SurfaceControl.generateSurfaceLocked
方法创建了native层的Surface
。
然后将native层Surface
的对象引用指针,赋值给java层Surface
的mNativeObject
。
// ============== frameworks/base/core/jni/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()))
//实际持有的Producer代理对象是同一个,不做任何处理
return nativeObject;
//通过SurfaceControl创建native层的Surface
sp<Surface> surface(ctrl->getSurface());
if (surface != NULL)
surface->incStrong(&sRefBaseOwner);
//返回native层surface对象的引用地址
return reinterpret_cast<jlong>(surface.get());
// =========== frameworks/native/libs/gui/SurfaceControl.cpp ==================
mutable sp<Surface> mSurfaceData;
sp<Surface> SurfaceControl::getSurface() const
Mutex::Autolock _l(mLock);
if (mSurfaceData == nullptr)
return generateSurfaceLocked();
return mSurfaceData;
sp<Surface> SurfaceControl::generateSurfaceLocked() const
// mGraphicBufferProducer就是Layer的中图形缓冲区域对应的生产者
// 创建native层的Surface
mSurfaceData = new Surface(mGraphicBufferProducer, false);
return mSurfaceData;
至此,ViewRootImpl
内持有的Suface
就转变为可用状态,并指向正确的native层Surface
对象引用,进而关联到SurfaceFlinger
创建的BufferQueue
。
最后来简要概括一下Surface
创建的过程
-
首先由
ViewRootImpl.requestLayout
通过Choreographer
向native申请Vsync
同步信号。 -
App进程的
Choreographer
接收到Vsync
同步信号后,通过SurfaceControl
内部创建并持有对应的native层SurfaceControl
对象引用地址。 -
在native层 中用
SurfaceSession
中持有的SurfaceComposerClient
通过Binder跨进程调用,在SurfaceFlinger
进程内中创建一个独立的,基于BufferQueue
的生产者消费者模型。在native层
SurfaceControl
创建时,会将BufferQueue
的生产者Producer
的Binder代理类对象赋值给其内部变量。 -
由java层
Surface.copyFrom
藉由native层SurfaceControl
创建native层的Surface
对象,后者持有来自native层SurfaceControl
的Producer
的对象引用。native层
SurfaceControl
内部会缓存native层Surface
到内部变量引用,只会在第一次获取时创建。将该native层
Surface
对象引用地址赋值给jave层的Surface
对象,使后者指向正确对象引用地址。java层的
Surface
和SurfaceControl
都是空壳,实际做事的都是native层的Surface
和SurfaceControl
。
以上是关于Surface的理解的主要内容,如果未能解决你的问题,请参考以下文章
深入Android系统Android图形显示系统-1-显示原理与Surface