VirtualBox

Changeset 4181 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Aug 16, 2007 5:49:59 PM (17 years ago)
Author:
vboxsync
Message:

Windows guest display driver to report the screen rectangle that was actually changed.

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Display
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/Makefile.kmk

    r4071 r4181  
    2828VBoxDisp_DEFS        = _WIN32_WINNT=0x0501 LOG_TO_BACKDOOR VBOX_WITH_DDRAW VBOX_WITH_OPENGL
    2929VBoxDisp_INCS        = ../../include
     30VBoxDisp_DEFS        += VBOX_VBVA_ADJUST_RECT
    3031#VBoxDisp_DEFS        += LOG_ENABLED
    3132#VBoxDisp_DEFS        += STAT_sunlover
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h

    r4124 r4181  
    231231    return 0;
    232232}
     233
     234#ifdef VBOX_VBVA_ADJUST_RECT
     235void vrdpAdjustRect (SURFOBJ *pso, RECTL *prcl);
     236BOOL vbvaFindChangedRect (SURFOBJ *psoDest, SURFOBJ *psoSrc, RECTL *prclDest, POINTL *pptlSrc);
     237#endif /* VBOX_VBVA_ADJUST_RECT */
     238
    233239
    234240#include <iprt/assert.h>
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/drv.c

    r4071 r4181  
    269269    )
    270270{
     271    RECTL rclDest = *prclDest;
     272    POINTL ptlSrc = *pptlSrc;
     273
    271274    BOOL bRc;
     275    BOOL bDo = TRUE;
    272276
    273277    DISPDBG((1, "%s\n", __FUNCTION__));
     
    282286
    283287    STATPRINT;
    284 
    285     bRc = EngCopyBits(CONV_SURF(psoDest), CONV_SURF(psoSrc), pco, pxlo, prclDest, pptlSrc);
     288   
     289#ifdef VBOX_VBVA_ADJUST_RECT
     290    /* Experimental fix for too large bitmap updates.
     291     *
     292     * Some application do a large bitmap update event if only
     293     * a small part of the bitmap is actually changed.
     294     *
     295     * The driver will find the changed rectangle by comparing
     296     * the current framebuffer content with the source bitmap.
     297     *
     298     * The optimization is only active when:
     299     *  - the VBVA extension is enabled;
     300     *  - the source bitmap is not cacheable;
     301     *  - the bitmap formats of both the source and the screen surfaces are equal.
     302     *
     303     */
     304    if (   psoSrc
     305        && !bIsScreenSurface(psoSrc)
     306        && bIsScreenSurface(psoDest))
     307    {
     308        PPDEV ppdev = (PPDEV)psoDest->dhpdev;
     309
     310        VBVAMEMORY *pVbvaMemory = ppdev->vbva.pVbvaMemory;
     311
     312        DISPDBG((1, "offscreen->screen\n"));
     313
     314        if (   pVbvaMemory
     315            && (pVbvaMemory->fu32ModeFlags & VBVA_F_MODE_ENABLED))
     316        {
     317            if (   (psoSrc->fjBitmap & BMF_DONTCACHE) != 0
     318                || psoSrc->iUniq == 0)
     319            {
     320                DISPDBG((1, "non-cacheable %d->%d (ppdev %p)\n", psoSrc->iBitmapFormat, psoDest->iBitmapFormat, ppdev));
     321
     322                /* It is possible to apply the fix. */
     323                bDo = vbvaFindChangedRect (CONV_SURF(psoDest), CONV_SURF(psoSrc), &rclDest, &ptlSrc);
     324            }
     325        }
     326    }
     327
     328    if (!bDo)
     329    {
     330        /* The operation is a NOP. Just return success. */
     331        return TRUE;
     332    }
     333#endif /* VBOX_VBVA_ADJUST_RECT */
     334
     335    bRc = EngCopyBits(CONV_SURF(psoDest), CONV_SURF(psoSrc), pco, pxlo, &rclDest, &ptlSrc);
    286336
    287337    VBVA_OPERATION(psoDest,
    288338                   CopyBits,
    289                    (psoDest, psoSrc, pco, pxlo, prclDest, pptlSrc));
     339                   (psoDest, psoSrc, pco, pxlo, &rclDest, &ptlSrc));
    290340
    291341    return bRc;
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vbva.c

    r4071 r4181  
    1818#include "driver.h"
    1919
     20#ifdef VBOX_VBVA_ADJUST_RECT
     21static ULONG vbvaConvertPixel ( /*from*/ BYTE *pu8PixelFrom, int cbPixelFrom,
     22                                /*to*/ int cbPixelTo)
     23{
     24    BYTE r, g, b;
     25    ULONG ulConvertedPixel = 0;
     26
     27    switch (cbPixelFrom)
     28    {
     29        case 4:
     30        {
     31           switch (cbPixelTo)
     32           {
     33               case 3:
     34               {
     35                   memcpy (&ulConvertedPixel, pu8PixelFrom, 3);
     36               } break;
     37
     38               case 2:
     39               {
     40                   ulConvertedPixel = *(ULONG *)pu8PixelFrom;
     41
     42                   r = (BYTE)(ulConvertedPixel >> 16);
     43                   g = (BYTE)(ulConvertedPixel >> 8);
     44                   b = (BYTE)(ulConvertedPixel);
     45
     46                   ulConvertedPixel = ((r >> 3) << 11) + ((g >> 2) << 5) + (b >> 3);
     47               } break;
     48           }
     49        } break;
     50
     51        case 3:
     52        {
     53           switch (cbPixelTo)
     54           {
     55               case 2:
     56               {
     57                   memcpy (&ulConvertedPixel, pu8PixelFrom, 3);
     58
     59                   r = (BYTE)(ulConvertedPixel >> 16);
     60                   g = (BYTE)(ulConvertedPixel >> 8);
     61                   b = (BYTE)(ulConvertedPixel);
     62
     63                   ulConvertedPixel = ((r >> 3) << 11) + ((g >> 2) << 5) + (b >> 3);
     64               } break;
     65           }
     66        } break;
     67    }
     68
     69    return ulConvertedPixel;
     70}
     71
     72BOOL vbvaFindChangedRect (SURFOBJ *psoDest, SURFOBJ *psoSrc, RECTL *prclDest, POINTL *pptlSrc)
     73{
     74    int x, y;
     75    int fTopNonEqualFound;
     76    int yTopmost;
     77    int yBottommost;
     78    int cbPixelSrc;
     79    int cbPixelDest;
     80    RECTL rclDest;
     81    RECTL rclSrc;
     82    BYTE *pu8Src;
     83    BYTE *pu8Dest;
     84   
     85    if (!prclDest || !pptlSrc)
     86    {
     87        return TRUE;
     88    }
     89   
     90    DISPDBG((1, "vbvaFindChangedRect: dest %d,%d %dx%d from %d,%d\n",
     91             prclDest->left, prclDest->top, prclDest->right - prclDest->left, prclDest->bottom - prclDest->top,
     92             pptlSrc->x, pptlSrc->y
     93            ));
     94           
     95    switch (psoDest->iBitmapFormat)
     96    {
     97        case BMF_16BPP: cbPixelDest = 2; break;
     98        case BMF_24BPP: cbPixelDest = 3; break;
     99        case BMF_32BPP: cbPixelDest = 4; break;
     100        default: cbPixelDest = 0;
     101    }
     102
     103    switch (psoSrc->iBitmapFormat)
     104    {
     105        case BMF_16BPP: cbPixelSrc = 2; break;
     106        case BMF_24BPP: cbPixelSrc = 3; break;
     107        case BMF_32BPP: cbPixelSrc = 4; break;
     108        default: cbPixelSrc = 0;
     109    }
     110
     111    if (cbPixelDest == 0 || cbPixelSrc == 0)
     112    {
     113        DISPDBG((1, "vbvaFindChangedRect: unsupported pixel format src %d dst %d\n", psoDest->iBitmapFormat, psoSrc->iBitmapFormat));
     114        return TRUE;
     115    }
     116   
     117    rclDest = *prclDest;
     118   
     119    vrdpAdjustRect (psoDest, &rclDest);
     120   
     121    pptlSrc->x += rclDest.left - prclDest->left;
     122    pptlSrc->y += rclDest.top - prclDest->top;
     123   
     124    *prclDest = rclDest;
     125   
     126    if (   rclDest.right == rclDest.left
     127        || rclDest.bottom == rclDest.top)
     128    {
     129        DISPDBG((1, "vbvaFindChangedRect: empty dest rect: %d-%d, %d-%d\n", rclDest.left, rclDest.right, rclDest.top, rclDest.bottom));
     130        return FALSE;
     131    }
     132   
     133    rclSrc.left   = pptlSrc->x;
     134    rclSrc.top    = pptlSrc->y;
     135    rclSrc.right  = pptlSrc->x + (rclDest.right - rclDest.left);
     136    rclSrc.bottom = pptlSrc->y + (rclDest.bottom - rclDest.top);
     137    vrdpAdjustRect (psoSrc, &rclSrc);
     138   
     139    if (   rclSrc.right == rclSrc.left
     140        || rclSrc.bottom == rclSrc.top)
     141    {
     142         prclDest->right = prclDest->left;
     143         prclDest->bottom = prclDest->top;
     144         
     145         DISPDBG((1, "vbvaFindChangedRect: empty src rect: %d-%d, %d-%d\n", rclSrc.left, rclSrc.right, rclSrc.top, rclSrc.bottom));
     146         return FALSE;
     147    }
     148   
     149    VBVA_ASSERT(pptlSrc->x == rclSrc.left);
     150    VBVA_ASSERT(pptlSrc->y == rclSrc.top);
     151   
     152    /*
     153     * Compare the content of the screen surface (psoDest) with the source surface (psoSrc).
     154     * Update the prclDest with the rectangle that will be actually changed after
     155     * copying the source bits to the screen.
     156     */
     157    pu8Src = (BYTE *)psoSrc->pvScan0 + psoSrc->lDelta * pptlSrc->y + cbPixelSrc * pptlSrc->x;
     158    pu8Dest = (BYTE *)psoDest->pvScan0 + psoDest->lDelta * prclDest->top + cbPixelDest * prclDest->left;
     159   
     160    /* Use the rclDest as the bounding rectangle for the changed area. */
     161    rclDest.left   = prclDest->right;  /* +inf */
     162    rclDest.right  = prclDest->left;   /* -inf */
     163    rclDest.top    = prclDest->bottom; /* +inf */
     164    rclDest.bottom = prclDest->top;    /* -inf */
     165   
     166    fTopNonEqualFound = 0;
     167    yTopmost = prclDest->top;        /* inclusive */
     168    yBottommost = prclDest->top - 1; /* inclusive */
     169   
     170    for (y = prclDest->top; y < prclDest->bottom; y++)
     171    {
     172        int fLeftNonEqualFound = 0;
     173       
     174        /* Init to an empty line. */
     175        int xLeftmost = prclDest->left;      /* inclusive */
     176        int xRightmost = prclDest->left - 1; /* inclusive */
     177       
     178        BYTE *pu8SrcLine = pu8Src;
     179        BYTE *pu8DestLine = pu8Dest;
     180       
     181        for (x = prclDest->left; x < prclDest->right; x++)
     182        {
     183            int fEqualPixels;
     184           
     185            if (cbPixelSrc == cbPixelDest)
     186            {
     187                fEqualPixels = (memcmp (pu8SrcLine, pu8DestLine, cbPixelDest) == 0);
     188            }
     189            else
     190            {
     191                /* Convert larger pixel to the smaller pixel format. */
     192                ULONG ulConvertedPixel;
     193                if (cbPixelSrc > cbPixelDest)
     194                {
     195                    /* Convert the source pixel to the destination pixel format. */
     196                    ulConvertedPixel = vbvaConvertPixel ( /*from*/ pu8SrcLine, cbPixelSrc,
     197                                                          /*to*/ cbPixelDest);
     198                    fEqualPixels = (memcmp (&ulConvertedPixel, pu8DestLine, cbPixelDest) == 0);
     199                }
     200                else
     201                {
     202                    /* Convert the destination pixel to the source pixel format. */
     203                    ulConvertedPixel = vbvaConvertPixel ( /*from*/ pu8DestLine, cbPixelDest,
     204                                                          /*to*/ cbPixelSrc);
     205                    fEqualPixels = (memcmp (&ulConvertedPixel, pu8SrcLine, cbPixelSrc) == 0);
     206                }
     207            }
     208           
     209            if (fEqualPixels)
     210            {
     211                /* Equal pixels. */
     212                if (!fLeftNonEqualFound)
     213                {
     214                    xLeftmost = x;
     215                }
     216            }
     217            else
     218            {
     219                fLeftNonEqualFound = 1;
     220                xRightmost = x;
     221            }
     222           
     223            pu8SrcLine += cbPixelSrc;
     224            pu8DestLine += cbPixelDest;
     225        }
     226       
     227        /* min */
     228        if (rclDest.left > xLeftmost)
     229        {
     230            rclDest.left = xLeftmost;
     231        }
     232       
     233        /* max */
     234        if (rclDest.right < xRightmost)
     235        {
     236            rclDest.right = xRightmost;
     237        }
     238       
     239        if (xLeftmost > xRightmost) /* xRightmost is inclusive, so '>', not '>='. */
     240        {
     241            /* Empty line. */
     242            if (!fTopNonEqualFound)
     243            {
     244                yTopmost = y;
     245            }
     246        }
     247        else
     248        {
     249            fTopNonEqualFound = 1;
     250            yBottommost = y;
     251        }
     252       
     253        pu8Src += psoSrc->lDelta;
     254        pu8Dest += psoDest->lDelta;
     255    }
     256   
     257    /* min */
     258    if (rclDest.top > yTopmost)
     259    {
     260        rclDest.top = yTopmost;
     261    }
     262       
     263    /* max */
     264    if (rclDest.bottom < yBottommost)
     265    {
     266        rclDest.bottom = yBottommost;
     267    }
     268       
     269    /* rclDest was calculated with right-bottom inclusive.
     270     * The following checks and the caller require exclusive coords.
     271     */
     272    rclDest.right++;
     273    rclDest.bottom++;
     274   
     275    DISPDBG((1, "vbvaFindChangedRect: new dest %d,%d %dx%d from %d,%d\n",
     276             rclDest.left, rclDest.top, rclDest.right - rclDest.left, rclDest.bottom - rclDest.top,
     277             pptlSrc->x, pptlSrc->y
     278            ));
     279           
     280    /* Update the rectangle with the changed area. */
     281    if (   rclDest.left >= rclDest.right
     282        || rclDest.top >= rclDest.bottom)
     283    {
     284        /* Empty rect. */
     285        DISPDBG((1, "vbvaFindChangedRect: empty\n"));
     286        prclDest->right = prclDest->left;
     287        prclDest->bottom = prclDest->top;
     288        return FALSE;
     289    }
     290   
     291    DISPDBG((1, "vbvaFindChangedRect: not empty\n"));
     292   
     293    pptlSrc->x += rclDest.left - prclDest->left;
     294    pptlSrc->y += rclDest.top - prclDest->top;
     295   
     296    *prclDest = rclDest;
     297   
     298    return TRUE;
     299}
     300#endif /* VBOX_VBVA_ADJUST_RECT */
     301
    20302void vboxReportDirtyRect (PPDEV ppdev, RECTL *pRectOrig)
    21303{
     
    99381    PPDEV ppdev = (PPDEV)psoTrg->dhpdev;
    100382
    101     vbvaReportDirtyRect (ppdev, prclTrg);
     383    vbvaReportDirtyClip (ppdev, pco, prclTrg);
    102384}
    103385
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vrdp.c

    r4071 r4181  
    153153    if (prcl->top > prcl->bottom)
    154154    {
    155         DISPDBG((1, "vrdpAdjustRect: Inverse Y coordinates!!!\n"));
     155        DISPDBG((1, "vrdpOrderRect: Inverse Y coordinates!!!\n"));
    156156
    157157        tmp = prcl->top;
     
    162162
    163163
    164 static void vrdpAdjustRect (SURFOBJ *pso, RECTL *prcl)
     164void vrdpAdjustRect (SURFOBJ *pso, RECTL *prcl)
    165165{
    166166    int x;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette