一、前言
对于应用开发者来说,Android的界面以及各种UI元素都是通过View以及系统组件来显示的,那么在系统层面,我们写的View是怎么绘制到显示屏幕上的呢?
我们知道SurfaceView是一种比较特殊的View,它包含有自己的Surface,我们今天就从SurfaceView入手来分析一下图形系统的大体轮廓。
本文是基于Android10来分析,相信后续的版本不会有太大的变动。在分析过程中会省略一些异常处理或者与分析无关的代码,使流程更加清晰。
二、Surface的创建
先放一张整体结构图,然后我们进行分析
2.1、SurfaceView
我们已经知道SurfaceView的基础绘制方式:
public void surfaceCreated(@NonNull SurfaceHolder holder) {Surface surface = holder.getSurface();Canvas canvas = surface.lockCanvas(new Rect(0, 0, 2, 2));//draw something...surface.unlockCanvasAndPost(canvas);
}
这里通过SurfaceHolder拿到的Surface,正是在SurfaceView中获取到的。也就是说拿到Surface之后,我们可以通过Surface获取一张画布,然后可以在上面绘制内容,在unlock方法调用之后绘制的内容就会被系统显示在显示屏幕上面。接下来我们看下SurfaceView中Surface的使用过程
final Surface mSurface = new Surface(); // Current surface in useprotected void updateSurface() {//...if (creating) {mSurface.copyFrom(mSurfaceControl);}//...
}SurfaceControl mSurfaceControl;
mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession).setName(name).setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0).setBufferSize(mSurfaceWidth, mSurfaceHeight).setFormat(mFormat).setParent(viewRoot.getSurfaceControl()).setFlags(mSurfaceFlags).build();SurfaceSession mSurfaceSession;
mSurfaceSession = new SurfaceSession();
我们只摘抄了Surface初始化的过程,我们看下Surface在Java层的代码,可以看到在Java层只有接口,具体的操作都是调用Native的接口,copyFrom方法如下:
public void copyFrom(SurfaceControl other) {//...long surfaceControlPtr = other.mNativeObject;long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);synchronized (mLock) {if (mNativeObject != 0) {nativeRelease(mNativeObject);}setNativeObjectLocked(newNativeObject);}
}
Surface的创建与SurfaceControl密不可分,从名字也可以看出来SurfaceControl正是对Surface的控制逻辑,我们接着向下分析,先看一下SurfaceControl的逻辑
2.2 SurfaceControl的初始化
SurfaceControl的初始化用到了建造者模式,主要是设置一些显示的元数据,比如透明度、需要显示的区域尺寸、以及Format等,我们看一下build方法:
public SurfaceControl build() {return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata);
}
这里的mSession是刚才构造的SurfaceSession,直接传进来。
进入了SurfaceControl的构造方法:
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,SurfaceControl parent, SparseIntArray metadata){//...mName = name;mWidth = w;mHeight = h;try {mNativeObject = nativeCreate(session, name, w, h, format, flags,parent != null ? parent.mNativeObject : 0, metaParcel);}//...mCloseGuard.open("release");
}
直接调用native方法来初始化,然后保存在mNativeObject中,这是AndroidFramework中随处可见的一种手段,往往使用一个long型来存储Native层对象的指针,可以通过Java Object来传递对象,然后在Native层需要使用的时候,直接将指针地址强制转换成对应的对象。我们看下Native层的逻辑:
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) {ScopedUtfChars name(env, nameStr);sp<SurfaceComposerClient> client;if (sessionObj != NULL) {client = android_view_SurfaceSession_getClient(env, sessionObj);} else {client = SurfaceComposerClient::getDefault();}SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);sp<SurfaceControl> surface;//...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());
}
这里引入一个结构体,叫做SurfaceComposerClient,sessionObj不为空,所以进入android_view_SurfaceSession_getClient:
sp<SurfaceComposerClient> android_view_SurfaceSession_getClient(JNIEnv* env, jobject surfaceSessionObj) {return reinterpret_cast<SurfaceComposerClient*>(env- >GetLongField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient));
}
根据2.3我们可以知道,这里获取到的是之前初始化的SurfaceComposerClient,接下来就是进入createSurfaceChecked,我们首先看下SurfaceComposerClient,进入2.4
2.3 SurfaceSession的初始化
public SurfaceSession() {mNativeClient = nativeCreate();
}
依然是直接进入native方法:
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);
}
初始化一个SurfaceComposerClient对象,并添加引用计数,然后返回给Java层
2.4 SurfaceComposerClient创建
frameworks\native\libs\gui\SurfaceComposerClient.cpp
class SurfaceComposerClient : public RefBase
SurfaceComposerClient继承自RefBase,这是Android Framework中使用的一种智能指针,使用引用计数,第一次调用的时候会回调onFirstRef方法:
void SurfaceComposerClient::onFirstRef() {sp<ISurfaceComposer> sf(ComposerService::getComposerService());if (sf != nullptr && mStatus == NO_INIT) {sp<ISurfaceComposerClient> conn;conn = sf->createConnection();if (conn != nullptr) {mClient = conn;mStatus = NO_ERROR;}}
}
首先获取ComposerService做为ISurfaceComposer,然后使用createConnection方法建立连接:
sp<ISurfaceComposer> ComposerService::getComposerService() {ComposerService& instance = ComposerService::getInstance();Mutex::Autolock _l(instance.mLock);if (instance.mComposerService == nullptr) {ComposerService::getInstance().connectLocked();assert(instance.mComposerService != nullptr);ALOGD("ComposerService reconnected");}return instance.mComposerService;
}
ComposerService是一个单例,第一次获取的时候会调用connectLocked,这个方法在SurfaceComposerClient中重写:
void ComposerService::connectLocked() {const String16 name("SurfaceFlinger");while (getService(name, &mComposerService) != NO_ERROR) {usleep(250000);}//...
}
mComposerService是通过getService获取的,也就是SurfaceFlinger,这里是通过ServiceManger来获取系统服务的过程,是一次Binder通信,最终获取到的是SurfaceFlinger在应用程序侧的Binder代理,类型为ISurfaceComposer:
frameworks\native\libs\gui\include\gui\ISurfaceComposer.h
frameworks\native\libs\gui\ISurfaceComposer.cpp
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
class BnSurfaceComposer: public BnInterface<ISurfaceComposer>
我们拿到的是BpSurfaceComposer对象,BnSurfaceComposer运行在服务端(这里是SurfaceFlinger)。拿到代理对象之后,接下来就是createConnection:
virtual sp<ISurfaceComposerClient> createConnection()
{Parcel data, reply;data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
}
是一次Binder调用,对端实现:
status_t BnSurfaceComposer::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{switch(code) {case CREATE_CONNECTION: {CHECK_INTERFACE(ISurfaceComposer, data, reply);sp<IBinder> b = IInterface::asBinder(createConnection());reply->writeStrongBinder(b);return NO_ERROR;}}
}
createConnection在SurfaceFlinger中实现:
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
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;
}
初始化一个Client对象:
class Client : public BnSurfaceComposerClient
Client继承自BnSurfaceComposerClient,也就是说,通过这次Binder调用,我们在应用侧获取到了
SurfaceComposerClient的Binder代理,也就是BpSurfaceComposerClient:
frameworks\native\libs\gui\ISurfaceComposerClient.cpp
class BpSurfaceComposerClient : public SafeBpInterface<ISurfaceComposerClient>
SurfaceComposerClient接下来所有的操作都由BpSurfaceComposerClient经Binder调用转发给Client来处理,也即Client与SurfaceFlinger创建了一条连接
2.5 SurfaceControl创建完成
获取到SurfaceComposerClient之后,我们回到SurfaceControl的初始化,接下来是createSurfaceChecked:
frameworks\native\libs\gui\SurfaceComposerClient.cpp
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();}err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),&handle, &gbp);if (err == NO_ERROR) {*outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);}}return err;
}
这里的mClient正是之前获取到的BpSurfaceComposerClient,调用createSurface方法:
status_t createSurface(const String8& name, uint32_t width, uint32_t height, PixelFormat format,uint32_t flags, const sp<IBinder>& parent, LayerMetadata metadata,sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) override
{return callRemote<decltype(&ISurfaceComposerClient::createSurface)>(Tag::CREATE_SURFACE,name, width, height,format, flags, parent,std::move(metadata),handle, gbp);
}
通过Binder调用,进入:
status_t BnSurfaceComposerClient::onTransact(uint32_t code, const Parcel& data, Parcel* reply,uint32_t flags) {switch (tag) {case Tag::CREATE_SURFACE:return callLocal(data, reply, &ISurfaceComposerClient::createSurface);}
}
实现在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.return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,parentHandle);
}
进入SurfaceFlinger的createLayer方法:
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) {status_t result = NO_ERROR;sp<Layer> layer;switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {case ISurfaceComposerClient::eFXSurfaceBufferQueue:result = createBufferQueueLayer(client, uniqueName, w, h, flags, std::move(metadata),format, handle, gbp, &layer);break;}result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,addToCurrentState);mInterceptor->saveSurfaceCreation(layer);setTransactionFlags(eTransactionNeeded);return result;
}
flags的值是SurfaceView中设置的,目前我们视为eOpaque,也就是不透明,与eFXSurfaceMask执行And操作之后,case为ISurfaceComposerClient::eFXSurfaceBufferQueue
enum { // (keep in sync with Surface.java)eHidden = 0x00000004,eDestroyBackbuffer = 0x00000020,eSecure = 0x00000080,eOpaque = 0x00000400,eProtectedByApp = 0x00000800,eProtectedByDRM = 0x00001000,eFXSurfaceBufferQueue = 0x00000000,eFXSurfaceColor = 0x00020000,eFXSurfaceBufferState = 0x00040000,eFXSurfaceContainer = 0x00080000,eFXSurfaceMask = 0x000F0000,
};
然后是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) {sp<BufferQueueLayer> layer = getFactory().createBufferQueueLayer(LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)));status_t err = layer->setDefaultBufferProperties(w, h, format);if (err == NO_ERROR) {*handle = layer->getHandle();*gbp = layer->getProducer();*outLayer = layer;}return err;
}
handle、gbp都是我们传进来的引用,最终都会保存在SurfaceControl里面,layer的创建可见2.6,我们现在返回SurfaceControl的创建,通过对SurfaceFlinger的调用,我们拿到了handle与gbp,其中handle是Layer的引用,而Layer是SurfaceFlinger侧与Surface对应的对象,gbp类型是IGraphicBufferProducer,我们在2.7分析。至此SurfaceControl创建就结束了。
2.6 Layer的创建
接上文,Layer的创建是通过SurfaceFlinger的createBufferQueueLayer方法:
getFactory().createBufferQueueLayer(LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)))
getFactory最终调用到SurfaceFlingerFactory中:
frameworks\native\services\surfaceflinger\SurfaceFlingerFactory.cpp
sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) override {return new BufferQueueLayer(args);
}
新建BufferQueueLayer对象:
frameworks\native\services\surfaceflinger\BufferLayer.cpp
BufferQueueLayer的构造函数:
BufferLayer::BufferLayer(const LayerCreationArgs& args): Layer(args),mTextureName(args.flinger->getNewTexture()),mCompositionLayer{mFlinger->getCompositionEngine().createLayer(compositionengine::LayerCreationArgs{this})} {mPremultipliedAlpha = !(args.flags & ISurfaceComposerClient::eNonPremultiplied);mPotentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;mProtectedByApp = args.flags & ISurfaceComposerClient::eProtectedByApp;
}
BufferLayer也是继承自RefBase,所以看下onFirstRef方法:
void BufferQueueLayer::onFirstRef() {BufferLayer::onFirstRef();// Creates a custom BufferQueue for SurfaceFlingerConsumer to usesp<IGraphicBufferProducer> producer;sp<IGraphicBufferConsumer> consumer;BufferQueue::createBufferQueue(&producer, &consumer, true);mProducer = new MonitoredProducer(producer, mFlinger, this);{// Grab the SF state lock during this since it's the only safe way to access RenderEngineMutex::Autolock lock(mFlinger->mStateLock);mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this);}// BufferQueueCore::mMaxDequeuedBufferCount is default to 1if (!mFlinger->isLayerTripleBufferingDisabled()) {mProducer->setMaxDequeuedBufferCount(2);}if (const auto display = mFlinger->getDefaultDisplayDevice()) {updateTransformHint(display);}
}
建立了两个引用,一个是IGraphicBufferProducer,一个是IGraphicBufferConsumer,从名字就可以看出来是生产消费者模式,然后调用BufferQueue::createBufferQueue方法:
frameworks\native\libs\gui\BufferQueue.cpp
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;
}
使用BufferQueueCore初始化了两个传入的引用,分别为BufferQueueProducer和BufferQueueConsumer,见2.8,初始化生产者消费者之后,做了一层代理,然后保存在mProducer和mConsumer中,而getProducer也就是我们通过Layer调用getProducer返回给SurfaceControl的gbp(见2.5)。
2.7 IGraphicBufferProducer与IGraphicBufferConsumer
IGraphicBufferProducer与IGraphicBufferConsumer是GraphicBuffer的生产者与消费者,
IGraphicBufferProducer被SurfaceControl持有,IGraphicBufferConsumer被Layer持有。
2.8 Surface的创建
由于SurfaceControl已经建立完毕了,我们回头分析copyFrom方法:
public void copyFrom(SurfaceControl other) {//...long surfaceControlPtr = other.mNativeObject;long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);synchronized (mLock) {if (mNativeObject != 0) {nativeRelease(mNativeObject);}setNativeObjectLocked(newNativeObject);}
}
首先是从SurfaceControl中获取Native层的Surface对象:
frameworks\base\core\jni\android_view_Surface.cpp
static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,jlong nativeObject,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());
}
第一次获取,直接调用SurfaceControl.getSurface:
frameworks\native\libs\gui\SurfaceControl.cpp
sp<Surface> SurfaceControl::getSurface() const
{Mutex::Autolock _l(mLock);if (mSurfaceData == nullptr) {return generateSurfaceLocked();}return mSurfaceData;
}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,mGraphicBufferProducer正是我们之前从SurfaceFlinger拿到的gbp,使用mGraphicBufferProducer创建Surface对象之后就代表Native层的Surface对象也创建完毕了。
2.9 Native层Surface的构造函数
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>()) {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;//...
}
ANativeWindow是OpenGL的窗口类,这里注册了一些OpenGL的回调,当OpenGL的回调函数回调的时候,Surface中对应的钩子函数就会调用相关的函数,用于和SurfaceFlinger的交互。
2.10 初始化结束
分析到这里,代表我们的Surface初始化完成,与SurfaceFlinger的连接也建立好了,用一张图简单概括一下
2.11 类结构图
Client与Server建立连接:
Surface与Layer对应关系:
三、绘制过程
Surface初始化完毕,我们也可以使用Surface来绘图了,回到SurfaceView的绘制方法:
public void surfaceCreated(@NonNull SurfaceHolder holder) {Surface surface = holder.getSurface();Canvas canvas = surface.lockCanvas(new Rect(0, 0, 2, 2));//draw something...surface.unlockCanvasAndPost(canvas);
}
首先是通过lockCanvas获取一个Canvas,也就是获得一张画布,然后在画布上面绘制内容,最终unlock来提交绘制内容。我们从lockcanvas开始:
3.1 lockCanvas
public Canvas lockCanvas(Rect inOutDirty)throws Surface.OutOfResourcesException, IllegalArgumentException {synchronized (mLock) {mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);return mCanvas;}
}
进入nativeLockCanvas:
static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));Rect dirtyRect(Rect::EMPTY_RECT);Rect* dirtyRectPtr = NULL;//... init dirtyRectANativeWindow_Buffer outBuffer;status_t err = surface->lock(&outBuffer, dirtyRectPtr);SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,convertPixelFormat(outBuffer.format),outBuffer.format == PIXEL_FORMAT_RGBX_8888? kOpaque_SkAlphaType : kPremul_SkAlphaType);SkBitmap bitmap;ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);bitmap.setInfo(info, bpr);if (outBuffer.width > 0 && outBuffer.height > 0) {bitmap.setPixels(outBuffer.bits);}Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);nativeCanvas->setBitmap(bitmap);// Create another reference to the surface and return it. This reference// should be passed to nativeUnlockCanvasAndPost in place of mNativeObject,// because the latter could be replaced while the surface is locked.sp<Surface> lockedSurface(surface);lockedSurface->incStrong(&sRefBaseOwner);return (jlong) lockedSurface.get();
}
1)获取Java层对应的Native Surface对象 2)通过Surface的lock方法获取一段内存,保存在outBuffer中 3)初始化一个SkBitmap对象,然后将获取到的内存设置为SkBitmap的内容 4)获取Native层的Canvas,Java层对应的Canvas是Surface中初始化的,然后将刚才创建的SkBitmap对象设置给Canvas,最后返回对应的Surface并修改引用计数。
首先我们看lock函数:
3.1.1 Surface::lock
frameworks\native\libs\gui\Surface.cpp
status_t Surface::lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
{ANativeWindowBuffer* out;int fenceFd = -1;status_t err = dequeueBuffer(&out, &fenceFd);if (err == NO_ERROR) {sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));const Rect bounds(backBuffer->width, backBuffer->height);void* vaddr;status_t res = backBuffer->lockAsync(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,newDirtyRegion.bounds(), &vaddr, fenceFd);if (res != 0) {err = INVALID_OPERATION;} else {mLockedBuffer = backBuffer;outBuffer->width = backBuffer->width;outBuffer->height = backBuffer->height;outBuffer->stride = backBuffer->stride;outBuffer->format = backBuffer->format;outBuffer->bits = vaddr;}}return err;
}
首先是dequeueBuffer:
3.1.2 Surface::dequeueBuffer
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {int buf = -1;sp<Fence> fence;nsecs_t startTime = systemTime();status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,reqFormat, reqUsage, &mBufferAge,enableFrameTimestamps ? &frameTimestamps
:nullptr);sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);if (fence->isValid()) {*fenceFd = fence->dup();} else {*fenceFd = -1;}*buffer = gbuf.get();if (mSharedBufferMode && mAutoRefresh) {mSharedBufferSlot = buf;mSharedBufferHasBeenQueued = false;}return OK;
}
直接调用到mGraphicBufferProducer的dequeueBuffer方法,我们已经知道这里最终会调用到SurfaceFlinger的GraphicBufferConsumer中去。进入GraphicBufferProducer之后,是一套比较复杂的生产者消费者模式,大概模式是:有一个BufferQueueCore维护一些Buffer与Slot,GraphicBufferProducer获取一些Buffer(也即这里通过dequeueBuffer获取到的Buffer),然后将其标记为Active,后面GraphicBufferConsumer会通过acquireBuffer来使用这些Buffer。具体的流程由于篇幅问题,这里不再展开。
回到3.1.1,获取到Buffer之后,经过GraphicBuffer::getSelf强制类型转换,就变成了GraphicBuffer类型。接着,调用GraphicBuffer的lockAsync方法:
status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage,const Rect& rect, void** vaddr, int fenceFd,int32_t* outBytesPerPixel, int32_t* outBytesPerStride) {status_t res = getBufferMapper().lockAsync(handle, inProducerUsage, inConsumerUsage, rect,vaddr, fenceFd, outBytesPerPixel, outBytesPerStride);return res;
}
经过几次辗转,最终会调用getBufferMapper的lockAsync方法,这里的getBufferMapper最终会调用到Gralloc模块中,它的做用是做一次内存映射,将在SurfaceFlinger服务中获取到的内存映射到应用程序的内存空间中,到这里,我们就可以对这块内存做出修改了,在SurfaceFlinger也可以观测到内存的变化,从而达到绘制的目的。
3.2 Canvas绘制
Canvas绘制的过程我们这里就不做详细描述了,只需要知道Canvas的绘制其实就是修改之前获取到的内存中的内容即可
3.3 unlockCanvasAndPost
先看下Java代码:
public void unlockCanvasAndPost(Canvas canvas) {synchronized (mLock) {unlockSwCanvasAndPost(canvas);}
}private void unlockSwCanvasAndPost(Canvas canvas) {try {nativeUnlockCanvasAndPost(mLockedObject, canvas);} finally {nativeRelease(mLockedObject);mLockedObject = 0;}
}
依然是直接调用native方法:
static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz,jlong nativeObject, jobject canvasObj) {sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));// detach the canvas from the surfaceCanvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);nativeCanvas->setBitmap(SkBitmap());// unlock surfacestatus_t err = surface->unlockAndPost();if (err < 0) {doThrowIAE(env);}
}
接着到Surface的unlockAndPost方法:
3.3.1 Surface::unlockAndPost
status_t Surface::unlockAndPost()
{int fd = -1;status_t err = mLockedBuffer->unlockAsync(&fd);err = queueBuffer(mLockedBuffer.get(), fd);mPostedBuffer = mLockedBuffer;mLockedBuffer = nullptr;return err;
}
首先是释放刚才获取的mLockedBuffer,然后将mLockedBuffer重新加入队列,代表这块Buffer其他地方可以使用了。
3.3.2 GraphicBuffer::unlockAsync
status_t GraphicBuffer::unlockAsync(int *fenceFd)
{status_t res = getBufferMapper().unlockAsync(handle, fenceFd);return res;
}
归还之前使用的Buffer
3.3.3 queueBuffer
int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { //... sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); IGraphicBufferProducer::QueueBufferOutput output;IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp, static_cast<android_dataspace>(mDataSpace), crop, mScalingMode,mTransform^mSticky,Transform,fence,mStickyTransform,mEnableFrameTimestamps); status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);//...
}
SurfacequeueBuffer的方法最终调用到GraphicBufferProducer的queueBuffer方法:
3.3.4 GraphicBufferProducer::queueBuffer
status_t BufferQueueProducer::queueBuffer(int slot, const QueueBufferInput &input, QueueBufferOutput *output) { sp<IConsumerListener> frameAvailableListener; sp<IConsumerListener> frameReplacedListener; int callbackTicket = 0; uint64_t currentFrameNumber = 0;BufferItem item; //...填充item int connectedApi; sp<Fence> lastQueuedFence; if (mCore->mQueue.empty()) { mCore->mQueue.push_back(item); frameAvailableListener = mCore->mConsumerListener; } {// scope for the lock std::unique_lock<std::mutex> lock(mCallbackMutex); while (callbackTicket != mCurrentCallbackTicket) { mCallbackCondition.wait(lock); } if (frameAvailableListener != nullptr) { frameAvailableListener->onFrameAvailable(item); } else if (frameReplacedListener != nullptr) { frameReplacedListener->onFrameReplaced(item); } mCallbackCondition.notify_all(); } // Wait without lock held if (connectedApi == NATIVE_WINDOW_API_EGL) { // Waiting here allows for two full buffers to be queued but not a // third. In the event that frames take varying time, this makes a // small trade-off in favor of latency rather than throughput. lastQueuedFence->waitForever("Throttling EGL Production"); } return NO_ERROR;
}
首先是构建一个BufferItem,并填充内容,里面包含UI元数据、buffer信息等,构建完了之后通过frameAvailableListener回调onFrameAvailable,代表这一帧可以绘制了,从上文可以看到,其中frameAvailableListener是从BufferQueueCore中获取,而BufferQueueCore中的mConsumerListener则是BufferQueueConsumer中获取到的,类型为ProxyConsumerListener.
继承关系如下图,最终BufferQueueLayer的onFrameAvailable方法被调用。
3.35 BufferQueueLayer::onFrameAvailable
void BufferQueueLayer::onFrameAvailable(const BufferItem& item) { //... mFlinger->mInterceptor->saveBufferUpdate(this, item.mGraphicBuffer->getWidth(), item.mGraphicBuffer->getHeight(), item.mFrameNumber); // If this layer is orphaned, then we run a fake vsync pulse so that // dequeueBuffer doesn't block indefinitely. if (isRemovedFromCurrentState()) { fakeVsync(); } else { mFlinger->signalLayerUpdate(); } mConsumer->onBufferAvailable(item);
}
调用mFlinger的signalLayerUpdate,从这里开始就进入SurfaceFlinger了,SurfaceFlinger中维护一个MessageQueue,在收到绘制的命令之后,会将图像缓冲区需要绘制的内容取出来,然后根据Z轴高度排列,最终绘制到屏幕上去。
3.4 数据传递总结
在应用侧的Surface与SurfaceFlinger建立连接之后,应用侧可以从SurfaceFlinger申请内存并映射到应用侧,然后可以对获取到的内存做绘制操作,在绘制完毕之后,释放相关的buffer并通知SurfaceFlinger,SurfaceFlinger收到回调之后开始混合,混合完毕之后渲染到实际的屏幕之上,也就是我们看到的UI。
四、总结
Surface系统是一个非常复杂的系统,涉及各种远程调用、内存分配,以及各种设计模式等,本文只是将Surface的初始化,以及与SurfaceFlinger建立连接的过程、数据的流向做了一个粗略的分析,并且略过了许多细节,子模块并没有涉及太多,以期对整个Surface系统有一个大概的认识。
五、参考
可以参考罗升阳与邓凡平分析Surface的一系列文章
1、Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析
2、Android应用程序与SurfaceFlinger服务的关系概述和学习计划
3、Android应用程序与SurfaceFlinger服务的连接过程分析
4、[深入理解Android卷一全文-第八章]深入理解Surface系统