android4.0.3源碼之鼠標光標繪製簡略版

搞定了android4.0.3的觸摸屏的適配後(其實只要驅動沒有什麼問題,加個配置文件就很容易搞定了),新的任務就下來了,就是要尋找android4.0.3中的鼠標是如何繪畫的,哪裏createSurface,哪裏分配空間的。因爲如果是軟鼠標的話,在播放視頻或者玩大型遊戲的時候是很卡的,而走overlay,硬鼠標的話,就顯得很靈敏了。艱鉅的任務啊,看了我好久還是沒有找到鼠標是在哪裏繪製的。因爲android2.3是在WindowManagerService裏面new了一個surface,接着畫了幾條線而得到的,而android4.0.3中,找了n久還是沒有發現,可惡的android4.0.3,網上資料也沒有介紹。
        期間也添加了android中的power、volumeup、volumedown三個按鍵,雖然基本功能實現了,但是還是沒有搞明白那個長按電源鍵出來關機和重啓等選項是怎麼實現的。無聊之餘,把KEY的DOWN和UP順序對調了下,居然有點效果,在此非常疑惑。就是我本來實現的時候,input子系統上報是

[html] view plaincopy
  1. input_report_key(&button_dev, KEY_POWER, 1);  
[html] view plaincopy
  1. input_report_key(&button_dev, KEY_POWER, 0);  

這樣可以實現電源鍵的鎖屏功能。但當我交換了上報的順尋後也就是

[html] view plaincopy
  1.   
[html] view plaincopy
  1. input_report_key(&button_dev, KEY_POWER, 0);  
  2. <pre class="html" name="code">input_report_key(&button_dev, KEY_POWER, 1);</pre><br>  
  3. <pre></pre>  
  4. <p>居然是那個長按鍵的功能,不知道哪位高手可以指導一下,這個還是得等找到了鼠標繪製的地方後再深入下去吧。        一直以爲surface的創建是在WindowManagerService中實現的,沒想到,這個android4.0.3居然把surface創建,鼠標繪製放在了input下了,這個可惡的SpriteController.cpp,目錄/frameworks/base/services/input/SpriteController.cpp。找得心灰意冷啊。居然中文解釋說是精靈,怪不得這麼難找呢。網上找了下,說java中好像是有一個Sprite的東東,說是什麼繪圖時候用的,這不正好是鼠標嗎,小小的精靈,難怪鼠標也是天藍色透明的了,看來寫這個代碼的高手還真的別有一番寓意啊,在此膜拜下。     
  5.  由於本人還是菜鳥,學電子的孩子,C++和Java接觸好少,看不大懂,只能簡單的瞭解下。先看看Sprite類的定義。註釋的已經很清楚了,六級都沒過的我也能看懂,相信難不倒你了。</p>  
  6. <pre class="html" name="code">class Sprite : public RefBase {  
  7. protected:  
  8.     Sprite() { }  
  9.     virtual ~Sprite() { }  
  10.   
  11. public:  
  12.     enum {  
  13.         // The base layer for pointer sprites.  
  14.         BASE_LAYER_POINTER = 0, // reserve space for 1 pointer  
  15.   
  16.         // The base layer for spot sprites.  
  17.         BASE_LAYER_SPOT = 1, // reserve space for MAX_POINTER_ID spots  
  18.     };  
  19.   
  20.     /* Sets the bitmap that is drawn by the sprite.  
  21.      * The sprite retains a copy of the bitmap for subsequent rendering. */  
  22.     virtual void setIcon(const SpriteIcon& icon) = 0;  
  23.   
  24.     inline void clearIcon() {  
  25.         setIcon(SpriteIcon());  
  26.     }  
  27.   
  28.     /* Sets whether the sprite is visible. */  
  29.     virtual void setVisible(bool visible) = 0;  
  30.   
  31.     /* Sets the sprite position on screen, relative to the sprite's hot spot. */  
  32.     virtual void setPosition(float x, float y) = 0;  
  33.   
  34.     /* Sets the layer of the sprite, relative to the system sprite overlay layer.  
  35.      * Layer 0 is the overlay layer, > 0 appear above this layer. */  
  36.     virtual void setLayer(int32_t layer) = 0;  
  37.   
  38.     /* Sets the sprite alpha blend ratio between 0.0 and 1.0. */  
  39.     virtual void setAlpha(float alpha) = 0;  
  40.   
  41.     /* Sets the sprite transformation matrix. */  
  42.     virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;  
  43. };  
  44.        
  45.   
  46. </pre>  
  47. <p><br>  
  48.     一開始的搜尋路線是找到鼠標那個png圖片是哪裏調用的,鼠標早就不叫mouse了,cursor或者pointer早就替換了mouse了。鼠標的圖標是在EventHub發現了鼠標這個驅動</p>  
  49. <p>(android4.0.3中應該是cursor這個驅動)後再由frameworks/base/core/java/android/view/PointerIcon.java中的getSystemIcon()導入,然後再由SpriteController::SpriteImpl::setIcon()(c++的類的繼承,虛函數,各種糾結,只能稍微理解)設置爲Sprite這個精靈的資源。每次鼠標移動後,InputReader線程總會獲取這個座標值,然後InputDispatch會分發給WindowManagerService,而ViewRootImpl會讀取等等,這個網上講得已經很詳細了。<br>  
  50.     對於鼠標,應該也是pointer,input目錄下面還有一個PointerController,看着這個名字,就知道了,這個肯定是控制鼠標啊, 觸摸屏啊什麼的。具體看註釋吧,寫得夠直</p>  
  51. <p>白的。</p>  
  52. <pre class="html" name="code">/**  
  53.  * Interface for tracking a mouse / touch pad pointer and touch pad spots.  
  54.  *  
  55.  * The spots are sprites on screen that visually represent the positions of  
  56.  * fingers  
  57.  *  
  58.  * The pointer controller is responsible for providing synchronization and for tracking  
  59.  * display orientation changes if needed.  
  60.  */  
  61. class PointerControllerInterface : public virtual RefBase {  
  62. protected:  
  63.     PointerControllerInterface() { }  
  64.     virtual ~PointerControllerInterface() { }  
  65.   
  66. public:  
  67.     /* Gets the bounds of the region that the pointer can traverse.  
  68.      * Returns true if the bounds are available. */  
  69.     virtual bool getBounds(float* outMinX, float* outMinY,  
  70.             float* outMaxX, float* outMaxY) const = 0;  
  71.   
  72.     /* Move the pointer. */  
  73.     virtual void move(float deltaX, float deltaY) = 0;  
  74.   
  75.     /* Sets a mask that indicates which buttons are pressed. */  
  76.     virtual void setButtonState(int32_t buttonState) = 0;  
  77.   
  78.     /* Gets a mask that indicates which buttons are pressed. */  
  79.     virtual int32_t getButtonState() const = 0;  
  80.   
  81.     /* Sets the absolute location of the pointer. */  
  82.     virtual void setPosition(float x, float y) = 0;  
  83.   
  84.     /* Gets the absolute location of the pointer. */  
  85.     virtual void getPosition(float* outX, float* outY) const = 0;  
  86.   
  87.     enum Transition {  
  88.         // Fade/unfade immediately.  
  89.         TRANSITION_IMMEDIATE,  
  90.         // Fade/unfade gradually.  
  91.         TRANSITION_GRADUAL,  
  92.     };  
  93.   
  94.     /* Fades the pointer out now. */  
  95.     virtual void fade(Transition transition) = 0;  
  96.   
  97.     /* Makes the pointer visible if it has faded out.  
  98.      * The pointer never unfades itself automatically.  This method must be called  
  99.      * by the client whenever the pointer is moved or a button is pressed and it  
  100.      * wants to ensure that the pointer becomes visible again. */  
  101.     virtual void unfade(Transition transition) = 0;  
  102.   
  103.     enum Presentation {  
  104.         // Show the mouse pointer.  
  105.         PRESENTATION_POINTER,  
  106.         // Show spots and a spot anchor in place of the mouse pointer.  
  107.         PRESENTATION_SPOT,  
  108.     };  
  109.   
  110.     /* Sets the mode of the pointer controller. */  
  111.     virtual void setPresentation(Presentation presentation) = 0;  
  112.   
  113.     /* Sets the spots for the current gesture.  
  114.      * The spots are not subject to the inactivity timeout like the pointer  
  115.      * itself it since they are expected to remain visible for so long as  
  116.      * the fingers are on the touch pad.  
  117.      *  
  118.      * The values of the AMOTION_EVENT_AXIS_PRESSURE axis is significant.  
  119.      * For spotCoords, pressure != 0 indicates that the spot's location is being  
  120.      * pressed (not hovering).  
  121.      */  
  122.     virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,  
  123.             BitSet32 spotIdBits) = 0;  
  124.   
  125.     /* Removes all spots. */  
  126.     virtual void clearSpots() = 0;  
  127. };  
  128.   
  129.   
  130. /*  
  131.  * Pointer resources.  
  132.  */  
  133. struct PointerResources {  
  134.     SpriteIcon spotHover;  
  135.     SpriteIcon spotTouch;  
  136.     SpriteIcon spotAnchor;  
  137. };  
  138.   
  139. </pre>  
  140. <p><br>  
  141.    而PointerController是繼承PointerControllerInterface的。突然看到這下面那兩行英文,這麼熟悉,這麼刺眼,頓時覺得,晴空霹靂啊,明明寫得這麼清楚了,畫pointer精靈到surface,這,,讓我情何以堪,找了這麼久,蒼天呢,都怪C++不夠好有木有,英語不夠牛有不有。其實android中很多函數的功能都在他的類的定義中有說明的,何不仔細研究.h呢?而把大把大把的時間浪費在.cpp中了,經驗啊,經驗不足啊。</p>  
  142. <pre class="html" name="code">/*  
  143.  * Tracks pointer movements and draws the pointer sprite to a surface.  
  144.  *  
  145.  * Handles pointer acceleration and animation.  
  146.  */  
  147. class PointerController : public PointerControllerInterface, public MessageHandler  
  148.     好了,發泄好了,而在Sprite中,最重要的就是SpriteController::doUpdateSprites()這個函數了,這裏就是鼠標繪製和移動後更新的全過程了。  
  149.   
  150. void SpriteController::doUpdateSprites() {  
  151.     // Collect information about sprite updates.  
  152.     // Each sprite update record includes a reference to its associated sprite so we can  
  153.     // be certain the sprites will not be deleted while this function runs.  Sprites  
  154.     // may invalidate themselves again during this time but we will handle those changes  
  155.     // in the next iteration.  
  156.     Vector<SpriteUpdate> updates;  
  157.     size_t numSprites;  
  158.     { // acquire lock  
  159.         AutoMutex _l(mLock);  
  160.   
  161.         numSprites = mLocked.invalidatedSprites.size();  
  162.         for (size_t i = 0; i < numSprites; i++) {  
  163.             const sp<SpriteImpl>sprite = mLocked.invalidatedSprites.itemAt(i);  
  164.   
  165.             updates.push(SpriteUpdate(sprite, sprite->getStateLocked()));  
  166.             sprite->resetDirtyLocked();  
  167.         }  
  168.         mLocked.invalidatedSprites.clear();  
  169.     } // release lock  
  170.   
  171.     // Create missing surfaces.  
  172.     bool surfaceChanged = false;  
  173.     for (size_t i = 0; i < numSprites; i++) {  
  174.         SpriteUpdate& update = updates.editItemAt(i);  
  175.   
  176.         if (update.state.surfaceControl == NULL && update.state.wantSurfaceVisible()) {  
  177.             update.state.surfaceWidth = update.state.icon.bitmap.width();  
  178.             update.state.surfaceHeight = update.state.icon.bitmap.height();  
  179.             update.state.surfaceDrawn = false;  
  180.             update.state.surfaceVisible = false;  
  181.             update.state.surfaceControl = obtainSurface(  
  182.                     update.state.surfaceWidth, update.state.surfaceHeight);  
  183.             if (update.state.surfaceControl != NULL) {  
  184.                 update.surfaceChanged = surfaceChanged = true;  
  185.             }  
  186.         }  
  187.     }  
  188.   
  189.     // Resize sprites if needed, inside a global transaction.  
  190.     bool haveGlobalTransaction = false;  
  191.     for (size_t i = 0; i < numSprites; i++) {  
  192.         SpriteUpdate& update = updates.editItemAt(i);  
  193.   
  194.         if (update.state.surfaceControl != NULL && update.state.wantSurfaceVisible()) {  
  195.             int32_t desiredWidth = update.state.icon.bitmap.width();  
  196.             int32_t desiredHeight = update.state.icon.bitmap.height();  
  197.             if (update.state.surfaceWidth < desiredWidth  
  198.                     || update.state.surfaceHeight < desiredHeight) {  
  199.                 if (!haveGlobalTransaction) {  
  200.                     SurfaceComposerClient::openGlobalTransaction();  
  201.                     haveGlobalTransaction = true;  
  202.                 }  
  203.   
  204.                 status_t status = update.state.surfaceControl->setSize(desiredWidth, desiredHeight);  
  205.                 if (status) {  
  206.                     LOGE("Error %d resizing sprite surface from %dx%d to %dx%d",  
  207.                             status, update.state.surfaceWidth, update.state.surfaceHeight,  
  208.                             desiredWidth, desiredHeight);  
  209.                 } else {  
  210.                     update.state.surfaceWidth = desiredWidth;  
  211.                     update.state.surfaceHeight = desiredHeight;  
  212.                     update.state.surfaceDrawn = false;  
  213.                     update.surfaceChanged = surfaceChanged = true;  
  214.   
  215.                     if (update.state.surfaceVisible) {  
  216.                         status = update.state.surfaceControl->hide();  
  217.                         if (status) {  
  218.                             LOGE("Error %d hiding sprite surface after resize.", status);  
  219.                         } else {  
  220.                             update.state.surfaceVisible = false;  
  221.                         }  
  222.                     }  
  223.                 }  
  224.             }  
  225.         }  
  226.     }  
  227.     if (haveGlobalTransaction) {  
  228.         SurfaceComposerClient::closeGlobalTransaction();  
  229.     }  
  230.   
  231.     // Redraw sprites if needed.  
  232.     for (size_t i = 0; i < numSprites; i++) {  
  233.         SpriteUpdate& update = updates.editItemAt(i);  
  234.   
  235.         if ((update.state.dirty & DIRTY_BITMAP) && update.state.surfaceDrawn) {  
  236.             update.state.surfaceDrawn = false;  
  237.             update.surfaceChanged = surfaceChanged = true;  
  238.         }  
  239.   
  240.         if (update.state.surfaceControl != NULL && !update.state.surfaceDrawn  
  241.                 && update.state.wantSurfaceVisible()) {  
  242.             sp<Surface> surface = update.state.surfaceControl->getSurface();  
  243.             Surface::SurfaceInfo surfaceInfo;  
  244.             status_t status = surface->lock(&surfaceInfo);  
  245.             if (status) {  
  246.                 LOGE("Error %d locking sprite surface before drawing.", status);  
  247.             } else {  
  248.                 SkBitmap surfaceBitmap;  
  249.                 ssize_t bpr = surfaceInfo.s * bytesPerPixel(surfaceInfo.format);  
  250.                 surfaceBitmap.setConfig(SkBitmap::kARGB_8888_Config,  
  251.                         surfaceInfo.w, surfaceInfo.h, bpr);  
  252.                 surfaceBitmap.setPixels(surfaceInfo.bits);  
  253.   
  254.                 SkCanvas surfaceCanvas;  
  255.                 surfaceCanvas.setBitmapDevice(surfaceBitmap);  
  256.   
  257.                 SkPaint paint;  
  258.                 paint.setXfermodeMode(SkXfermode::kSrc_Mode);  
  259.                 surfaceCanvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint);  
  260.   
  261.                 if (surfaceInfo.w > uint32_t(update.state.icon.bitmap.width())) {  
  262.                     paint.setColor(0); // transparent fill color  
  263.                     surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0,  
  264.                             surfaceInfo.w, update.state.icon.bitmap.height(), paint);  
  265.                 }  
  266.                 if (surfaceInfo.h > uint32_t(update.state.icon.bitmap.height())) {  
  267.                     paint.setColor(0); // transparent fill color  
  268.                     surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(),  
  269.                             surfaceInfo.w, surfaceInfo.h, paint);  
  270.                 }  
  271.   
  272.                 status = surface->unlockAndPost();  
  273.                 if (status) {  
  274.                     LOGE("Error %d unlocking and posting sprite surface after drawing.", status);  
  275.                 } else {  
  276.                     update.state.surfaceDrawn = true;  
  277.                     update.surfaceChanged = surfaceChanged = true;  
  278.                 }  
  279.             }  
  280.         }  
  281.     }  
  282.   
  283.     // Set sprite surface properties and make them visible.  
  284.     bool haveTransaction = false;  
  285.     for (size_t i = 0; i < numSprites; i++) {  
  286.         SpriteUpdate& update = updates.editItemAt(i);  
  287.   
  288.         bool wantSurfaceVisibleAndDrawn = update.state.wantSurfaceVisible()  
  289.                 && update.state.surfaceDrawn;  
  290.         bool becomingVisible = wantSurfaceVisibleAndDrawn && !update.state.surfaceVisible;  
  291.         bool becomingHidden = !wantSurfaceVisibleAndDrawn && update.state.surfaceVisible;  
  292.         if (update.state.surfaceControl != NULL && (becomingVisible || becomingHidden  
  293.                 || (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA  
  294.                         | DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER  
  295.                         | DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) {  
  296.             status_t status;  
  297.             if (!haveTransaction) {  
  298.                 SurfaceComposerClient::openGlobalTransaction();  
  299.                 haveTransaction = true;  
  300.             }  
  301.   
  302.             if (wantSurfaceVisibleAndDrawn  
  303.                     && (becomingVisible || (update.state.dirty & DIRTY_ALPHA))) {  
  304.                 status = update.state.surfaceControl->setAlpha(update.state.alpha);  
  305.                 if (status) {  
  306.                     LOGE("Error %d setting sprite surface alpha.", status);  
  307.                 }  
  308.             }  
  309.   
  310.             if (wantSurfaceVisibleAndDrawn  
  311.                     && (becomingVisible || (update.state.dirty & (DIRTY_POSITION  
  312.                             | DIRTY_HOTSPOT)))) {  
  313.                 status = update.state.surfaceControl->setPosition(  
  314.                         update.state.positionX - update.state.icon.hotSpotX,  
  315.                         update.state.positionY - update.state.icon.hotSpotY);  
  316.                 if (status) {  
  317.                     LOGE("Error %d setting sprite surface position.", status);  
  318.                 }  
  319.             }  
  320.   
  321.             if (wantSurfaceVisibleAndDrawn  
  322.                     && (becomingVisible  
  323.                             || (update.state.dirty & DIRTY_TRANSFORMATION_MATRIX))) {  
  324.                 status = update.state.surfaceControl->setMatrix(  
  325.                         update.state.transformationMatrix.dsdx,  
  326.                         update.state.transformationMatrix.dtdx,  
  327.                         update.state.transformationMatrix.dsdy,  
  328.                         update.state.transformationMatrix.dtdy);  
  329.                 if (status) {  
  330.                     LOGE("Error %d setting sprite surface transformation matrix.", status);  
  331.                 }  
  332.             }  
  333.   
  334.             int32_t surfaceLayer = mOverlayLayer + update.state.layer;  
  335.             if (wantSurfaceVisibleAndDrawn  
  336.                     && (becomingVisible || (update.state.dirty & DIRTY_LAYER))) {  
  337.                 status = update.state.surfaceControl->setLayer(surfaceLayer);  
  338.                 if (status) {  
  339.                     LOGE("Error %d setting sprite surface layer.", status);  
  340.                 }  
  341.             }  
  342.   
  343.             if (becomingVisible) {  
  344.                 status = update.state.surfaceControl->show(surfaceLayer);  
  345.                 if (status) {  
  346.                     LOGE("Error %d showing sprite surface.", status);  
  347.                 } else {  
  348.                     update.state.surfaceVisible = true;  
  349.                     update.surfaceChanged = surfaceChanged = true;  
  350.                 }  
  351.             } else if (becomingHidden) {  
  352.                 status = update.state.surfaceControl->hide();  
  353.                 if (status) {  
  354.                     LOGE("Error %d hiding sprite surface.", status);  
  355.                 } else {  
  356.                     update.state.surfaceVisible = false;  
  357.                     update.surfaceChanged = surfaceChanged = true;  
  358.                 }  
  359.             }  
  360.         }  
  361.     }  
  362.   
  363.     if (haveTransaction) {  
  364.         SurfaceComposerClient::closeGlobalTransaction();  
  365.     }  
  366.   
  367.     // If any surfaces were changed, write back the new surface properties to the sprites.  
  368.     if (surfaceChanged) { // acquire lock  
  369.         AutoMutex _l(mLock);  
  370.   
  371.         for (size_t i = 0; i < numSprites; i++) {  
  372.             const SpriteUpdate& update = updates.itemAt(i);  
  373.   
  374.             if (update.surfaceChanged) {  
  375.                 update.sprite->setSurfaceLocked(update.state.surfaceControl,  
  376.                         update.state.surfaceWidth, update.state.surfaceHeight,  
  377.                         update.state.surfaceDrawn, update.state.surfaceVisible);  
  378.             }  
  379.         }  
  380.     } // release lock  
  381.   
  382.     // Clear the sprite update vector outside the lock.  It is very important that  
  383.     // we do not clear sprite references inside the lock since we could be releasing  
  384.     // the last remaining reference to the sprite here which would result in the  
  385.     // sprite being deleted and the lock being reacquired by the sprite destructor  
  386.     // while already held.  
  387.     updates.clear();  
  388. }  
  389.   
  390. </pre>  
  391. <p><br>  
  392.     看到 update.state.surfaceControl = obtainSurface(update.state.surfaceWidth, update.state.surfaceHeight); 其實就是創建了一個surface,在一開始進入的主界面</p>  
  393. <p>的時候,鼠標是沒有的,當移動了下鼠標或者點擊了下鼠標後就執行這個創建了這個surface,有logcat後的信息爲證(只可惜公司nta內的東西拿不出來)。</p>  
  394. <pre class="html" name="code">sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height) {  
  395.     ensureSurfaceComposerClient();  
  396.   
  397.     sp<SurfaceControl> surfaceControl = mSurfaceComposerClient->createSurface(  
  398.             String8("Sprite"), 0, width, height, PIXEL_FORMAT_RGBA_8888);  
  399.     if (surfaceControl == NULL || !surfaceControl->isValid()  
  400.             || !surfaceControl->getSurface()->isValid()) {  
  401.         LOGE("Error creating sprite surface.");  
  402.         return NULL;  
  403.     }  
  404.     return surfaceControl;  
  405. }  
  406.   
  407. </pre>  
  408. <p><br>  
  409.       而創建完後,必須得分配空間啊,surface的信息也得錄入啊。具體就在下面了</p>  
  410. <p> </p>  
  411. <pre class="html" name="code">sp<Surface> surface = update.state.surfaceControl->getSurface();  
  412.             Surface::SurfaceInfo surfaceInfo;  
  413.             status_t status = surface->lock(&surfaceInfo);           
  414. </pre>  
  415. <p><br>  
  416.  看到lock()了嗎?就是這,繼續跟進代碼<br>  
  417. </p>  
  418. <pre class="html" name="code">status_t Surface::lock(SurfaceInfo* other, Region* inOutDirtyRegion) {  
  419.     ANativeWindow_Buffer outBuffer;  
  420.   
  421.     ARect temp;  
  422.     ARect* inOutDirtyBounds = NULL;  
  423.     if (inOutDirtyRegion) {  
  424.         temp = inOutDirtyRegion->getBounds();  
  425.         inOutDirtyBounds = &temp;  
  426.     }  
  427.   
  428.     status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds);  
  429.   
  430.     if (err == NO_ERROR) {  
  431.         other->w = uint32_t(outBuffer.width);  
  432.         other->h = uint32_t(outBuffer.height);  
  433.         other->s = uint32_t(outBuffer.stride);  
  434.         other->usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;  
  435.         other->format = uint32_t(outBuffer.format);  
  436.         other->bits = outBuffer.bits;  
  437.     }  
  438.   
  439.     if (inOutDirtyRegion) {  
  440.         inOutDirtyRegion->set( static_cast<Rect const&>(temp) );  
  441.     }  
  442.   
  443.     return err;  
  444. }  
  445.   
  446. </pre>  
  447. <p><br>  
  448.  也行你會說,怎麼這個lock有兩個參數的,明顯不對嗎,好吧,看來我的C++還是有點基礎的,後悔以前搞ACM的時候只是一個main函數到底,沒有好好用C++來實現,要不然現在也肯定是個大牛了。看看這個 status_t    lock(SurfaceInfo* info, Region* dirty = NULL);明白了吧?使用了默認的參數,剛開始還以爲這個lock是假的。哈哈接着,看到了SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds);了吧,好明顯的說,接着看看這個函數到底幹了什麼了</p>  
  449. <pre class="html" name="code">status_t SurfaceTextureClient::lock(  
  450.         ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)  
  451. {  
  452.     if (mLockedBuffer != 0) {  
  453.         LOGE("Surface::lock failed, already locked");  
  454.         return INVALID_OPERATION;  
  455.     }  
  456.   
  457.     if (!mConnectedToCpu) {  
  458.         int err = SurfaceTextureClient::connect(NATIVE_WINDOW_API_CPU);  
  459.         if (err) {  
  460.             return err;  
  461.         }  
  462.         // we're intending to do software rendering from this point  
  463.         setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);  
  464.     }  
  465.   
  466.     ANativeWindowBuffer* out;  
  467.     status_t err = dequeueBuffer(&out);  
  468.     LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));  
  469.     if (err == NO_ERROR) {  
  470.         sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));  
  471.         err = lockBuffer(backBuffer.get());  
  472.         LOGE_IF(err, "lockBuffer (handle=%p) failed (%s)",  
  473.                 backBuffer->handle, strerror(-err));  
  474.         if (err == NO_ERROR) {  
  475.             const Rect bounds(backBuffer->width, backBuffer->height);  
  476.   
  477.             Region newDirtyRegion;  
  478.             if (inOutDirtyBounds) {  
  479.                 newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));  
  480.                 newDirtyRegion.andSelf(bounds);  
  481.             } else {  
  482.                 newDirtyRegion.set(bounds);  
  483.             }  
  484.   
  485.             // figure out if we can copy the frontbuffer back  
  486.             const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);  
  487.             const bool canCopyBack = (frontBuffer != 0 &&  
  488.                     backBuffer->width  == frontBuffer->width &&  
  489.                     backBuffer->height == frontBuffer->height &&  
  490.                     backBuffer->format == frontBuffer->format);  
  491.   
  492.             if (canCopyBack) {  
  493.                 // copy the area that is invalid and not repainted this round  
  494.                 const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));  
  495.                 if (!copyback.isEmpty())  
  496.                     copyBlt(backBuffer, frontBuffer, copyback);  
  497.             } else {  
  498.                 // if we can't copy-back anything, modify the user's dirty  
  499.                 // region to make sure they redraw the whole buffer  
  500.                 newDirtyRegion.set(bounds);  
  501.             }  
  502.   
  503.             // keep track of the are of the buffer that is "clean"  
  504.             // (ie: that will be redrawn)  
  505.             mOldDirtyRegion = newDirtyRegion;  
  506.   
  507.             if (inOutDirtyBounds) {  
  508.                 *inOutDirtyBounds = newDirtyRegion.getBounds();  
  509.             }  
  510.   
  511.             void* vaddr;  
  512.             status_t res = backBuffer->lock(  
  513.                     GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,  
  514.                     newDirtyRegion.bounds(), &vaddr);  
  515.   
  516.             LOGW_IF(res, "failed locking buffer (handle = %p)",  
  517.                     backBuffer->handle);  
  518.   
  519.             mLockedBuffer = backBuffer;  
  520.             outBuffer->width  = backBuffer->width;  
  521.             outBuffer->height = backBuffer->height;  
  522.             outBuffer->stride = backBuffer->stride;  
  523.             outBuffer->format = backBuffer->format;  
  524.             outBuffer->bits   = vaddr;  
  525.         }  
  526.     }  
  527.     return err;  
  528. }  
  529.   
  530. </pre>  
  531. <p><br>  
  532.    好了,找到了 ANativeWindowBuffer* out;   status_t err = dequeueBuffer(&out);差不多告一段落了,代碼看着頭暈,還是分析不大來額。菜鳥有待提高,打好基礎,慢慢</p>  
  533. <p>地分析。</p>  
  534. <pre class="html" name="code">int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {  
  535.     LOGV("SurfaceTextureClient::dequeueBuffer");  
  536.     Mutex::Autolock lock(mMutex);  
  537.     int buf = -1;  
  538.     status_t result = mSurfaceTexture->dequeueBuffer(&buf, mReqWidth, mReqHeight,  
  539.             mReqFormat, mReqUsage);  
  540.     if (result < 0) {  
  541.         LOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"  
  542.              "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,  
  543.              result);  
  544.         return result;  
  545.     }  
  546.     sp<GraphicBuffer>& gbuf(mSlots[buf]);  
  547.     if (result & ISurfaceTexture::RELEASE_ALL_BUFFERS) {  
  548.         freeAllBuffers();  
  549.     }  
  550.   
  551.     if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {  
  552.         result = mSurfaceTexture->requestBuffer(buf, &gbuf);  
  553.         if (result != NO_ERROR) {  
  554.             LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",  
  555.                     result);  
  556.             return result;  
  557.         }  
  558.     }  
  559.     *buffer = gbuf.get();  
  560.     return OK;  
  561. }  
  562.   
  563. </pre>  
  564. <p><br>  
  565.     由於對surface很多的概念還不是很清楚,分析代碼也有點難度。只能拿出來,慢慢啃了。快要下班了,就這麼着吧。android的圖形顯示系統好複雜好複雜啊,看得我頭都大</p>  
  566. <p>了。不過結合板子和代碼慢慢調試倒是可以理解得很好。不錯。還有就是代碼中的英文得好好啃,看來單詞還得好好記啊。<br>  
  567. </p>  
  568. <pre></pre>  
  569. <pre></pre>  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章