1. 程式人生 > >Android6.0 顯示系統(六) 影象的輸出過程

Android6.0 顯示系統(六) 影象的輸出過程

上篇部落格分析到SurfaceFlinger收到了VSync訊號後,呼叫了handleMessageRefresh函式,這篇部落格主要就是分析這個函式,我們先看看它的程式碼:

  1. void SurfaceFlinger::handleMessageRefresh() {  
  2.     ATRACE_CALL();  
  3.     static nsecs_t previousExpectedPresent = 0;  
  4.     nsecs_t expectedPresent = mPrimaryDispSync.computeNextRefresh(0);  
  5.     static
    bool previousFrameMissed = false;  
  6.     bool frameMissed = (expectedPresent == previousExpectedPresent);  
  7.     if (frameMissed != previousFrameMissed) {  
  8.         ATRACE_INT("FrameMissed"static_cast<int>(frameMissed));  
  9.     }  
  10.     previousFrameMissed = frameMissed;  
  11.     if (CC_UNLIKELY(mDropMissedFrames && frameMissed)) {  
  12.         // Latch buffers, but don't send anything to HWC, then signal another
  13.         // wakeup for the next vsync
  14.         preComposition();  
  15.         repaintEverything();  
  16.     } else {  
  17.         preComposition();  
  18.         rebuildLayerStacks();  
  19.         setUpHWComposer();  
  20.         doDebugFlashRegions();  
  21.         doComposition();  
  22.         postComposition();  
  23.     }  
  24.     previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0);  
  25. }  

我們主要看下下面幾個函式。

  1. preComposition();  
  2. rebuildLayerStacks();  
  3. setUpHWComposer();  
  4. doDebugFlashRegions();  
  5. doComposition();  
  6. postComposition();  

一、preComposition函式

我們先來看第一個函式preComposition

  1. void SurfaceFlinger::preComposition()  
  2. {  
  3.     bool needExtraInvalidate = false;  
  4.     const LayerVector& layers(mDrawingState.layersSortedByZ);  
  5.     constsize_t count = layers.size();  
  6.     for (size_t i=0 ; i<count ; i++) {  
  7.         if (layers[i]->onPreComposition()) {  
  8.             needExtraInvalidate = true;  
  9.         }  
  10.     }  
  11.     if (needExtraInvalidate) {  
  12.         signalLayerUpdate();  
  13.     }  
  14. }  

上面函式先是呼叫了mDrawingState的layersSortedByZ來得到上次繪圖的Layer層列表。並不是所有的Layer都會參與螢幕影象的繪製,因此SurfaceFlinger用state物件來記錄參與繪製的Layer物件。

記得在之前的部落格,我們分析過createLayer函式來建立Layer,建立之後會呼叫addClientLayer函式。

  1. status_t SurfaceFlinger::createLayer(  
  2.         const String8& name,  
  3.         const sp<Client>& client,  
  4.         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,  
  5.         sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)  
  6. {  
  7.     //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
  8.     if (int32_t(w|h) < 0) {  
  9.         ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",  
  10.                 int(w), int(h));  
  11.         return BAD_VALUE;  
  12.     }  
  13.     status_t result = NO_ERROR;  
  14.     sp<Layer> layer;  
  15.     switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {  
  16.         case ISurfaceComposerClient::eFXSurfaceNormal:  
  17.             result = createNormalLayer(client,  
  18.                     name, w, h, flags, format,  
  19.                     handle, gbp, &layer);  
  20.             break;  
  21.         case ISurfaceComposerClient::eFXSurfaceDim:  
  22.             result = createDimLayer(client,  
  23.                     name, w, h, flags,  
  24.                     handle, gbp, &layer);  
  25.             break;  
  26.         default:  
  27.             result = BAD_VALUE;  
  28.             break;  
  29.     }  
  30.     if (result != NO_ERROR) {  
  31.         return result;  
  32.     }  
  33.     result = addClientLayer(client, *handle, *gbp, layer);  
  34.     if (result != NO_ERROR) {  
  35.         return result;  
  36.     }  
  37.     setTransactionFlags(eTransactionNeeded);  
  38.     return result;  
  39. }  

我們來看下addClientLayer函式,這裡會把Layer物件放在mCurrentState的layersSortedByZ物件中。而mDrawingState和mCurrentState什麼關係呢?在後面我們會介紹,mDrawingState代表上一次繪圖時的狀態,處理完之後會把mCurrentState賦給mDrawingState。

  1. status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,  
  2.         const sp<IBinder>& handle,  
  3.         const sp<IGraphicBufferProducer>& gbc,  
  4.         const sp<Layer>& lbc)  
  5. {  
  6.     // add this layer to the current state list
  7.     {  
  8.         Mutex::Autolock _l(mStateLock);  
  9.         if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) {  
  10.             return NO_MEMORY;  
  11.         }  
  12.         mCurrentState.layersSortedByZ.add(lbc);  
  13.         mGraphicBufferProducerList.add(IInterface::asBinder(gbc));  
  14.     }  
  15.     // attach this layer to the client
  16.     client->attachLayer(handle, lbc);  
  17.     return NO_ERROR;  
  18. }  

影象處理與影象識別筆記影象增強3

上一章節中我們講解了空域濾波的影象增強方法,包括影象的平滑和銳化,本文中,我們首先帶來頻域濾波的影象增強方法,指在頻域中對影象進行變換,需要的基礎知識是前述過的影象傅立葉變換,請檢視學習。 一、頻域濾波處理 頻域濾波處理的一般方法如下圖所示,先將影象經過傅立葉變換為頻域形式,然後乘以

LAMP+Postfix+Dovecot+Postfixadmin搭建郵件管理系統

接上期,我們部署完了Postfix服務,下面開始部署Dovecot服務。 七、部署Dovecot服務     1、下載dovecot安裝包     [[email protected] ~]# wget -c

機房系統——【下機】

    相對於上機來說,小編覺得下機還是有點兒難度的,在進行下機時,也是耗費了很長的時間。     在機房收費系統中,涉及到下機的,有三部分:首先是主介面上的下機,其次是操作員的所有學生下機和部分學生下機。這些部分的主要功能就是,實現上機使

Redis5.0原始碼解析----------Redis物件

基於Redis5.0 之前介紹了 Redis 用到的所有主要資料結構, 比如簡單動態字串(SDS)、雙端連結串列、字典、跳躍表、整數集合, 等等,但Redis 並沒有直接使用這些資料結構來實現鍵值對資料庫, 而是基於這些資料結構建立了一個物件系統, 這個系統包含字串物件

Spring Boot + Spring Cloud 構建微服務系統:熔斷監控叢集Turbine

Spring Cloud Turbine 上一章我們集成了Hystrix Dashboard,使用Hystrix Dashboard可以看到單個應用內的服務資訊,顯然這是不夠的,我們還需要一個工具能讓我們彙總系統內多個服務的資料並顯示到Hystrix Dashboard上,這個工具就是Turbine。 新增依

Opengl es2.0 學習筆記矩陣變化

一.座標系變化 openGL使用右手座標 從左到右,x遞增 從下到上,y遞增 從遠到近,z遞增 MVP 模型矩陣(Model):將區域性座標轉換為世界座標 觀察矩陣(View): 投影矩陣(Projection):正交還是透視投影 1.概述 為了將座標從一個座

OAuth 2.0系列教程 端點

作者:Jakob Jenkov   譯者:林浩    校對:郭蕾 OAuth 2.0定義了一系列端點。端點典型的就是web伺服器上的URI。比如,一個Java Servlet, JSP page, PHP page, ASP.NET網頁等等。 這些端點定義有: 授權端點 令牌端點 重定向端

我對hyperledger fabric1.1.0的執著:kafka叢集部署

1、用11臺伺服器,如下 名稱 ip Hostname 組織機構 Zk1 192.168.2.237 zookeeper1   Zk2 19

整合SpringMVC框架+Mybatis框架開發人力資源管理系統

業務邏輯元件HrmService介面的實現 業務邏輯元件的實現需要依賴於DAO元件,在HrmService介面中針對需要操作的六個實體(User、Employee、Job、Dept、Notice、Document)設計了不一樣的業務方法(CRUD),每個方法又會呼叫DAO元件中的一個或多

自頂向下分析一個簡單的語音識別系統

上回分析了run_model函式的configuration過程,其中load_placeholder_into_network函式用於構建該語音識別系統中RNN網路的基本結構,本回將分析以下該網路。 1.RNN簡介 人們並不是從每秒鐘他接收到的資訊開始

C語言構建WEB管理系統:使用XMLHttpRequest物件和服務端交換資料

       以登入頁面為例,當我們提交登入頁面表單時,將登入使用者名稱和登入密碼傳送到伺服器,這個時候我們肯定希望伺服器可以返回提交的使用者名稱和密碼是否正確的資訊。如果錯誤給出提示資訊以便重新輸入,正確則頁面給出提示或跳轉到指定頁面。這是就需要前端和伺服器端可以同步

學習opencv之-影象切割,使用ROI

一.ROI介紹在OpenCV中我們能夠非常方便地獲取指定ROI區域的子影象。如果你對影象設定了ROI,那麼,Opencv的大多數函式只在該ROI區域內運算(只處理該ROI區域),如果沒設ROI的話,就會出來整幅影象。ROI非常有用,例如我們想把影象中的人臉扣出來,進行人臉識別

【Android】15.0 UI開發——列表控件RecyclerView的網格布局排列實現

dir test pro 繼承 http 香港 bin too app 1.0 列表控件RecyclerView的網格布局排列實現,關鍵詞GridLayoutManager。 LinearLayoutManager 實現順序布局 GridLayoutManager 實現網格

qmail郵件系統qmail的日誌和管理

前面幾篇介紹了一個unix上安裝了qmail,做完所有的配置工作,你可能以為工作就要告一段落了。不幸的是,工作剛剛開始。相對於安裝和配置,真正讓人反感的是管理和對錯誤地發現和解決。下面我們講一下通過日誌,來判斷分析系統和qmail是否正常,來發現解決問題。在這裡,我們分系統日誌和qmail日誌兩部分來講。講一

資料庫系統---MySQL語句及儲存過程

一、DDL、DML、DCL常用語句  1、DDL(Data Definition Language)資料庫定義語言 (1)資料庫模式定義 #建立資料庫   create database if exsites db_name; #選定資料庫 use db_name; #刪除資料庫 drop d