VirtualBox

Changeset 83354 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Mar 20, 2020 4:19:35 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
136558
Message:

VMSVGA: Implemented SVGA_CMD_RECT_COPY (see bugref:9424).

Location:
trunk/src/VBox/Devices/Graphics
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp

    r83305 r83354  
    270270    STAMCOUNTER             StatR3CmdMoveCursor;
    271271    STAMCOUNTER             StatR3CmdDisplayCursor;
     272    STAMCOUNTER             StatR3CmdRectFill;
     273    STAMCOUNTER             StatR3CmdRectCopy;
     274    STAMCOUNTER             StatR3CmdRectRopCopy;
    272275    STAMCOUNTER             StatR3CmdEscape;
    273276    STAMCOUNTER             StatR3CmdDefineScreen;
     
    435438    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatR3CmdMoveCursor),
    436439    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatR3CmdDisplayCursor),
     440    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatR3CmdRectFill),
     441    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatR3CmdRectCopy),
     442    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatR3CmdRectRopCopy),
    437443    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatR3CmdEscape),
    438444    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatR3CmdDefineScreen),
     
    665671        case SVGA_CMD_UPDATE:                   return "SVGA_CMD_UPDATE";
    666672        case SVGA_CMD_RECT_COPY:                return "SVGA_CMD_RECT_COPY";
     673        case SVGA_CMD_RECT_ROP_COPY:            return "SVGA_CMD_RECT_ROP_COPY";
    667674        case SVGA_CMD_DEFINE_CURSOR:            return "SVGA_CMD_DEFINE_CURSOR";
    668675        case SVGA_CMD_DISPLAY_CURSOR:           return "SVGA_CMD_DISPLAY_CURSOR";
     
    15921599}
    15931600
     1601
     1602/**
     1603 * Copy a rectangle of pixels within guest VRAM.
     1604 */
     1605static void vmsvgaR3RectCopy(PVGASTATECC pThisCC, VMSVGASCREENOBJECT const *pScreen, uint32_t srcX, uint32_t srcY,
     1606                             uint32_t dstX, uint32_t dstY, uint32_t width, uint32_t height, unsigned cbFrameBuffer)
     1607{
     1608    if (!width || !height)
     1609        return; /* Nothing to do, don't even bother. */
     1610
     1611    /*
     1612     * The guest VRAM (aka GFB) is considered to be a bitmap in the format
     1613     * corresponding to the current display mode.
     1614     */
     1615    uint32_t const  cbPixel = RT_ALIGN(pScreen->cBpp, 8) / 8;
     1616    uint32_t const  cbScanline = pScreen->cbPitch ? pScreen->cbPitch : width * cbPixel;
     1617    uint8_t const   *pSrc;
     1618    uint8_t         *pDst;
     1619    unsigned const  cbRectWidth = width * cbPixel;
     1620    unsigned        uMaxOffset;
     1621
     1622    uMaxOffset = (RT_MAX(srcY, dstY) + height) * cbScanline + (RT_MAX(srcX, dstX) + width) * cbPixel;
     1623    if (uMaxOffset >= cbFrameBuffer)
     1624    {
     1625        Log(("Max offset (%u) too big for framebuffer (%u bytes), ignoring!\n", uMaxOffset, cbFrameBuffer));
     1626        return; /* Just don't listen to a bad guest. */
     1627    }
     1628
     1629    pSrc = pDst = pThisCC->pbVRam;
     1630    pSrc += srcY * cbScanline + srcX * cbPixel;
     1631    pDst += dstY * cbScanline + dstX * cbPixel;
     1632
     1633    if (srcY >= dstY)
     1634    {
     1635        /* Source below destination, copy top to bottom. */
     1636        for (; height > 0; height--)
     1637        {
     1638            memmove(pDst, pSrc, cbRectWidth);
     1639            pSrc += cbScanline;
     1640            pDst += cbScanline;
     1641        }
     1642    }
     1643    else
     1644    {
     1645        /* Source above destination, copy bottom to top. */
     1646        pSrc += cbScanline * (height - 1);
     1647        pDst += cbScanline * (height - 1);
     1648        for (; height > 0; height--)
     1649        {
     1650            memmove(pDst, pSrc, cbRectWidth);
     1651            pSrc -= cbScanline;
     1652            pDst -= cbScanline;
     1653        }
     1654    }
     1655}
     1656
    15941657#endif /* IN_RING3 */
    15951658
     
    39424005            }
    39434006
     4007            case SVGA_CMD_RECT_FILL:
     4008            {
     4009                SVGAFifoCmdRectFill *pRectFill;
     4010                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pRectFill, SVGAFifoCmdRectFill, sizeof(*pRectFill));
     4011                STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdRectFill);
     4012
     4013                Log(("vmsvgaR3FifoLoop: RECT FILL %08X @ %d,%d (%dx%d)\n", pRectFill->pixel, pRectFill->destX, pRectFill->destY, pRectFill->width, pRectFill->height));
     4014                LogRelMax(4, ("Unsupported SVGA_CMD_RECT_FILL command ignored.\n"));
     4015                break;
     4016            }
     4017
     4018            case SVGA_CMD_RECT_COPY:
     4019            {
     4020                SVGAFifoCmdRectCopy *pRectCopy;
     4021                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pRectCopy, SVGAFifoCmdRectCopy, sizeof(*pRectCopy));
     4022                STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdRectCopy);
     4023
     4024                Log(("vmsvgaR3FifoLoop: RECT COPY %d,%d -> %d,%d (%dx%d)\n", pRectCopy->srcX, pRectCopy->srcY, pRectCopy->destX, pRectCopy->destY, pRectCopy->width, pRectCopy->height));
     4025                VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0);
     4026                AssertBreak(pScreen);
     4027
     4028                /* Check that arguments aren't complete junk. A precise check is done in vmsvgaR3RectCopy(). */
     4029                AssertBreak(pRectCopy->srcX < pThis->svga.u32MaxWidth);
     4030                AssertBreak(pRectCopy->destX < pThis->svga.u32MaxWidth);
     4031                AssertBreak(pRectCopy->width < pThis->svga.u32MaxWidth);
     4032                AssertBreak(pRectCopy->srcY < pThis->svga.u32MaxHeight);
     4033                AssertBreak(pRectCopy->destY < pThis->svga.u32MaxHeight);
     4034                AssertBreak(pRectCopy->height < pThis->svga.u32MaxHeight);
     4035
     4036                vmsvgaR3RectCopy(pThisCC, pScreen, pRectCopy->srcX, pRectCopy->srcY, pRectCopy->destX, pRectCopy->destY,
     4037                                 pRectCopy->width, pRectCopy->height, pThis->vram_size);
     4038                vmsvgaR3UpdateScreen(pThisCC, pScreen, pRectCopy->destX, pRectCopy->destY, pRectCopy->width, pRectCopy->height);
     4039                break;
     4040            }
     4041
     4042            case SVGA_CMD_RECT_ROP_COPY:
     4043            {
     4044                SVGAFifoCmdRectRopCopy *pRRCopy;
     4045                VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pRRCopy, SVGAFifoCmdRectRopCopy, sizeof(*pRRCopy));
     4046                STAM_REL_COUNTER_INC(&pSVGAState->StatR3CmdRectRopCopy);
     4047
     4048                Log(("vmsvgaR3FifoLoop: RECT ROP COPY %d,%d -> %d,%d (%dx%d) ROP %X\n", pRRCopy->srcX, pRRCopy->srcY, pRRCopy->destX, pRRCopy->destY, pRRCopy->width, pRRCopy->height, pRRCopy->rop));
     4049                if (pRRCopy->rop != SVGA_ROP_COPY)
     4050                {
     4051                    /* We only support the plain copy ROP which makes SVGA_CMD_RECT_ROP_COPY exactly the same
     4052                     * as SVGA_CMD_RECT_COPY. XFree86 4.1.0 and 4.2.0 drivers (driver version 10.4.0 and 10.7.0,
     4053                     * respectively) issue SVGA_CMD_RECT_ROP_COPY when SVGA_CAP_RECT_COPY is present even when
     4054                     * SVGA_CAP_RASTER_OP is not. However, the ROP will always be SVGA_ROP_COPY.
     4055                     */
     4056                    LogRelMax(4, ("RECT ROP COPY %d,%d -> %d,%d (%dx%d) ROP %X unsupported\n", pRRCopy->srcX, pRRCopy->srcY, pRRCopy->destX, pRRCopy->destY, pRRCopy->width, pRRCopy->height, pRRCopy->rop));
     4057                    break;
     4058                }
     4059
     4060                VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0);
     4061                AssertBreak(pScreen);
     4062
     4063                /* Check that arguments aren't complete junk. A precise check is done in vmsvgaR3RectCopy(). */
     4064                AssertBreak(pRRCopy->srcX < pThis->svga.u32MaxWidth);
     4065                AssertBreak(pRRCopy->destX < pThis->svga.u32MaxWidth);
     4066                AssertBreak(pRRCopy->width < pThis->svga.u32MaxWidth);
     4067                AssertBreak(pRRCopy->srcY < pThis->svga.u32MaxHeight);
     4068                AssertBreak(pRRCopy->destY < pThis->svga.u32MaxHeight);
     4069                AssertBreak(pRRCopy->height < pThis->svga.u32MaxHeight);
     4070
     4071                vmsvgaR3RectCopy(pThisCC, pScreen, pRRCopy->srcX, pRRCopy->srcY, pRRCopy->destX, pRRCopy->destY,
     4072                                 pRRCopy->width, pRRCopy->height, pThis->vram_size);
     4073                vmsvgaR3UpdateScreen(pThisCC, pScreen, pRRCopy->destX, pRRCopy->destY, pRRCopy->width, pRRCopy->height);
     4074                break;
     4075            }
     4076
    39444077            case SVGA_CMD_ESCAPE:
    39454078            {
     
    44584591                break;
    44594592            }
    4460 
    4461             /** @todo SVGA_CMD_RECT_COPY  - see with ubuntu */
    44624593
    44634594            default:
     
    58886019    if (pSVGAState->Cursor.fActive)
    58896020    {
     6021        /* We don't store the alpha flag, but we can take a guess that if
     6022         * the old register interface was used, the cursor was B&W.
     6023         */
     6024        bool    fAlpha = pThis->svga.uCursorOn ? false : true;
     6025
    58906026        int rc = pThisCC->pDrv->pfnVBVAMousePointerShape(pThisCC->pDrv,
    58916027                                                         true /*fVisible*/,
    5892                                                          true /*fAlpha*/,
     6028                                                         fAlpha,
    58936029                                                         pSVGAState->Cursor.xHotspot,
    58946030                                                         pSVGAState->Cursor.yHotspot,
     
    58976033                                                         pSVGAState->Cursor.pData);
    58986034        AssertRC(rc);
     6035
     6036        if (pThis->svga.uCursorOn)
     6037            pThisCC->pDrv->pfnVBVAReportCursorPosition(pThisCC->pDrv, VBVA_CURSOR_VALID_DATA, SVGA_ID_INVALID, pThis->svga.uCursorX, pThis->svga.uCursorY);
    58996038    }
    59006039
     
    60736212                           | SVGA_CAP_IRQMASK
    60746213                           | SVGA_CAP_PITCHLOCK
     6214                           | SVGA_CAP_RECT_COPY
    60756215                           | SVGA_CAP_TRACES
    60766216                           | SVGA_CAP_SCREEN_OBJECT_2
     
    65226662    REG_CNT(&pSVGAState->StatR3CmdMoveCursor,             "VMSVGA/Cmd/MoveCursor",                 "SVGA_CMD_MOVE_CURSOR");
    65236663    REG_CNT(&pSVGAState->StatR3CmdDisplayCursor,          "VMSVGA/Cmd/DisplayCursor",              "SVGA_CMD_DISPLAY_CURSOR");
     6664    REG_CNT(&pSVGAState->StatR3CmdRectFill,               "VMSVGA/Cmd/RectFill",                   "SVGA_CMD_RECT_FILL");
     6665    REG_CNT(&pSVGAState->StatR3CmdRectCopy,               "VMSVGA/Cmd/RectCopy",                   "SVGA_CMD_RECT_COPY");
     6666    REG_CNT(&pSVGAState->StatR3CmdRectRopCopy,            "VMSVGA/Cmd/RectRopCopy",                "SVGA_CMD_RECT_ROP_COPY");
    65246667    REG_CNT(&pSVGAState->StatR3CmdDefineGmr2,             "VMSVGA/Cmd/DefineGmr2",                 "SVGA_CMD_DEFINE_GMR2");
    65256668    REG_CNT(&pSVGAState->StatR3CmdDefineGmr2Free,         "VMSVGA/Cmd/DefineGmr2/Free",            "Number of SVGA_CMD_DEFINE_GMR2 commands that only frees.");
  • trunk/src/VBox/Devices/Graphics/vmsvga/svga_reg.h

    r83274 r83354  
    10111011   SVGA_CMD_INVALID_CMD           = 0,
    10121012   SVGA_CMD_UPDATE                = 1,
     1013   SVGA_CMD_RECT_FILL             = 2,  // No longer documented, used by old drivers.
    10131014   SVGA_CMD_RECT_COPY             = 3,
     1015   SVGA_CMD_RECT_ROP_COPY         = 14, // No longer documented, used by old drivers.
    10141016   SVGA_CMD_DEFINE_CURSOR         = 19,
    10151017   SVGA_CMD_DISPLAY_CURSOR        = 20, // Deprecated.
     
    10741076
    10751077/*
     1078 * SVGA_CMD_RECT_FILL --
     1079 *
     1080 *    Fill a rectangular area in the the GFB, and copy the result
     1081 *    to any screens which intersect it.
     1082 *
     1083 *    Deprecated?
     1084 *
     1085 * Availability:
     1086 *    SVGA_CAP_RECT_FILL
     1087 */
     1088
     1089typedef
     1090struct {
     1091   uint32_t pixel;
     1092   uint32_t destX;
     1093   uint32_t destY;
     1094   uint32_t width;
     1095   uint32_t height;
     1096} SVGAFifoCmdRectFill;
     1097
     1098
     1099/*
    10761100 * SVGA_CMD_RECT_COPY --
    10771101 *
     
    10921116   uint32_t height;
    10931117} SVGAFifoCmdRectCopy;
     1118
     1119
     1120/*
     1121 * SVGA_CMD_RECT_ROP_COPY --
     1122 *
     1123 *    Perform a rectangular DMA transfer from one area of the GFB to
     1124 *    another using a a raster op, and copy the result to any screens
     1125 *    which intersect it.
     1126 *
     1127 *    XFree86 4.1.0/4.2.0 drivers incorrectly use this command when
     1128 *    SVGA_CAP_RECT_COPY is present even when SVGA_CAP_RASTER_OP is not.
     1129 *
     1130 * Availability:
     1131 *    SVGA_CAP_RECT_COPY + SVGA_CAP_RASTER_OP
     1132 */
     1133
     1134typedef
     1135struct {
     1136   uint32_t srcX;
     1137   uint32_t srcY;
     1138   uint32_t destX;
     1139   uint32_t destY;
     1140   uint32_t width;
     1141   uint32_t height;
     1142   uint32_t rop;
     1143} SVGAFifoCmdRectRopCopy;
    10941144
    10951145
Note: See TracChangeset for help on using the changeset viewer.

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