• 和菜鸟一起学android4.0.3源码之鼠标光标绘制简略版


    http://blog.csdn.net/eastmoon502136/article/details/7696928


         搞定了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子 系统上报是
    1. input_report_key(&button_dev, KEY_POWER, 1);  
    1. input_report_key(&button_dev, KEY_POWER, 0);  

    这样可以实现电源键的锁屏功能。但当我交换了上报的顺寻后也就是

    1.   
    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> 

  • 相关阅读:
    自定义Bootstrap样式弹出框
    自定义Bootstrap样式弹出框
    Java高级
    Java高级
    Java高级
    Java高级
    与jQuery的感情碰撞——由浅入深学jQuery
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/leaven/p/2672360.html
Copyright © 2020-2023  润新知