一、前言
对于应用开发者来说,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 use
protected 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 use
sp<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 RenderEngine
Mutex::Autolock lock(mFlinger->mStateLock);
mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this);
}
// BufferQueueCore::mMaxDequeuedBufferCount is default to 1
if (!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 dirtyRect
ANativeWindow_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 surface
Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
nativeCanvas->setBitmap(SkBitmap());
// unlock surface
status_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系统有一个大概的认识。
五、参考
1、Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析
2、Android应用程序与SurfaceFlinger服务的关系概述和学习计划