国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Android SurfaceFlinger中的Layer,LayerDim,LayerBlur,LayerBuffer

下面幾張圖片分別表示了不同Layer產(chǎn)生的視覺效果:

  • Layer對(duì)應(yīng)普通的窗口
  • LayerDim 會(huì)使他后面的窗口產(chǎn)生一個(gè)變暗的透明效果
  • LayerBlur在LayerDim的基礎(chǔ)上,背景會(huì)產(chǎn)生模糊的效果

創(chuàng)建Layer

默認(rèn)地,創(chuàng)建普通的窗口Surface,在SurfaceFlinger中會(huì)創(chuàng)建Layer類,如果想創(chuàng)建LayerDim或LayerBlur,應(yīng)用程序需要在綁定View之前設(shè)置一下窗口的標(biāo)志位:

創(chuàng)建LayerDim效果:

 

  1. @Override  
  2. protected void onCreate(Bundle icicle) {  
  3.     // Be sure to call the super class.  
  4.     super.onCreate(icicle);  
  5.   
  6.     // Have the system blur any windows behind this one.  
  7.     getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,  
  8.             WindowManager.LayoutParams.FLAG_DIM_BEHIND);  
  9.     ......  
  10.     setContentView(......);  
  11. }  

 

 

創(chuàng)建LayerBlur效果:

 

  1. @Override  
  2. protected void onCreate(Bundle icicle) {  
  3.     // Be sure to call the super class.  
  4.     super.onCreate(icicle);  
  5.   
  6.     // Have the system blur any windows behind this one.  
  7.     getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,  
  8.             WindowManager.LayoutParams.FLAG_BLUR_BEHIND);  
  9.     ......  
  10.     setContentView(......);  
  11. }  

 

 

相應(yīng)地,在SufaceFlinger中,會(huì)根據(jù)Java層傳入的標(biāo)志,創(chuàng)建不同的Layer:

 

  1. sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,  
  2.         const String8& name, ISurfaceFlingerClient::surface_data_t* params,  
  3.         DisplayID d, uint32_t w, uint32_t h, PixelFormat format,  
  4.         uint32_t flags)  
  5. {  
  6.     sp<LayerBaseClient> layer;  
  7.     sp<LayerBaseClient::Surface> surfaceHandle;  
  8.     ......  
  9.     switch (flags & eFXSurfaceMask) {  
  10.         case eFXSurfaceNormal:  
  11.             if (UNLIKELY(flags & ePushBuffers)) {  
  12.                 layer = createPushBuffersSurfaceLocked(client, d, id,  
  13.                         w, h, flags);  
  14.             } else {  
  15.                 layer = createNormalSurfaceLocked(client, d, id,  
  16.                         w, h, flags, format);  
  17.             }  
  18.             break;  
  19.         case eFXSurfaceBlur:  
  20.             layer = createBlurSurfaceLocked(client, d, id, w, h, flags);  
  21.             break;  
  22.         case eFXSurfaceDim:  
  23.             layer = createDimSurfaceLocked(client, d, id, w, h, flags);  
  24.             break;  
  25.     }  
  26.   
  27.     if (layer != 0) {  
  28.         layer->setName(name);  
  29.         setTransactionFlags(eTransactionNeeded);  
  30.         surfaceHandle = layer->getSurface();  
  31.         ........  
  32.     }  
  33.   
  34.     return surfaceHandle;  
  35. }  

 

 

 


Layer類的靜態(tài)結(jié)構(gòu)

下面的圖展示了Layer類之間的繼承關(guān)系:

  • 所有的Layer都繼承了LayerBaseClient,SurfaceFlinger統(tǒng)一通過LayerBaseClient類訪問其他的派生Layer類
  • LayerBaseClient的內(nèi)嵌類Surface繼承了ISurface接口,ISurface用于和SurfaceFlinger的客戶端交互
  • Layer和LayerBuffer都有各自的內(nèi)嵌類:SurfaceLayer、SurfaceLayerBuffer,繼承了LayerBaseClient的內(nèi)嵌類Surface
  •  LayerBuffer還有另外的內(nèi)嵌類:Source,并且派生出另外兩個(gè)內(nèi)嵌類:BufferSource、OverlaySource

ISurface接口

 ISurface接口其實(shí)非常簡單,只有幾個(gè)函數(shù):

  • requestBuffer()        // Layer類使用,用于申請(qǐng)frontbuffer、backbuffer,初始化或size變化時(shí)調(diào)用
  • registerBuffers()      // LayerBuffer類使用,用于注冊(cè)IMemoryHeap接口
  • unregisterBuffers()  // LayerBuffer類使用,用于注銷IMemoryHeap接口
  • postBuffer()             // post用于刷新的圖像數(shù)據(jù)
  • createOverlay()       // 用于創(chuàng)建Overlay表面

LayerBaseClient的派生類中,會(huì)有一個(gè)內(nèi)嵌類,繼承LayerBaseClient::Surface,然后根據(jù)需要會(huì)實(shí)現(xiàn)該接口的相應(yīng)函數(shù)。


Layer類

Layer類是使用最多的一個(gè),普通的應(yīng)用程序窗口都會(huì)對(duì)應(yīng)一個(gè)Layer類,Layer類的內(nèi)嵌類SurfaceLayer繼承了ISurface接口,創(chuàng)建Layer類時(shí),將會(huì)返回一個(gè)ISurface接口給創(chuàng)建者。并且,Layer類在創(chuàng)建時(shí)會(huì)建立兩個(gè)GraphicBuffer對(duì)象,這兩個(gè)Buffer在不同的時(shí)刻分別被作為frontbuffer和backbuffer,frontbuffer用于本窗口的畫圖操作,backbuffer用于所有窗口的混合操作。但是兩個(gè)GraphicBuffer對(duì)象在創(chuàng)建時(shí)并沒有真正地分配內(nèi)存,而是在第一次lockBuffer時(shí)才正式通過ISurface接口的requestBuffer方法申請(qǐng)內(nèi)存,當(dāng)窗口的大小發(fā)生變化時(shí),也要重新分配適合窗口大小的內(nèi)存。Layer類的主要成員函數(shù)如下:

  • createSurface()  返回ISurface接口
  • setBuffers()  創(chuàng)建兩個(gè)GraphicBuffer對(duì)象,創(chuàng)建ISurface接口的實(shí)現(xiàn)類SurfaceLayer
  • onDraw()  把frontbuffer中的圖像數(shù)據(jù)通過OpenGL混合到OpenGL的主表面中
  • doTransaction()  檢測并處理窗口大小變化
  • lockPageFlip()  獲取frontbuffer,并且生成frontbuffer的OpenGL貼圖
  • finishPageFlip()  unlock frontbuffer,此后該buffer會(huì)queue到空閑列表中,下次可以作為backbuffer使用

 

 


 

LayerDim和LayerBlur

LayerDim和LayerBlur,他們的顯示內(nèi)容是固定不變的(透明的黑色),所以不需要分配兩個(gè)GraphicBuffer對(duì)象,因此它們也沒有繼承自LayerBaseClient::Surface的內(nèi)嵌類,而是直接使用LayerBaseClient::Surface類作為它們的ISurface接口。以LayerDim為例跟蹤一下它的Draw過程:

  • 創(chuàng)建LayerDim時(shí),在LayerDim.initDimmer()中生成純黑的OpenGL貼圖

 

  1. void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)  
  2. {  
  3.     sTexId = -1;  
  4.     sImage = EGL_NO_IMAGE_KHR;  
  5.     ......  
  6.     if (LIKELY(flags & DisplayHardware::DIRECT_TEXTURE)) {  
  7.         /* 申請(qǐng)GraphicBuffer */  
  8.         sp<GraphicBuffer> buffer = new GraphicBuffer(w, h, PIXEL_FORMAT_RGB_565,  
  9.                  GraphicBuffer::USAGE_SW_WRITE_OFTEN |  
  10.                  GraphicBuffer::USAGE_HW_TEXTURE);  
  11.           
  12.         android_native_buffer_t* clientBuf = buffer->getNativeBuffer();  
  13.        /* 申請(qǐng)OpenGL貼圖 */  
  14.         glGenTextures(1, &sTexId);  
  15.         glBindTexture(GL_TEXTURE_2D, sTexId);  
  16.   
  17.         EGLDisplay dpy = eglGetCurrentDisplay();  
  18.         sImage = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,   
  19.                 EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)clientBuf, 0);  
  20.         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)sImage);  
  21.         ......   
  22.         // initialize the texture with zeros  
  23.         GGLSurface t;  
  24.         buffer->lock(&t, GRALLOC_USAGE_SW_WRITE_OFTEN);  
  25.         memset(t.data, 0, t.stride * t.height * 2);  
  26.         buffer->unlock();  
  27.         sUseTexture = true;  
  28.     }  
  29. }  

 

  • 在OnDraw()中把第一步生成的貼圖混合到OpenGL的主表面中

 

 

  1. void LayerDim::onDraw(const Region& clip) const  
  2. {  
  3.     const State& s(drawingState());  
  4.     Region::const_iterator it = clip.begin();  
  5.     Region::const_iterator const end = clip.end();  
  6.     if (s.alpha>0 && (it != end)) {  
  7.         const DisplayHardware& hw(graphicPlane(0).displayHardware());  
  8.         ......  
  9.         /* 設(shè)置透明值 */  
  10.         glColor4x(0, 0, 0, alpha);  
  11.          
  12. #if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer)  
  13.         if (sUseTexture) {  
  14.             glBindTexture(GL_TEXTURE_2D, sTexId);  
  15.             glEnable(GL_TEXTURE_2D);  
  16.             glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);  
  17.             const GLshort texCoords[4][2] = {  
  18.                     { 0,  0 },  
  19.                     { 0,  1 },  
  20.                     { 1,  1 },  
  21.                     { 1,  0 }  
  22.             };  
  23.             glMatrixMode(GL_TEXTURE);  
  24.             glLoadIdentity();  
  25.             glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
  26.             glTexCoordPointer(2, GL_SHORT, 0, texCoords);  
  27.         } else  
  28. #endif  
  29.         {  
  30.             glDisable(GL_TEXTURE_2D);  
  31.         }  
  32.   
  33.         GLshort w = sWidth;  
  34.         GLshort h = sHeight;  
  35.         const GLshort vertices[4][2] = {  
  36.                 { 0, 0 },  
  37.                 { 0, h },  
  38.                 { w, h },  
  39.                 { w, 0 }  
  40.         };  
  41.         glVertexPointer(2, GL_SHORT, 0, vertices);  
  42.   
  43.         while (it != end) {  
  44.             const Rect& r = *it++;  
  45.             const GLint sy = fbHeight - (r.top + r.height());  
  46.             glScissor(r.left, sy, r.width(), r.height());  
  47.             glDrawArrays(GL_TRIANGLE_FAN, 0, 4);   
  48.         }  
  49.     }  
  50.     glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
  51. }  

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android中的GraphicBuffer同步機(jī)制
surfaceflinger中的顯示內(nèi)存管理類
android雙屏顯示的一些修改與嘗試
Android 開關(guān)機(jī)動(dòng)畫顯示源碼分析
[Android5.1]開機(jī)動(dòng)畫顯示工作流程分析
Android應(yīng)用程序UI硬件加速渲染技術(shù)簡要介紹和學(xué)習(xí)計(jì)劃
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服