1. Linux內核提供了統一的framebuffer顯示驅動,設備節點/dev/graphics/fb*或者/dev/fb*,以fb0表示第一個顯示屏,當前實現中只用到了一個顯示屏。
2. Android的HAL層提供了Gralloc,分為fb和gralloc兩個設備。設備fb負責打開內核中的framebuffer以及提供post、 setSwapInterval等操作,設備gralloc則負責管理幀緩沖區的分配和釋放。上層只能通過Gralloc訪問幀緩沖區,這樣一來就實現了 有序的封裝保護。
3. 由於OpenGL ES是一個通用的函數庫,在不同的平台系統上需要被“本地化”——即把它與具體平台上的窗口系統建立起關聯,這樣才能保證它正常工作。從FramebufferNativeWindow就是將OpenGL ES在Android平台上本地化窗口。
4. OpenGL或者OpenGL ES 更多的只是一個接口協議,實現上既可以采用軟件,也能依托於硬件。EGL通過讀取egl.cfg配置文件,根據用戶的設定來動態加載libagl(軟件實 現)或者libhgl(硬件實現)。然后上層才可以正常使用各種glXXX接口。
5. SurfaceFlinger中持有一個GraphicPlane成員變量mGraphicPlanes來描述“顯示屏”;GraphicPlane類中 又包含了一個DisplayHardware對象實例(mHw)。DisplayHardware在初始化時還將調用eglInitialize、 eglCreateWindowSurface等接口,並利用EGL完成對OpenGLES環境的搭建。
本地窗口
Android提供了兩種本地窗口:
1) 面向SurfaceFlinger的FramebufferNativeWindow;
2) 面向應用程序的SurfaceTextureClient;
使用OpenGL繪制圖像前,需要通過EGL創建一個Surface畫板:
frameworks\native\opengl\libagl\ Egl.cpp
- EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
- NativeWindowType window,
- const EGLint *attrib_list)
- {
- return createWindowSurface(dpy, config, window, attrib_list);
- }
OpenGL是跨平台的圖形庫,不同平台上的NativeWindowType窗口類型有不同的定義:
frameworks\native\opengl\include\egl\ Eglplatform.h
- typedef EGLNativeWindowType NativeWindowType;
- #if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN 1
- #endif
- #include <windows.h>
- typedef HDC EGLNativeDisplayType;
- typedef HBITMAP EGLNativePixmapType;
- typedef HWND EGLNativeWindowType;
- #elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
- typedef int EGLNativeDisplayType;
- typedef void *EGLNativeWindowType;
- typedef void *EGLNativePixmapType;
- #elif defined(__ANDROID__) || defined(ANDROID)
- struct ANativeWindow;
- struct egl_native_pixmap_t;
- typedef struct ANativeWindow* EGLNativeWindowType;
- typedef struct egl_native_pixmap_t* EGLNativePixmapType;
- typedef void* EGLNativeDisplayType;
- #elif defined(__unix__)
- /* X11 (tentative) */
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- typedef Display *EGLNativeDisplayType;
- typedef Pixmap EGLNativePixmapType;
- typedef Window EGLNativeWindowType;
- #else
- #error "Platform not recognized"
- #endif
可以看出對於Android平台,NativeWindowType的類型為ANativeWindow
- struct ANativeWindow
- {
- #ifdef __cplusplus //C++定義
- ANativeWindow(): flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
- {
- common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
- common.version = sizeof(ANativeWindow);
- memset(common.reserved, 0, sizeof(common.reserved));
- }
- /* Implement the methods that sp<ANativeWindow> expects so that it
- can be used to automatically refcount ANativeWindow's. */
- void incStrong(const void* id) const {
- common.incRef(const_cast<android_native_base_t*>(&common));
- }
- void decStrong(const void* id) const {
- common.decRef(const_cast<android_native_base_t*>(&common));
- }
- #endif
- struct android_native_base_t common;
- /* flags describing some attributes of this surface or its updater */
- const uint32_t flags;
- /* min swap interval supported by this updated */
- const int minSwapInterval;
- /* max swap interval supported by this updated */
- const int maxSwapInterval;
- /* horizontal and vertical resolution in DPI */
- const float xdpi;
- const float ydpi;
- /* Some storage reserved for the OEM's driver. */
- intptr_t oem[4];
- /* Set the swap interval for this surface. */
- int (*setSwapInterval)(struct ANativeWindow* window,
- int interval);
- /*
- * Hook called by EGL to acquire a buffer. After this call, the buffer
- * is not locked, so its content cannot be modified. This call may block if
- * no buffers are available.
- */
- int (*dequeueBuffer)(struct ANativeWindow* window,
- struct ANativeWindowBuffer** buffer);
- /*
- * hook called by EGL to lock a buffer. This MUST be called before modifying
- * the content of a buffer. The buffer must have been acquired with
- * dequeueBuffer first.
- */
- int (*lockBuffer)(struct ANativeWindow* window,
- struct ANativeWindowBuffer* buffer);
- /*
- * Hook called by EGL when modifications to the render buffer are done.
- * This unlocks and post the buffer.
- */
- int (*queueBuffer)(struct ANativeWindow* window,
- struct ANativeWindowBuffer* buffer);
- /*
- * hook used to retrieve information about the native window.
- */
- int (*query)(const struct ANativeWindow* window,
- int what, int* value);
- /*
- * hook used to perform various operations on the surface.
- * (*perform)() is a generic mechanism to add functionality to
- * ANativeWindow while keeping backward binary compatibility.
- * The valid operations are:
- * NATIVE_WINDOW_SET_USAGE
- * NATIVE_WINDOW_CONNECT (deprecated)
- * NATIVE_WINDOW_DISCONNECT (deprecated)
- * NATIVE_WINDOW_SET_CROP (private)
- * NATIVE_WINDOW_SET_BUFFER_COUNT
- * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY (deprecated)
- * NATIVE_WINDOW_SET_BUFFERS_TRANSFORM
- * NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
- * NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS
- * NATIVE_WINDOW_SET_BUFFERS_FORMAT
- * NATIVE_WINDOW_SET_SCALING_MODE (private)
- * NATIVE_WINDOW_LOCK (private)
- * NATIVE_WINDOW_UNLOCK_AND_POST (private)
- * NATIVE_WINDOW_API_CONNECT (private)
- * NATIVE_WINDOW_API_DISCONNECT (private)
- * NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS (private)
- * NATIVE_WINDOW_SET_POST_TRANSFORM_CROP (private)
- *
- */
- int (*perform)(struct ANativeWindow* window,
- int operation, ... );
- /*
- * Hook used to cancel a buffer that has been dequeued.
- * No synchronization is performed between dequeue() and cancel(), so
- * either external synchronization is needed, or these functions must be
- * called from the same thread.
- */
- int (*cancelBuffer)(struct ANativeWindow* window,
- struct ANativeWindowBuffer* buffer);
- void* reserved_proc[2];
- };
無論是基於應用程序的本地窗口SurfaceTextureClient還是基於SurfaceFlinger的 FramebufferNativeWindow本地窗口,都必須實現ANativeWindow定義的一套窗口協議,這樣應用程序和 SurfaceFlinger才能使用OpenGL。ANativeWindow就相當於Java中的接口類型,只是用於定義窗口的功能函數,並不去實現 這些函數,而是由需要使用OpenGL的對象來實現。
應用程序本地窗口
應用程序端的SurfaceTextureClient實現了ANativeWindow類型中定義的函數,這樣應用程序就可以使用OpenGL來繪制圖形圖像了,當然應用程序可以選擇性地使用OpenGL或是Skia。
SurfaceFlinger本地窗口
由於SurfaceFlinger必須要使用OpenGL來混合圖像,因此SurfaceFlinger端的FramebufferNativeWindow必須實現ANativeWindow類型。
Gralloc
通過加載gralloc抽象層,可以打開fb設備和gpu設備,fb設備用於操作framebuffer,gpu設備負責圖形緩沖區的分配和釋放。對於SurfaceFlinger服務端的本地窗口FramebufferNativeWindow將分別打開fb設備和gpu設備,FramebufferNativeWindow通過gpu設備從Framebuffer中分配圖形緩沖區,通過fb設備來渲染經SurfaceFlinger混合后的圖像。而對於應用程序端的SurfaceTextureClient本地窗口,其需要的圖形緩沖區也是由SurfaceFlinger服務端來分配,應用程序進程只需要將服務端分配的圖形緩沖區映射到應用程序的虛擬地址空間,圖形緩沖區的映射過程也是由Gralloc模塊完成。Android圖形顯示之硬件抽象層Gralloc對Gralloc模塊進行了詳細介紹,這里只簡單帶過。
gpu、fb和gralloc模塊中定義的數據結構關系如下:
通過加載Gralloc動態庫,可以分別打開fb設備和gpu設備。
gpu設備
Gpu打開過程就是創建並初始化一個gralloc_context_t對象,gpu負責圖形buffer的分配和釋放。
- int gralloc_device_open(const hw_module_t* module, const char* name,
- hw_device_t** device)
- {
- int status = -EINVAL;
- if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
- gralloc_context_t *dev;
- dev = (gralloc_context_t*)malloc(sizeof(*dev));
- /* initialize our state here */
- memset(dev, 0, sizeof(*dev));
- /* initialize the procs */
- dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = 0;
- dev->device.common.module = const_cast<hw_module_t*>(module);
- dev->device.common.close = gralloc_close;
- dev->device.alloc = gralloc_alloc;
- dev->device.free = gralloc_free;
- *device = &dev->device.common;
- status = 0;
- return status;
- }
fb設備
Fb設備打開過程就是創建並初始化一個fb_context_t對象,關於屏幕大小、格式、刷新頻率等信息都是通過Framebuffer驅動來獲取,最后將Framebuffer映射到SurfaceFlinger進程地址空間,並將映射后的首地址保持到private_module_t的framebuffer->base變量中。
- int fb_device_open(hw_module_t const* module, const char* name,
- hw_device_t** device)
- {
- int status = -EINVAL;
- if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
- alloc_device_t* gralloc_device;
- status = gralloc_open(module, &gralloc_device);
- if (status < 0)
- return status;
- /* initialize our state here */
- fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
- /* initialize the procs */
- dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = 0;
- dev->device.common.module = const_cast<hw_module_t*>(module);
- dev->device.common.close = fb_close;
- dev->device.setSwapInterval = fb_setSwapInterval;
- dev->device.post = fb_post;
- dev->device.setUpdateRect = 0;
- private_module_t* m = (private_module_t*)module;
- status = mapFrameBuffer(m);
- if (status >= 0) {
- int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
- int format = (m->info.bits_per_pixel == 32)
- ? HAL_PIXEL_FORMAT_RGBX_8888
- : HAL_PIXEL_FORMAT_RGB_565;
- const_cast<uint32_t&>(dev->device.flags) = 0;
- const_cast<uint32_t&>(dev->device.width) = m->info.xres;
- const_cast<uint32_t&>(dev->device.height) = m->info.yres;
- const_cast<int&>(dev->device.stride) = stride;
- const_cast<int&>(dev->device.format) = format;
- const_cast<float&>(dev->device.xdpi) = m->xdpi;
- const_cast<float&>(dev->device.ydpi) = m->ydpi;
- const_cast<float&>(dev->device.fps) = m->fps;
- const_cast<int&>(dev->device.minSwapInterval) = 1;
- const_cast<int&>(dev->device.maxSwapInterval) = 1;
- *device = &dev->device.common;
- }
- }
- return status;
- }
為了方便應用程序及SurfaceFlinger使用Gralloc模塊中的fb設備和gpu設備,Android對gpu設備進行了封裝。我們知 道,SurfaceFlinger不僅負責FramebufferNativeWindow本地窗口的圖形buffer的分配,同時也負責應用程序本地窗 口SurfaceTextureClient的圖形buffer分配,應用程序只需將服務端分配的圖形buffer映射到當前進程的虛擬地址空間即可,因 此應用程序和SurfaceFlinger都將會使用到Gralloc模塊。
SurfaceSession建立過程
SurfaceSession對象承擔了應用程序與SurfaceFlinger之間的通信過程,每一個需要與SurfaceFlinger進程交互的應用程序端都需要創建一個SurfaceSession對象。
客戶端請求
frameworks\base\core\java\android\view\SurfaceSession.java
- public SurfaceSession() {
- init();
- }
Java層的SurfaceSession對象構造過程會通過JNI在native層創建一個SurfaceComposerClient對象。
frameworks\base\core\jni\android_view_Surface.cpp
- static void SurfaceSession_init(JNIEnv* env, jobject clazz)
- {
- sp<SurfaceComposerClient> client = new SurfaceComposerClient;
- client->incStrong(clazz);
- env->SetIntField(clazz, sso.client, (int)client.get());
- }
Java層的SurfaceSession對象與C++層的SurfaceComposerClient對象之間是一對一關系。
frameworks\native\libs\gui\SurfaceComposerClient.cpp
- SurfaceComposerClient::SurfaceComposerClient()
- : mStatus(NO_INIT), mComposer(Composer::getInstance())
- {
- }
SurfaceComposerClient繼承於RefBase類,當第一次被強引用時,onFirstRef函數被回調,在該函數中 SurfaceComposerClient會請求SurfaceFlinger為當前應用程序創建一個Client對象,專門接收該應用程序的請求,在 SurfaceFlinger端創建好Client本地Binder對象后,將該Binder代理對象返回給應用程序端,並保存在 SurfaceComposerClient的成員變量mClient中。
- void SurfaceComposerClient::onFirstRef() {
- //得到SurfaceFlinger的代理對象BpSurfaceComposer
- sp<ISurfaceComposer> sm(getComposerService());
- if (sm != 0) {
- sp<ISurfaceComposerClient> conn = sm->createConnection();
- if (conn != 0) {
- mClient = conn;
- mStatus = NO_ERROR;
- }
- }
- }
服務端處理
在SurfaceFlinger服務端為應用程序創建交互的Client對象
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
- sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
- {
- sp<ISurfaceComposerClient> bclient;
- sp<Client> client(new Client(this));
- status_t err = client->initCheck();
- if (err == NO_ERROR) {
- bclient = client;
- }
- return bclient;
- }
關於SurfaceFlinger服務代理對象獲取的詳細過程請查看Android SurfaceFlinger服務代理對象獲取過程源碼分析。
Surface創建過程
客戶端請求
frameworks\base\core\java\android\view\Surface.java
- public Surface(SurfaceSession s,int pid, String name, int display, int w, int h, int format, int flags)
- throws OutOfResourcesException {
- checkHeadless();
- if (DEBUG_RELEASE) {
- mCreationStack = new Exception();
- }
- mCanvas = new CompatibleCanvas();
- init(s,pid,name,display,w,h,format,flags);
- mName = name;
- }
frameworks\base\core\jni\android_view_Surface.cpp
- static void Surface_init(JNIEnv* env, jobject clazz,jobject session,jint, jstring jname, jint dpy,
- jint w, jint h, jint format, jint flags)
- {
- if (session == NULL) {
- doThrowNPE(env);
- return;
- }
- //取得SurfaceComposerClient對象
- SurfaceComposerClient* client =
- (SurfaceComposerClient*)env->GetIntField(session, sso.client);
- //調用SurfaceComposerClient的createSurface函數在SurfaceFlinger服務端創建Layer對象,並返回ISurface
- //代理對象,並通過ISurface代理對象在應用程序端創建一個SurfaceControl對象,用於控制Surface
- sp<SurfaceControl> surface;
- if (jname == NULL) {
- surface = client->createSurface(dpy, w, h, format, flags);
- } else {
- const jchar* str = env->GetStringCritical(jname, 0);
- const String8 name(str, env->GetStringLength(jname));
- env->ReleaseStringCritical(jname, str);
- surface = client->createSurface(name, dpy, w, h, format, flags);
- }
- if (surface == 0) {
- jniThrowException(env, OutOfResourcesException, NULL);
- return;
- }
- //將創建的SurfaceControl對象指針保存到Java層的Surface的成員變量mSurfaceControl中
- setSurfaceControl(env, clazz, surface);
- }
該函數首先得到前面創建好的SurfaceComposerClient對象,通過該對象向SurfaceFlinger端的Client對象發送創建Surface的請求,最后得到一個SurfaceControl對象。
frameworks\native\libs\gui\SurfaceComposerClient.cpp
- sp<SurfaceControl> SurfaceComposerClient::createSurface(
- const String8& name,
- DisplayID display,
- uint32_t w,
- uint32_t h,
- PixelFormat format,
- uint32_t flags)
- {
- sp<SurfaceControl> result;
- if (mStatus == NO_ERROR) {
- //通過IsurfaceComposerClient的代理對象請求服務端的Client創建Surface
- ISurfaceComposerClient::surface_data_t data;
- sp<ISurface> surface = mClient->createSurface(&data, name,
- display, w, h, format, flags);
- //通過ISurface的代理對象創建SurfaceControl
- if (surface != 0) {
- result = new SurfaceControl(this, surface, data);
- }
- }
- return result;
- }
SurfaceComposerClient將Surface創建請求轉交給保存在其成員變量中的Bp SurfaceComposerClient對象來完成,在SurfaceFlinger端的Client本地對象會返回一個ISurface代理對象給 應用程序,通過該代理對象為應用程序當前創建的Surface創建一個SurfaceControl對象。
frameworks\native\include\gui\ISurfaceComposerClient.h
- virtual sp<ISurface> createSurface( surface_data_t* params,
- const String8& name,
- DisplayID display,
- uint32_t w,
- uint32_t h,
- PixelFormat format,
- uint32_t flags)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
- data.writeString8(name);
- data.writeInt32(display);
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- data.writeInt32(flags);
- remote()->transact(CREATE_SURFACE, data, &reply);
- params->readFromParcel(reply);
- return interface_cast<ISurface>(reply.readStrongBinder());
- }
服務端處理
frameworks\native\include\gui\ISurfaceComposerClient.h
- status_t BnSurfaceComposerClient::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
- {
- switch(code) {
- case CREATE_SURFACE: {
- CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
- surface_data_t params;
- String8 name = data.readString8();
- DisplayID display = data.readInt32();
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- PixelFormat format = data.readInt32();
- uint32_t flags = data.readInt32();
- //Client繼承於BnSurfaceComposerClient,調用Client的createSurface函數處理
- sp<ISurface> s = createSurface(¶ms, name, display, w, h,
- format, flags);
- params.writeToParcel(reply);
- reply->writeStrongBinder(s->asBinder());
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
- }
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp$ Client
- sp<ISurface> Client::createSurface(
- ISurfaceComposerClient::surface_data_t* params,
- const String8& name,
- DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
- uint32_t flags)
- {
- sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
- params, name, this, display, w, h, format, flags);
- //將Surface創建請求轉換為異步消息處理方式發送到SurfaceFlinger消息隊列中,由SurfaceFlinger服務來完成
- mFlinger->postMessageSync(msg);
- return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
- }
MessageCreateSurface消息是專門為應用程序請求創建Surface而定義的一種消息類型:
- /*
- * createSurface must be called from the GL thread so that it can
- * have access to the GL context.
- */
- class MessageCreateSurface : public MessageBase {
- sp<ISurface> result;
- SurfaceFlinger* flinger;
- ISurfaceComposerClient::surface_data_t* params;
- Client* client;
- const String8& name;
- DisplayID display;
- uint32_t w, h;
- PixelFormat format;
- uint32_t flags;
- public:
- MessageCreateSurface(SurfaceFlinger* flinger,
- ISurfaceComposerClient::surface_data_t* params,
- const String8& name, Client* client,
- DisplayID display, uint32_t w, uint32_t h, PixelFormat format,uint32_t flags)
- : flinger(flinger), params(params), client(client), name(name),display(display),
- w(w), h(h), format(format), flags(flags)
- {
- }
- sp<ISurface> getResult() const { return result; }
- //MessageCreateSurface消息的處理過程
- virtual bool handler() {
- result = flinger->createSurface(params, name, client,
- display, w, h, format, flags);
- return true;
- }
- };
Client將應用程序創建Surface的請求轉換為異步消息投遞到SurfaceFlinger的消息隊列中,將創建Surface的任務轉交給SurfaceFlinger。
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
- sp<ISurface> SurfaceFlinger::createSurface(
- ISurfaceComposerClient::surface_data_t* params,
- const String8& name,
- const sp<Client>& client,
- DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
- uint32_t flags)
- {
- sp<LayerBaseClient> layer;
- sp<ISurface> surfaceHandle;
- if (int32_t(w|h) < 0) {
- ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",int(w), int(h));
- return surfaceHandle;
- }
- //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
- sp<Layer> normalLayer;
- //根據flags創建不同類型的Surface
- switch (flags & eFXSurfaceMask) {
- case eFXSurfaceNormal:
- normalLayer = createNormalSurface(client, d, w, h, flags, format);
- layer = normalLayer;
- break;
- case eFXSurfaceBlur:
- // for now we treat Blur as Dim, until we can implement it
- // efficiently.
- case eFXSurfaceDim:
- layer = createDimSurface(client, d, w, h, flags);
- break;
- case eFXSurfaceScreenshot:
- layer = createScreenshotSurface(client, d, w, h, flags);
- break;
- }
- //為客戶端的Surface創建好Layer對象
- if (layer != 0) {
- layer->initStates(w, h, flags);
- layer->setName(name);
- //將創建好的Layer對象保存在Client中
- ssize_t token = addClientLayer(client, layer);
- //創建BSurface本地Binder對象
- surfaceHandle = layer->getSurface();
- if (surfaceHandle != 0) {
- //token為當前Layer對象在Client中的id號
- params->token = token;
- //Identity是每個Layer對象標號,SurfaceFlinger每創建一個Layer對象,自動加1
- params->identity = layer->getIdentity();
- //將創建好的Layer對象保存在SurfaceFlinger中
- if (normalLayer != 0) {
- Mutex::Autolock _l(mStateLock);
- mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
- }
- }
- setTransactionFlags(eTransactionNeeded);
- }
- return surfaceHandle;
- }
SurfaceFlinger根據標志位創建對應類型的Surface,當前系統定義了5種類型的Surface:
普遍Surface的創建過程:
- sp<Layer> SurfaceFlinger::createNormalSurface(
- const sp<Client>& client, DisplayID display,
- uint32_t w, uint32_t h, uint32_t flags,
- PixelFormat& format)
- {
- // initialize the surfaces
- switch (format) { // TODO: take h/w into account
- case PIXEL_FORMAT_TRANSPARENT:
- case PIXEL_FORMAT_TRANSLUCENT:
- format = PIXEL_FORMAT_RGBA_8888;
- break;
- case PIXEL_FORMAT_OPAQUE:
- #ifdef NO_RGBX_8888
- format = PIXEL_FORMAT_RGB_565;
- #else
- format = PIXEL_FORMAT_RGBX_8888;
- #endif
- break;
- }
- #ifdef NO_RGBX_8888
- if (format == PIXEL_FORMAT_RGBX_8888)
- format = PIXEL_FORMAT_RGBA_8888;
- #endif
- //在SurfaceFlinger端為應用程序的Surface創建對應的Layer對象
- sp<Layer> layer = new Layer(this, display, client);
- status_t err = layer->setBuffers(w, h, format, flags);
- if (CC_LIKELY(err != NO_ERROR)) {
- ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
- layer.clear();
- }
- return layer;
- }
在SurfaceFlinger服務端為應用程序創建的Surface創建對應的Layer對象。應用程序請求創建Surface過程如下:
Layer構造過程
frameworks\native\services\surfaceflinger\LayerBase.cpp
- LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
- : dpy(display), contentDirty(false),
- sequence(uint32_t(android_atomic_inc(&sSequence))),
- mFlinger(flinger), mFiltering(false),
- mNeedsFiltering(false),
- mOrientation(0),
- mPlaneOrientation(0),
- mTransactionFlags(0),
- mPremultipliedAlpha(true), mName("unnamed"), mDebug(false)
- {
- const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
- mFlags = hw.getFlags();
- }
- LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
- const sp<Client>& client)
- : LayerBase(flinger, display),
- mHasSurface(false),
- mClientRef(client),
- //為每個Layer對象分配一個唯一的標示號
- mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
- {
- }
frameworks\native\services\surfaceflinger\Layer.cpp
- Layer::Layer(SurfaceFlinger* flinger,
- DisplayID display, const sp<Client>& client)
- : LayerBaseClient(flinger, display, client),
- mTextureName(-1U),
- mQueuedFrames(0),
- mCurrentTransform(0),
- mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
- mCurrentOpacity(true),
- mRefreshPending(false),
- mFrameLatencyNeeded(false),
- mFrameLatencyOffset(0),
- mFormat(PIXEL_FORMAT_NONE),
- mGLExtensions(GLExtensions::getInstance()),
- mOpaqueLayer(true),
- mNeedsDithering(false),
- mSecure(false),
- mProtectedByApp(false)
- {
- mCurrentCrop.makeInvalid();
- glGenTextures(1, &mTextureName);
- }
第一次強引用Layer對象時,onFirstRef()函數被回調
- void Layer::onFirstRef()
- {
- LayerBaseClient::onFirstRef();
- //創建BufferQueue對象
- sp<BufferQueue> bq = new SurfaceTextureLayer();
- //創建SurfaceTexture對象
- mSurfaceTexture = new SurfaceTexture(mTextureName, true,
- GL_TEXTURE_EXTERNAL_OES, false, bq);
- mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
- //設置buffer可用監聽,生產者就是通過回調機制來通知消費者buffer數據已經填充好了
- mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
- //設置同步模式
- mSurfaceTexture->setSynchronousMode(true);
- //設置緩沖區個數
- #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
- #warning "disabling triple buffering"
- mSurfaceTexture->setBufferCountServer(2);
- #else
- mSurfaceTexture->setBufferCountServer(3);
- #endif
- }
BufferQueue構造過程
frameworks\native\libs\gui\ SurfaceTexture.cpp
- SurfaceTextureLayer::SurfaceTextureLayer()
- : BufferQueue(true) {
- }
frameworks\native\libs\gui\BufferQueue.cpp
- BufferQueue::BufferQueue( bool allowSynchronousMode, int bufferCount ) :
- mDefaultWidth(1),
- mDefaultHeight(1),
- mPixelFormat(PIXEL_FORMAT_RGBA_8888),
- mMinUndequeuedBuffers(bufferCount),
- mMinAsyncBufferSlots(bufferCount + 1),
- mMinSyncBufferSlots(bufferCount),
- mBufferCount(mMinAsyncBufferSlots),
- mClientBufferCount(0),
- mServerBufferCount(mMinAsyncBufferSlots),
- mSynchronousMode(false),
- mAllowSynchronousMode(allowSynchronousMode),
- mConnectedApi(NO_CONNECTED_API),
- mAbandoned(false),
- mFrameCounter(0),
- mBufferHasBeenQueued(false),
- mDefaultBufferFormat(0),
- mConsumerUsageBits(0),
- mTransformHint(0)
- {
- // Choose a name using the PID and a process-unique ID.
- mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
- ST_LOGV("BufferQueue");
- //由於BufferQueue與SurfaceFlinger處於同一進程中,因此這里獲取到SurfaceFlinger的本地Binder對象
- sp<ISurfaceComposer> composer(ComposerService::getComposerService());
- //通過SurfaceFlinger來創建圖形buffer分配器
- mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
- if (mGraphicBufferAlloc == 0) {
- ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");
- }
- }
GraphicBufferAlloc構造過程
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
- sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
- {
- sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
- return gba;
- }
SurfaceTexture構造過程
frameworks\native\libs\gui\ SurfaceTexture.cpp
- SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
- GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :
- mCurrentTransform(0),
- mCurrentTimestamp(0),
- mFilteringEnabled(true),
- mTexName(tex),
- #ifdef USE_FENCE_SYNC
- mUseFenceSync(useFenceSync),
- #else
- mUseFenceSync(false),
- #endif
- mTexTarget(texTarget),
- mEglDisplay(EGL_NO_DISPLAY),
- mEglContext(EGL_NO_CONTEXT),
- mAbandoned(false),
- mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
- mAttached(true)
- {
- // Choose a name using the PID and a process-unique ID.
- mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
- ST_LOGV("SurfaceTexture");
- if (bufferQueue == 0) {
- ST_LOGV("Creating a new BufferQueue");
- mBufferQueue = new BufferQueue(allowSynchronousMode);
- }
- else {
- mBufferQueue = bufferQueue;
- }
- memcpy(mCurrentTransformMatrix, mtxIdentity,
- sizeof(mCurrentTransformMatrix));
- // Note that we can't create an sp<...>(this) in a ctor that will not keep a
- // reference once the ctor ends, as that would cause the refcount of 'this'
- // dropping to 0 at the end of the ctor. Since all we need is a wp<...>
- // that's what we create.
- wp<BufferQueue::ConsumerListener> listener;
- sp<BufferQueue::ConsumerListener> proxy;
- //將當前SurfaceTexture對象保存到ProxyConsumerListener成員變量中,由ProxyConsumerListener
- //來代理接收FrameAvailable通知
- listener = static_cast<BufferQueue::ConsumerListener*>(this);
- proxy = new BufferQueue::ProxyConsumerListener(listener);
- //將ProxyConsumerListener對象設置到BufferQueue中,當buffer可被消費時,由BufferQueue
- //通知ProxyConsumerListener。BufferQueueProxyConsumerListenerSurfaceTexture
- status_t err = mBufferQueue->consumerConnect(proxy);
- if (err != NO_ERROR) {
- ST_LOGE("SurfaceTexture: error connecting to BufferQueue: %s (%d)",
- strerror(-err), err);
- } else {
- mBufferQueue->setConsumerName(mName);
- mBufferQueue->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
- }
- }
根據buffer可用監聽器的注冊過程,我們知道,當生產者也就是應用程序填充好圖形buffer數據后,通過回調方式通知消費者的過程如下:
在服務端為Surface創建Layer過程中,分別創建了SurfaceTexture、BufferQueue和GraphicBufferAlloc對象,它們之間的關系如下:
ISurface本地對象創建過程
以上完成Layer對象創建后,通過layer->getSurface()來創建ISurface的Binder本地對象,並將其代理對象返回給應用程序。
frameworks\native\services\surfaceflinge\ Layer.cpp
- sp<ISurface> Layer::createSurface()
- {
- sp<ISurface> sur(new BSurface(mFlinger, this));
- return sur;
- }
總結一下Surface創建過程,應用程序通過SurfaceComposerClient請求SurfaceFlinger創建一個Surface,在SurfaceFlinger服務端將會創建的對象有:
1. 一個Layer對象:
2. 一個SurfaceTexture對象
3. 一個BufferQueue對象:用於管理當前創建的Surface的圖形buffer
4. 一個GraphicBufferAlloc對象:用於分配圖形buffer
5. 一個BSurface本地Binder對象:用於獲取BufferQueue的Binder代理對象
關於Surface創建過程的詳細分析請參考Android應用程序創建Surface過程源碼分析。Android在SurfaceFlinger進程為應用程序定義了4個Binder對象:
1. SurfaceFlinger: 有名Binder對象,可通過服務查詢方式獲取;
2. Client: 無名Binder對象,只能由SurfaceFlinger服務創建;
3. BSurface: 無名Binder對象,只能由Client服務創建;
4. BufferQueue: 無名Binder對象,只能通過BSurface服務返回;
以上各個Binder對象提供的接口函數如下所示:
應用程序本地窗口Surface創建過程
從前面分析可知,SurfaceFlinger在處理應用程序請求創建Surface中,在SurfaceFlinger服務端僅僅創建了Layer對象,那么應用程序本地窗口Surface在什么時候、什么地方創建呢?
我們知道Surface繼承於SurfaceTextureClient,而SurfaceTextureClient是面向應用程序的本地創建,因此它就應該是在應用程序進程中創建。在前面的分析中,我們也知道,SurfaceFlinger
為應用程序創建好了Layer對象並返回ISurface的代理對象給應用程序,應用程序通過該代理對象創建了一個SurfaceControl對 象,Java層Surface需要通過android_view_Surface.cpp中的JNI函數來操作native層的Surface,在操作 native層Surface前,首先需要獲取到native的Surface,應用程序本地窗口Surface就是在這個時候創建的。
frameworks\base\core\jni\android_view_Surface.cpp
- static sp<Surface> getSurface(JNIEnv* env, jobject clazz)
- {
- //從Java層的Surface對象中獲取native的Surface對象指針
- sp<Surface> result(Surface_getSurface(env, clazz));
- //native Surface還未創建
- if (result == 0) {
- /*
- * if this method is called from the WindowManager's process, it means
- * the client is is not remote, and therefore is allowed to have
- * a Surface (data), so we create it here.
- * If we don't have a SurfaceControl, it means we're in a different
- * process.
- */
- SurfaceControl* const control =
- (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
- if (control) {
- //創建native Surface
- result = control->getSurface();
- if (result != 0) {
- result->incStrong(clazz);
- env->SetIntField(clazz, so.surface, (int)result.get());
- }
- }
- }
- return result;
- }
frameworks\native\libs\gui\Surface.cpp
- sp<Surface> SurfaceControl::getSurface() const
- {
- Mutex::Autolock _l(mLock);
- if (mSurfaceData == 0) {
- sp<SurfaceControl> surface_control(const_cast<SurfaceControl*>(this));
- //構造應用程序本地窗口
- mSurfaceData = new Surface(surface_control);
- }
- return mSurfaceData;
- }
- Surface::Surface(const sp<SurfaceControl>& surface)
- : SurfaceTextureClient(),
- mSurface(surface->mSurface),
- mIdentity(surface->mIdentity)
- {
- sp<ISurfaceTexture> st;
- if (mSurface != NULL) {
- st = mSurface->getSurfaceTexture();
- }
- init(st);
- }
Surface繼承於SurfaceTextureClient類,在構造Surface時,首先會調用SurfaceTextureClient的構造函數:
frameworks\native\libs\gui\SurfaceTextureClient.cpp
- SurfaceTextureClient::SurfaceTextureClient() {
- SurfaceTextureClient::init();
- }
- void SurfaceTextureClient::init() {
- // Initialize the ANativeWindow function pointers.
- ANativeWindow::setSwapInterval = hook_setSwapInterval;
- ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
- ANativeWindow::cancelBuffer = hook_cancelBuffer;
- ANativeWindow::lockBuffer = hook_lockBuffer;
- ANativeWindow::queueBuffer = hook_queueBuffer;
- ANativeWindow::query = hook_query;
- ANativeWindow::perform = hook_perform;
- const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
- const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
- mReqWidth = 0;
- mReqHeight = 0;
- mReqFormat = 0;
- mReqUsage = 0;
- mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
- mCrop.clear();
- mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
- mTransform = 0;
- mDefaultWidth = 0;
- mDefaultHeight = 0;
- mUserWidth = 0;
- mUserHeight = 0;
- mTransformHint = 0;
- mConsumerRunningBehind = false;
- mConnectedToCpu = false;
- }
父類SurfaceTextureClient構造完成后,通過ISurface的代理對象BpSurface請求BSurface獲取BufferQueue的代理對象。
frameworks\native\services\surfaceflinge\ Layer.cpp
- class BSurface : public BnSurface, public LayerCleaner {
- wp<const Layer> mOwner;
- virtual sp<ISurfaceTexture> getSurfaceTexture() const {
- sp<ISurfaceTexture> res;
- sp<const Layer> that( mOwner.promote() );
- if (that != NULL) {
- res = that->mSurfaceTexture->getBufferQueue();
- }
- return res;
- }
- public:
- BSurface(const sp<SurfaceFlinger>& flinger,const sp<Layer>& layer)
- : LayerCleaner(flinger, layer), mOwner(layer) { }
- };
最后調用Surface的init函數進行初始化
frameworks\native\libs\gui\Surface.cpp
- void Surface::init(const sp<ISurfaceTexture>& surfaceTexture)
- {
- if (mSurface != NULL || surfaceTexture != NULL) {
- ALOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface");
- if (surfaceTexture != NULL) {
- setISurfaceTexture(surfaceTexture);
- setUsage(GraphicBuffer::USAGE_HW_RENDER);
- }
- DisplayInfo dinfo;
- SurfaceComposerClient::getDisplayInfo(0, &dinfo);
- const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
- const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
- const_cast<uint32_t&>(ANativeWindow::flags) = 0;
- }
- }
到此應用程序的本地窗口Surface就創建完成了,通過上面的分析,可以知道,應用程序本地窗口的創建會在應用程序進程和SurfaceFlinger進程分別創建不同的對象:
1. SurfaceFlinger進程:Layer、SurfaceTexture、BufferQueue等;
2. 應用程序進程:Surface、SurfaceControl、SurfaceComposerClient等;
ISurfaceTexture是應用程序與BufferQueue的傳輸通道。
ISurfaceComposerClient是應用程序與SurfaceFlinger間的橋梁,在應用進程中則被封裝在 SurfaceComposerClient這個類中。這是一個匿名binder server,由應用程序調用SurfaceFlinger這個實名binder的createConnection方法來獲取到,服務端的實現是 SurfaceFlinger::Client。任何有UI界面的程序都在SurfaceFlinger中有且僅有一個Client實例。
ISurface:由應用程序調用ISurfaceComposerClient::createSurface()得到,同時在SurfaceFlinger這一進程中將會有一個Layer被創建,代表了一個“畫面”。ISurface就是控制這一畫面的handle。
Surface:從邏輯關系上看,它是上述ISurface的使用者。從繼承關系上看,它是一個SurfaceTextureClient,也就是本地窗 口。SurfaceTextureClient內部持有ISurfaceTexture,即BufferQueue的實現接口。
以上Surface、Layer、SurfaceTexture、BufferQueue,應用程序和Client之間的關系如下圖所示:
Surface的圖形buffer申請過程
在創建完應用程序本地窗口Surface后,想要在該Surface上繪圖,首先需要為該Surface分配圖形buffer。我們前面介紹了 Android應用程序圖形緩沖區的分配都是由SurfaceFlinger服務進程來完成,在請求創建Surface時,在服務端創建了一個 BufferQueue本地Binder對象,該對象負責管理應用程序一個本地窗口Surface的圖形緩沖區。在BufferQueue中定義了圖形 buffer的四個狀態:
- enum BufferState {
- // FREE indicates that the buffer is not currently being used and
- // will not be used in the future until it gets dequeued and
- // subsequently queued by the client.
- // aka "owned by BufferQueue, ready to be dequeued"
- FREE = 0,
- // DEQUEUED indicates that the buffer has been dequeued by the
- // client, but has not yet been queued or canceled. The buffer is
- // considered 'owned' by the client, and the server should not use
- // it for anything.
- //
- // Note that when in synchronous-mode (mSynchronousMode == true),
- // the buffer that's currently attached to the texture may be
- // dequeued by the client. That means that the current buffer can
- // be in either the DEQUEUED or QUEUED state. In asynchronous mode,
- // however, the current buffer is always in the QUEUED state.
- // aka "owned by producer, ready to be queued"
- DEQUEUED = 1,
- // QUEUED indicates that the buffer has been queued by the client,
- // and has not since been made available for the client to dequeue.
- // Attaching the buffer to the texture does NOT transition the
- // buffer away from the QUEUED state. However, in Synchronous mode
- // the current buffer may be dequeued by the client under some
- // circumstances. See the note about the current buffer in the
- // documentation for DEQUEUED.
- // aka "owned by BufferQueue, ready to be acquired"
- QUEUED = 2,
- // aka "owned by consumer, ready to be released"
- ACQUIRED = 3
- };
BufferQueue對圖形buffer的管理采用消費者-生產者模型,所有的buffer都由 BufferQueue管理,當生產者也就是應用程序需要繪圖時,必須向BufferQueue申請繪圖緩沖區,並且將圖形buffer設置為 DEQUEUED出列狀態,此時只有應用程序才能訪問這塊圖形buffer。當應用程序完成繪圖后,需要將圖形緩沖區歸還給BufferQueue管理, 並設置當前buffer為QUEUED入列狀態,同時通知消費者繪圖完成。消費者又將向BufferQueue申請已完成的圖形buffer,並將當前申 請的圖形buffer設置為ACQUIRED狀態,此時的圖形buffer只能被消費者處理。
客戶端請求
frameworks\native\libs\gui\SurfaceTextureClient.cpp
- int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::dequeueBuffer");
- Mutex::Autolock lock(mMutex);
- //圖形buffer的索引號
- int buf = -1;
- int reqW = mReqWidth ? mReqWidth : mUserWidth;
- int reqH = mReqHeight ? mReqHeight : mUserHeight;
- //請求服務端的BufferQueue
- status_t result = mSurfaceTexture->dequeueBuffer(&buf, reqW, reqH,
- mReqFormat, mReqUsage);
- if (result < 0) {
- ALOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
- "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
- result);
- return result;
- }
- sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
- //結果為RELEASE_ALL_BUFFERS,則釋放所有的buffer
- if (result & ISurfaceTexture::RELEASE_ALL_BUFFERS) {
- freeAllBuffers();
- }
- //結果為BUFFER_NEEDS_REALLOCATION,則請求重新分配圖形buffer
- if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
- //請求服務端的BufferQueue
- result = mSurfaceTexture->requestBuffer(buf, &gbuf);
- if (result != NO_ERROR) {
- ALOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",result);
- return result;
- }
- }
- *buffer = gbuf.get();
- return OK;
- }
frameworks\native\libs\gui\ISurfaceTexture.cpp$ BpSurfaceTexture
- virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
- uint32_t format, uint32_t usage) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- data.writeInt32(usage);
- status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- *buf = reply.readInt32();
- result = reply.readInt32();
- return result;
- }
服務端處理
frameworks\native\libs\gui\ISurfaceTexture.cpp$BnSurfaceTexture
- status_t BnSurfaceTexture::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
- {
- switch(code) {
- case DEQUEUE_BUFFER: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- uint32_t format = data.readInt32();
- uint32_t usage = data.readInt32();
- int buf;
- int result = dequeueBuffer(&buf, w, h, format, usage);
- reply->writeInt32(buf);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- }
- return BBinder::onTransact(code, data, reply, flags);
- }
frameworks\native\libs\gui\BufferQueue.cpp
- status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
- uint32_t format, uint32_t usage) {
- ATRACE_CALL();
- ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
- if ((w && !h) || (!w && h)) {
- ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
- return BAD_VALUE;
- }
- status_t returnFlags(OK);
- EGLDisplay dpy = EGL_NO_DISPLAY;
- EGLSyncKHR fence = EGL_NO_SYNC_KHR;
- { // Scope for the lock
- Mutex::Autolock lock(mMutex);
- if (format == 0) {
- format = mDefaultBufferFormat;
- }
- // turn on usage bits the consumer requested
- usage |= mConsumerUsageBits;
- int found = -1;
- int foundSync = -1;
- int dequeuedCount = 0;
- bool tryAgain = true;
- while (tryAgain) {
- if (mAbandoned) {
- ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
- return NO_INIT;
- }
- const int minBufferCountNeeded = mSynchronousMode ? mMinSyncBufferSlots : mMinAsyncBufferSlots;
- const bool numberOfBuffersNeedsToChange = !mClientBufferCount &&
- ((mServerBufferCount != mBufferCount) ||(mServerBufferCount < minBufferCountNeeded));
- if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {
- // wait for the FIFO to drain
- mDequeueCondition.wait(mMutex);
- // NOTE: we continue here because we need to reevaluate our
- // whole state (eg: we could be abandoned or disconnected)
- continue;
- }
- if (numberOfBuffersNeedsToChange) {
- // here we're guaranteed that mQueue is empty
- freeAllBuffersLocked();
- mBufferCount = mServerBufferCount;
- if (mBufferCount < minBufferCountNeeded)
- mBufferCount = minBufferCountNeeded;
- mBufferHasBeenQueued = false;
- returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
- }
- // look for a free buffer to give to the client
- found = INVALID_BUFFER_SLOT;
- foundSync = INVALID_BUFFER_SLOT;
- dequeuedCount = 0;
- for (int i = 0; i < mBufferCount; i++) {
- const int state = mSlots[i].mBufferState;
- if (state == BufferSlot::DEQUEUED) {
- dequeuedCount++;//統計已經被生產者出列的buffer個數
- }
- if (state == BufferSlot::FREE) {
- /*
- * mFrameNumber用於標示buffer入列序號,buffer入列時都會
- * mFrameNumber自動加一,通過mFrameNumber可以判斷buffer入列的先后順序
- */
- bool isOlder = mSlots[i].mFrameNumber < mSlots[found].mFrameNumber;
- if (found < 0 || isOlder) {
- foundSync = i;
- found = i;
- }
- }
- }
- // clients are not allowed to dequeue more than one buffer
- // if they didn't set a buffer count.
- if (!mClientBufferCount && dequeuedCount) {
- ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "
- "setting the buffer count");
- return -EINVAL;
- }
- // See whether a buffer has been queued since the last
- // setBufferCount so we know whether to perform the
- // mMinUndequeuedBuffers check below.
- if (mBufferHasBeenQueued) {
- // make sure the client is not trying to dequeue more buffers
- // than allowed.
- const int avail = mBufferCount - (dequeuedCount+1);
- if (avail < (mMinUndequeuedBuffers-int(mSynchronousMode))) {
- ST_LOGE("dequeueBuffer: mMinUndequeuedBuffers=%d exceeded ""(dequeued=%d)",
- mMinUndequeuedBuffers-int(mSynchronousMode),
- dequeuedCount);
- return -EBUSY;
- }
- }
- // if no buffer is found, wait for a buffer to be released
- tryAgain = found == INVALID_BUFFER_SLOT;
- if (tryAgain) {
- mDequeueCondition.wait(mMutex);
- }
- }
- if (found == INVALID_BUFFER_SLOT) {
- // This should not happen.
- ST_LOGE("dequeueBuffer: no available buffer slots");
- return -EBUSY;
- }
- //狀態為FREE、合適的buffer索引號
- const int buf = found;
- *outBuf = found;
- ATRACE_BUFFER_INDEX(buf);
- const bool useDefaultSize = !w && !h;
- if (useDefaultSize) {
- // use the default size
- w = mDefaultWidth;
- h = mDefaultHeight;
- }
- const bool updateFormat = (format != 0);
- if (!updateFormat) {
- // keep the current (or default) format
- format = mPixelFormat;
- }
- // buffer is now in DEQUEUED (but can also be current at the same time,
- // if we're in synchronous mode)
- mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
- const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
- //如果當前buffer不合適,則創建一個新的圖形buffer
- if ((buffer == NULL) ||
- (uint32_t(buffer->width) != w) ||
- (uint32_t(buffer->height) != h) ||
- (uint32_t(buffer->format) != format) ||
- ((uint32_t(buffer->usage) & usage) != usage))
- {
- status_t error;
- //創建新的圖形buffer
- sp<GraphicBuffer> graphicBuffer(
- mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage, &error));
- if (graphicBuffer == 0) {
- ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer ""failed");
- return error;
- }
- if (updateFormat) {
- mPixelFormat = format;
- }
- //根據buffer索引,初始化mSlots中對應的元素
- mSlots[buf].mAcquireCalled = false;
- mSlots[buf].mGraphicBuffer = graphicBuffer;
- mSlots[buf].mRequestBufferCalled = false;
- mSlots[buf].mFence = EGL_NO_SYNC_KHR;
- mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
- //設置返回結果為BUFFER_NEEDS_REALLOCATION
- returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
- }
- dpy = mSlots[buf].mEglDisplay;
- fence = mSlots[buf].mFence;
- mSlots[buf].mFence = EGL_NO_SYNC_KHR;
- } // end lock scope
- if (fence != EGL_NO_SYNC_KHR) {
- EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);
- // If something goes wrong, log the error, but return the buffer without
- // synchronizing access to it. It's too late at this point to abort the
- // dequeue operation.
- if (result == EGL_FALSE) {
- ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());
- } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
- ST_LOGE("dequeueBuffer: timeout waiting for fence");
- }
- eglDestroySyncKHR(dpy, fence);
- }
- ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
- mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);
- return returnFlags;
- }
BufferQueue中有一個mSlots數組用於管理其內的各緩沖區,最大容量為32。mSlots在程序一開始就 靜態分配了32個BufferSlot大小的空間。但BufferSlot的內部變指針mGraphicBuffer所指向的圖形buffer空間卻是動 態分配的。
圖形緩沖區創建過程
如果從mSlots數組中找到了一個狀態為FREE的圖形buffer,但由於該圖形buffer不合適,因此需要重新創建一個GraphicBuffer對象。
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
- sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage, status_t* error) {
- //構造一個GraphicBuffer對象
- sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
- status_t err = graphicBuffer->initCheck();
- *error = err;
- if (err != 0 || graphicBuffer->handle == 0) {
- if (err == NO_MEMORY) {
- GraphicBuffer::dumpAllocationsToSystemLog();
- }
- ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
- "failed (%s), handle=%p",
- w, h, strerror(-err), graphicBuffer->handle);
- return 0;
- }
- return graphicBuffer;
- }
frameworks\native\libs\ui\GraphicBuffer.cpp
- GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat reqFormat, uint32_t reqUsage)
- : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
- mInitCheck(NO_ERROR), mIndex(-1)
- {
- width =
- height =
- stride =
- format =
- usage = 0;
- handle = NULL;
- //分配圖形buffer存儲空間
- mInitCheck = initSize(w, h, reqFormat, reqUsage);
- }
根據圖形buffer的寬高、格式等信息為圖形緩沖區分配存儲空間
- status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
- uint32_t reqUsage)
- {
- GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
- status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);
- if (err == NO_ERROR) {
- this->width = w;
- this->height = h;
- this->format = format;
- this->usage = reqUsage;
- }
- return err;
- }
使用GraphicBufferAllocator對象來為圖形緩沖區分配內存空間,GraphicBufferAllocator是對Gralloc模塊中的gpu設備的封裝類。關於GraphicBufferAllocator內存分配過程請查看Android圖形緩沖區分配過程源碼分析,圖形緩沖區分配完成后,還會映射到SurfaceFlinger服務進程的虛擬地址空間。
應用程序獲取圖形buffer首地址

如果重新為圖形buffer分配空間,那么BufferQueue的dequeueBuffer函數返回值中需要加上 BUFFER_NEEDS_REALLOCATION標志。客戶端在發現這個標志后,它還應調用requestBuffer()來取得最新的buffer 地址。
客戶端請求
frameworks\native\libs\gui\SurfaceTextureClient.cpp
- int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
- ...
- if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
- //獲取圖形buffer的首地址
- result = mSurfaceTexture->requestBuffer(buf, &gbuf);
- if (result != NO_ERROR) {
- ALOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",
- result);
- return result;
- }
- }
- *buffer = gbuf.get();
- return OK;
- }
frameworks\native\libs\gui\ISurfaceTexture.cpp$ BpSurfaceTexture
- virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(bufferIdx);
- status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- bool nonNull = reply.readInt32();
- if (nonNull) {
- //在應用程序進程中創建一個GraphicBuffer對象
- sp<GraphicBuffer> p = new GraphicBuffer();
- result = reply.read(*p);
- if (result != NO_ERROR) {
- p = 0;
- return result;
- }
- *buf = p;
- }
- result = reply.readInt32();
- return result;
- }
frameworks\native\libs\ui\GraphicBuffer.cpp
- GraphicBuffer::GraphicBuffer()
- : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
- mInitCheck(NO_ERROR), mIndex(-1)
- {
- width =
- height =
- stride =
- format =
- usage = 0;
- handle = NULL;
- }
服務端進程接收到應用程序進程requestBuffer請求后,將新創建的GraphicBuffer對象發送給應用 程序。上面可以看到,應用程序進程這邊也創建了一個GraphicBuffer對象,在SurfaceFlinger服務進程中也同樣創建了一個 GraphicBuffer對象,SurfaceFlinger服務進程只是將它進程中創建的GraphicBuffer對象傳輸給應用程序進程,我們知 道,一個對象要在進程間傳輸必須繼承於Flattenable類,並且實現flatten和unflatten方法,flatten方法用於序列化該對 象,unflatten方法用於反序列化對象。
GraphicBuffer同樣繼承於Flattenable類並實現了flatten和unflatten方法,在應 用程序讀取來自服務進程的GraphicBuffer對象時,也就是result = reply.read(*p),會調用GraphicBuffer類的unflatten函數進行反序列化過程:
- status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
- int fds[], size_t count)
- {
- if (size < 8*sizeof(int)) return NO_MEMORY;
- int const* buf = static_cast<int const*>(buffer);
- if (buf[0] != 'GBFR') return BAD_TYPE;
- const size_t numFds = buf[6];
- const size_t numInts = buf[7];
- const size_t sizeNeeded = (8 + numInts) * sizeof(int);
- if (size < sizeNeeded) return NO_MEMORY;
- size_t fdCountNeeded = 0;
- if (count < fdCountNeeded) return NO_MEMORY;
- if (handle) {
- // free previous handle if any
- free_handle();
- }
- if (numFds || numInts) {
- width = buf[1];
- height = buf[2];
- stride = buf[3];
- format = buf[4];
- usage = buf[5];
- //創建一個native_handle對象
- native_handle* h = native_handle_create(numFds, numInts);
- memcpy(h->data, fds, numFds*sizeof(int));
- memcpy(h->data + numFds, &buf[8], numInts*sizeof(int));
- handle = h;
- } else {
- width = height = stride = format = usage = 0;
- handle = NULL;
- }
- mOwner = ownHandle;
- if (handle != 0) {
- //使用GraphicBufferMapper將服務端創建的圖形buffer映射到當前進程地址空間
- status_t err = mBufferMapper.registerBuffer(handle);
- if (err != NO_ERROR) {
- native_handle_close(handle);
- native_handle_delete(const_cast<native_handle*>(handle));
- handle = NULL;
- return err;
- }
- }
- return NO_ERROR;
- }
應用程序進程得到服務端進程返回來的GraphicBuffer對象后,還需要將該圖形buffer映射到應用程序進程地址空間,有關圖形緩存區的映射詳細過程請查看Android圖形緩沖區映射過程源碼分析。
服務端處理
frameworks\native\libs\gui\ISurfaceTexture.cpp$BnSurfaceTexture
- status_t BnSurfaceTexture::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
- {
- switch(code) {
- case REQUEST_BUFFER: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- int bufferIdx = data.readInt32();
- sp<GraphicBuffer> buffer;
- //通過BufferQueue的requestBuffer函數來獲得重新分配的圖形buffer
- int result = requestBuffer(bufferIdx, &buffer);
- reply->writeInt32(buffer != 0);
- //將GraphicBuffer對象寫回到應用程序進程,因此GraphicBuffer必須是Flattenable的子類
- if (buffer != 0) {
- reply->write(*buffer);
- }
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- }
- return BBinder::onTransact(code, data, reply, flags);
- }
frameworks\native\libs\gui\BufferQueue.cpp
- status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
- ATRACE_CALL();
- ST_LOGV("requestBuffer: slot=%d", slot);
- Mutex::Autolock lock(mMutex);
- if (mAbandoned) {
- ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!");
- return NO_INIT;
- }
- if (slot < 0 || mBufferCount <= slot) {
- ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",
- mBufferCount, slot);
- return BAD_VALUE;
- }
- mSlots[slot].mRequestBufferCalled = true;
- *buf = mSlots[slot].mGraphicBuffer;
- return NO_ERROR;
- }
由於GraphicBuffer繼承於Flattenable類,在Android 數據Parcel序列化過程源碼分析中介紹了,將一個對象寫入到Parcel中,需要使用flatten函數序列化該對象:
frameworks\native\libs\ui\GraphicBuffer.cpp
- status_t GraphicBuffer::flatten(void* buffer, size_t size,
- int fds[], size_t count) const
- {
- size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
- if (size < sizeNeeded) return NO_MEMORY;
- size_t fdCountNeeded = GraphicBuffer::getFdCount();
- if (count < fdCountNeeded) return NO_MEMORY;
- int* buf = static_cast<int*>(buffer);
- buf[0] = 'GBFR';
- buf[1] = width;
- buf[2] = height;
- buf[3] = stride;
- buf[4] = format;
- buf[5] = usage;
- buf[6] = 0;
- buf[7] = 0;
- if (handle) {
- buf[6] = handle->numFds;
- buf[7] = handle->numInts;
- native_handle_t const* const h = handle;
- memcpy(fds, h->data, h->numFds*sizeof(int));
- memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));
- }
- return NO_ERROR;
- }
到此我們就介紹完了應用程序請求BufferQueue出列一個可用圖形buffer的完整過程,那么應用程序什么時候發出這個請求呢?我們知道, 在使用Surface繪圖前,需要調用SurfaceHolder的lockCanvas()函數來鎖定畫布,然后才可以在畫布上作圖,應用程序就是在這 個時候向SurfaceFlinger服務進程中的BufferQueue申請圖形緩存區的。
應用程序釋放圖形buffer過程
當應用程序完成繪圖后,需要調用SurfaceHolder的unlockCanvasAndPost(canvas)函數來釋放畫布,並請求SurfaceFlinger服務進程混合並顯示該圖像。
從以上時序圖可以看到,應用程序完成繪圖后,首先對當前這塊圖形buffer進行解鎖,然后調用queueBuffer()函數請求 SurfaceFlinger服務進程中的BufferQueue將當前已繪制好圖形的buffer入列,也就是將當前buffer交還給 BufferQueue管理。應用程序這個生產者在這塊buffer中生產出了圖像產品后,就需要將buffer中的圖像產品放到BufferQueue 銷售市場中交易,SurfaceFlinger這個消費者得知市場上有新的圖像產品出現,就立刻請求VSync信號,在下一次VSync到來 時,SurfaceFlinger混合當前市場上的所有圖像產品,並顯示到屏幕上,從而完成圖像產品的消費過程。
客戶端請求
frameworks\native\libs\gui\SurfaceTextureClient.cpp
- int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::queueBuffer");
- Mutex::Autolock lock(mMutex);
- int64_t timestamp;
- if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
- timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
- ALOGV("SurfaceTextureClient::queueBuffer making up timestamp: %.2f ms",
- timestamp / 1000000.f);
- } else {
- timestamp = mTimestamp;
- }
- int i = getSlotFromBufferLocked(buffer);
- if (i < 0) {
- return i;
- }
- // Make sure the crop rectangle is entirely inside the buffer.
- Rect crop;
- mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
- ISurfaceTexture::QueueBufferOutput output;
- ISurfaceTexture::QueueBufferInput input(timestamp, crop, mScalingMode,
- mTransform);
- status_t err = mSurfaceTexture->queueBuffer(i, input, &output);
- if (err != OK) {
- ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
- }
- uint32_t numPendingBuffers = 0;
- output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,&numPendingBuffers);
- mConsumerRunningBehind = (numPendingBuffers >= 2);
- return err;
- }
frameworks\native\libs\gui\ ISurfaceTexture.cpp $BpSurfaceTexture
- virtual status_t queueBuffer(int buf,const QueueBufferInput& input, QueueBufferOutput* output) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(buf);
- memcpy(data.writeInplace(sizeof(input)), &input, sizeof(input));
- status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
- result = reply.readInt32();
- return result;
- }
服務端處理
frameworks\native\libs\gui\ ISurfaceTexture.cpp $BnSurfaceTexture
- status_t BnSurfaceTexture::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
- {
- switch(code) {
- case QUEUE_BUFFER: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- int buf = data.readInt32();
- QueueBufferInput const* const input =
- reinterpret_cast<QueueBufferInput const *>(
- data.readInplace(sizeof(QueueBufferInput)));
- QueueBufferOutput* const output =
- reinterpret_cast<QueueBufferOutput *>(
- reply->writeInplace(sizeof(QueueBufferOutput)));
- status_t result = queueBuffer(buf, *input, output);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- }
- return BBinder::onTransact(code, data, reply, flags);
- }
frameworks\native\libs\gui\ BufferQueue.cpp
- status_t BufferQueue::queueBuffer(int buf,
- const QueueBufferInput& input, QueueBufferOutput* output) {
- ATRACE_CALL();
- ATRACE_BUFFER_INDEX(buf);
- Rect crop;
- uint32_t transform;
- int scalingMode;
- int64_t timestamp;
- input.deflate(×tamp, &crop, &scalingMode, &transform);
- ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x "
- "scale=%s",
- buf, timestamp, crop.left, crop.top, crop.right, crop.bottom,
- transform, scalingModeName(scalingMode));
- sp<ConsumerListener> listener;
- { // scope for the lock
- Mutex::Autolock lock(mMutex);
- if (mAbandoned) {
- ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!");
- return NO_INIT;
- }
- if (buf < 0 || buf >= mBufferCount) {
- ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
- mBufferCount, buf);
- return -EINVAL;
- } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
- ST_LOGE("queueBuffer: slot %d is not owned by the client "
- "(state=%d)", buf, mSlots[buf].mBufferState);
- return -EINVAL;
- } else if (!mSlots[buf].mRequestBufferCalled) {
- ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
- "buffer", buf);
- return -EINVAL;
- }
- const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer);
- Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
- Rect croppedCrop;
- crop.intersect(bufferRect, &croppedCrop);
- if (croppedCrop != crop) {
- ST_LOGE("queueBuffer: crop rect is not contained within the "
- "buffer in slot %d", buf);
- return -EINVAL;
- }
- if (mSynchronousMode) {
- // In synchronous mode we queue all buffers in a FIFO.
- mQueue.push_back(buf);
- // Synchronous mode always signals that an additional frame should
- // be consumed.
- listener = mConsumerListener;
- } else {
- // In asynchronous mode we only keep the most recent buffer.
- if (mQueue.empty()) {
- mQueue.push_back(buf);
- // Asynchronous mode only signals that a frame should be
- // consumed if no previous frame was pending. If a frame were
- // pending then the consumer would have already been notified.
- listener = mConsumerListener;
- } else {
- Fifo::iterator front(mQueue.begin());
- // buffer currently queued is freed
- mSlots[*front].mBufferState = BufferSlot::FREE;
- // and we record the new buffer index in the queued list
- *front = buf;
- }
- }
- mSlots[buf].mTimestamp = timestamp;
- mSlots[buf].mCrop = crop;
- mSlots[buf].mTransform = transform;
- switch (scalingMode) {
- case NATIVE_WINDOW_SCALING_MODE_FREEZE:
- case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
- case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
- break;
- default:
- ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode);
- scalingMode = mSlots[buf].mScalingMode;
- break;
- }
- mSlots[buf].mBufferState = BufferSlot::QUEUED;
- mSlots[buf].mScalingMode = scalingMode;
- mFrameCounter++;
- mSlots[buf].mFrameNumber = mFrameCounter;
- mBufferHasBeenQueued = true;
- //通知有buffer入列
- mDequeueCondition.broadcast();
- output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
- mQueue.size());
- ATRACE_INT(mConsumerName.string(), mQueue.size());
- } // scope for the lock
- //通知消費者buffer已入列
- if (listener != 0) {
- listener->onFrameAvailable();
- }
- return OK;
- }
在 前面構造SurfaceTexture對象時,通過mBufferQueue->consumerConnect(proxy)將 ProxyConsumerListener監聽器保存到了BufferQueue的成員變量mConsumerListener中,同時又將 SurfaceTexture對象保存到ProxyConsumerListener的成員變量mConsumerListener中。
frameworks\native\libs\gui\SurfaceTexture.cpp
- SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
- GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue)
- {
- ...
- wp<BufferQueue::ConsumerListener> listener;
- sp<BufferQueue::ConsumerListener> proxy;
- listener = static_cast<BufferQueue::ConsumerListener*>(this);
- proxy = new BufferQueue::ProxyConsumerListener(listener);
- status_t err = mBufferQueue->consumerConnect(proxy);
- ....
- }
因此BufferQueue通過回調ProxyConsumerListener的onFrameAvailable()函數來通知消費者圖形buffer已經准備就緒。
frameworks\native\libs\gui\ BufferQueue.cpp
- void BufferQueue::ProxyConsumerListener::onFrameAvailable() {
- sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
- if (listener != NULL) {
- listener->onFrameAvailable();
- }
- }
ProxyConsumerListener又回調SurfaceTexture的onFrameAvailable()函數來處理。
frameworks\native\libs\gui\ SurfaceTexture.cpp
- void SurfaceTexture::onFrameAvailable() {
- ST_LOGV("onFrameAvailable");
- sp<FrameAvailableListener> listener;
- { // scope for the lock
- Mutex::Autolock lock(mMutex);
- listener = mFrameAvailableListener;
- }
- if (listener != NULL) {
- ST_LOGV("actually calling onFrameAvailable");
- listener->onFrameAvailable();
- }
- }
在 Layer對象的onFirstRef()函數中,通過調用SurfaceTexture的setFrameAvailableListener函數來為 SurfaceTexture設置buffer可用監器為FrameQueuedListene,其實就是將FrameQueuedListener對象 保存到SurfaceTexture的成員變量mFrameAvailableListener中:
frameworks\native\services\surfaceflinger\ Layer.cpp
- mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
因此buffer可用通知最終又交給FrameQueuedListener來處理:
- struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
- FrameQueuedListener(Layer* layer) : mLayer(layer) { }
- private:
- wp<Layer> mLayer;
- virtual void onFrameAvailable() {
- sp<Layer> that(mLayer.promote());
- if (that != 0) {
- that->onFrameQueued();
- }
- }
- };
FrameQueuedListener的onFrameAvailable()函數又調用Layer類的onFrameQueued()來處理
- void Layer::onFrameQueued() {
- android_atomic_inc(&mQueuedFrames);
- mFlinger->signalLayerUpdate();
- }
接着又通知SurfaceFlinger來更新Layer層。
frameworks\native\services\surfaceflinger\ SurfaceFlinger.cpp
- void SurfaceFlinger::signalLayerUpdate() {
- mEventQueue.invalidate();
- }
該函數就是向SurfaceFlinger的事件隊列中發送一個Vsync信號請求
frameworks\native\services\surfaceflinger\ MessageQueue.cpp
- void MessageQueue::invalidate() {
- mEvents->requestNextVsync();
- }
應用程序入列一個圖形buffer的整個過程如下: