Surface系统概述

news/2024/11/15 1:42:47/

一、前言

​ 对于应用开发者来说,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系统


http://www.ppmy.cn/news/522296.html

相关文章

windows 8 Surface 会成功吗?

Surface 会成功吗&#xff1f; Windows RT 的目标是在平板领域上挑战苹果 iOS 系统&#xff0c;但就目前来看还缺乏俘获消费者芳心的杀手级应用&#xff0c;无论时游戏还是办公应用都没有几个应用可以真正让消费者眼前一亮。 至于售价呢&#xff0c;美国价格为 32GB 的 Surface…

Microsoft Surface

Microsoft Surface&#xff0c;微软的第一款平面电脑&#xff0c;没有鼠标键盘&#xff0c;通过触摸等方式来进行交互&#xff0c;走入一种新的人和信息之间的交互方式。 具体了解可以看一下这篇文章: http://www.hi-id.com/?p1165 Surface视频展示&#xff1a; http://www.p…

Surface 之父 Panos Panay 加入微软高级领导层,Windows 重整旗鼓!

众所周知&#xff0c;微软起家靠的是 Windows 的崛起。在 Windows 的逐代更新中&#xff0c;微软也将其生态从操作系统拓展到软件、硬件、云计算、人工智能等多个领域&#xff0c;然而当围绕数字化为核心的第四次工业革命正式打响之际&#xff0c;微软为加快自身数字化转型的步…

让我们走近 Microsoft Surface

让我们走近 Microsoft Surface 最近在研究 Mulit Touch 的时候发现了它&#xff0c;so cool &#xff0c;找找相关资料转载下。 每当我们在讨论多点触摸的用户界面该如何设计时&#xff0c;往往会不由自主地谈到iPhone/iPad。很多时候&#xff0c;我们会忽略另外一个同样使用多…

Surface Computing

Surface Computing在学术界里已经研究了良久&#xff0c;最让人震撼的是MIT天才学生&#xff08;来自印度&#xff09;的那个介绍自己作品的视频&#xff08;链接&#xff09;。Surface Computing其实是一种新的人机交互范式&#xff0c;撇开了传统的人机交互设备&#xff1a;鼠…

StyleRig: Rigging StyleGAN for 3D Control over Portrait Images(CVPR20 oral)

4. Semantic Rig Parameters 使用parametric face model对人脸建模based on a set of semantic control parameters p ( α , β , δ , R , t ) ∈ R 257 \mathbf{p}\left ( \alpha, \beta, \delta, \mathbf{R}, \mathbf{t} \right )\in \mathbb{R}^{257} p(α,β,δ,R,t)∈…

无线防丢器设计

目录 一、方案流程及技术规格书设计 二、系统硬件电路设计 三、软件编写及调试 四、系统调试测试与分析 前言 为了解决重要物品丢失或遗忘的问题&#xff0c;达到找到丢失或遗忘的重要物品和报警提示&#xff0c;防止重要物品丢失或遗忘的目的&#xff0c;提出一种基于无线…

霍尔电流传感器

霍尔电流传感器的功耗计算以及开环霍尔比闭环霍尔带宽低的原理&#xff0c;以及运放的输入阻抗对霍尔的影响 目录 1.霍尔工作原理 2.功耗分析 3.开环带宽和闭环带宽 4.运放的输入阻抗 1.霍尔工作原理 &#xff1a;如下图 由上图可得&#xff0c;霍尔是恒流源输出。 2.功…