VirtualBox

Changeset 95288 in vbox for trunk/src/VBox/Devices/Graphics


Ignore:
Timestamp:
Jun 15, 2022 3:11:14 PM (3 years ago)
Author:
vboxsync
Message:

Devices/Graphics: generic screen update function. bugref:9830

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

Legend:

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

    r95249 r95288  
    19711971                        pSvgaR3State->pFuncsGBO->pfnScreenTargetUpdate(pThisCC, pScreen, &targetRect);
    19721972                    }
    1973                     else if (pScreen->pvScreenBitmap)
     1973                    else
    19741974                    {
    1975                         /* Copy the screen target surface to the memory buffer. */
    1976                         SVGA3dBox box; /* SurfaceMap will clip the box as necessary. */
    1977                         box.x = pCmd->rect.x;
    1978                         box.y = pCmd->rect.y;
    1979                         box.z = 0;
    1980                         box.w = pCmd->rect.w;
    1981                         box.h = pCmd->rect.h;
    1982                         box.d = 1;
    1983 
    1984                         VMSVGA3D_MAPPED_SURFACE map;
    1985                         rc = vmsvga3dSurfaceMap(pThisCC, &entryScreenTarget.image, &box, VMSVGA3D_SURFACE_MAP_READ, &map);
    1986                         if (RT_SUCCESS(rc))
    1987                         {
    1988                             VMSGA3D_BOX_DIMENSIONS dims;
    1989                             rc = vmsvga3dGetBoxDimensions(pThisCC, &entryScreenTarget.image, &map.box, &dims);
    1990                             if (RT_SUCCESS(rc))
    1991                             {
    1992                                 uint8_t const *pu8Src = (uint8_t *)map.pvData;
    1993                                 uint8_t *pu8Dst = (uint8_t *)pScreen->pvScreenBitmap + dims.offSubresource + dims.offBox;
    1994                                 for (uint32_t iRow = 0; iRow < map.cRows; ++iRow)
    1995                                 {
    1996                                     memcpy(pu8Dst, pu8Src, dims.cbRow);
    1997 
    1998                                     pu8Src += map.cbRowPitch;
    1999                                     pu8Dst += dims.cbPitch;
    2000                                 }
    2001                             }
    2002 
    2003                             vmsvga3dSurfaceUnmap(pThisCC, &entryScreenTarget.image, &map, /* fWritten =  */ false);
    2004 
    2005                             vmsvgaR3UpdateScreen(pThisCC, pScreen, map.box.x, map.box.y, map.box.w, map.box.h);
    2006                         }
    2007                         else
    2008                             AssertFailed();
     1975                        SVGASignedRect r;
     1976                        r.left   = pCmd->rect.x;
     1977                        r.top    = pCmd->rect.y;
     1978                        r.right  = pCmd->rect.x + pCmd->rect.w;
     1979                        r.bottom = pCmd->rect.y + pCmd->rect.h;
     1980                        vmsvga3dScreenUpdate(pThisCC, pCmd->stid, r, entryScreenTarget.image, r, 0, NULL);
    20091981                    }
    20101982                }
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp

    r95231 r95288  
    965965    src.face = 0;
    966966
     967    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
    967968    if (pScreen->pHwScreen)
    968969    {
    969970        /* Use the backend accelerated method, if available. */
    970         PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
    971971        if (pSvgaR3State->pFuncs3D)
    972972        {
     
    978978        }
    979979    }
     980
     981    if (pSvgaR3State->pFuncsMap)
     982        return vmsvga3dScreenUpdate(pThisCC, idDstScreen, destRect, src, srcRect, cRects, pRect);
    980983
    981984    /** @todo scaling */
     
    10501053}
    10511054
     1055int vmsvga3dScreenUpdate(PVGASTATECC pThisCC, uint32_t idDstScreen, SVGASignedRect const &dstRect,
     1056                         SVGA3dSurfaceImageId const &srcImage, SVGASignedRect const &srcRect,
     1057                         uint32_t cDstClipRects, SVGASignedRect *paDstClipRect)
     1058{
     1059    //DEBUG_BREAKPOINT_TEST();
     1060    PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
     1061
     1062#ifdef LOG_ENABLED
     1063    LogFunc(("[%u] %d,%d %d,%d (%dx%d) -> %d,%d %d,%d (%dx%d), %u clip rects\n",
     1064             idDstScreen, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom,
     1065             srcRect.right - srcRect.left, srcRect.bottom - srcRect.top,
     1066             dstRect.left, dstRect.top, dstRect.right, dstRect.bottom,
     1067             dstRect.right - dstRect.left, dstRect.bottom - dstRect.top, cDstClipRects));
     1068    for (uint32_t i = 0; i < cDstClipRects; i++)
     1069    {
     1070        LogFunc(("  [%u] %d,%d %d,%d (%dx%d)\n",
     1071                 i, paDstClipRect[i].left, paDstClipRect[i].top, paDstClipRect[i].right, paDstClipRect[i].bottom,
     1072                 paDstClipRect[i].right - paDstClipRect[i].left, paDstClipRect[i].bottom - paDstClipRect[i].top));
     1073    }
     1074#endif
     1075
     1076    PVMSVGA3DSURFACE pSurface;
     1077    int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, srcImage.sid, &pSurface);
     1078    AssertRCReturn(rc, rc);
     1079
     1080    /* Update the screen from a surface. */
     1081    ASSERT_GUEST_RETURN(idDstScreen < RT_ELEMENTS(pSvgaR3State->aScreens), VERR_INVALID_PARAMETER);
     1082    RT_UNTRUSTED_VALIDATED_FENCE();
     1083
     1084    VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[idDstScreen];
     1085
     1086    if (   srcRect.right <= srcRect.left
     1087        || srcRect.bottom <= srcRect.top)
     1088        return VINF_SUCCESS; /* Empty src rect. */
     1089
     1090    if (   dstRect.right <= dstRect.left
     1091        || dstRect.bottom <= dstRect.top)
     1092        return VINF_SUCCESS; /* Empty dst rect. */
     1093    RT_UNTRUSTED_VALIDATED_FENCE();
     1094
     1095    ASSERT_GUEST_RETURN(   srcRect.right - srcRect.left == dstRect.right - dstRect.left
     1096                        && srcRect.bottom - srcRect.top == dstRect.bottom - dstRect.top,
     1097                        VERR_INVALID_PARAMETER); /* Stretch is not supported. */
     1098
     1099    /* Destination box should be within the screen rectangle. */
     1100    SVGA3dBox dstBox;
     1101    dstBox.x = dstRect.left;
     1102    dstBox.y = dstRect.top;
     1103    dstBox.z = 0;
     1104    dstBox.w = dstRect.right - dstRect.left;
     1105    dstBox.h = dstRect.bottom - dstRect.top;
     1106    dstBox.d = 1;
     1107
     1108    SVGA3dSize dstBound;
     1109    dstBound.width = pScreen->cWidth;
     1110    dstBound.height = pScreen->cHeight;
     1111    dstBound.depth = 1;
     1112
     1113    vmsvgaR3ClipBox(&dstBound, &dstBox);
     1114    ASSERT_GUEST_RETURN(dstBox.w > 0 && dstBox.h > 0, VERR_INVALID_PARAMETER);
     1115    RT_UNTRUSTED_VALIDATED_FENCE();
     1116
     1117    /* All dst clip rects will be clipped by the dst box because
     1118     * "The clip rectangle coordinates are measured relative to the top-left corner of destRect."
     1119     * Therefore they are relative to the top-left corner of srcRect as well.
     1120     */
     1121    dstBound.width = dstBox.w;
     1122    dstBound.height = dstBox.h;
     1123    dstBound.depth = 1;
     1124
     1125    SVGA3dBox srcBox; /* SurfaceMap will clip the box as necessary (srcMap.box). */
     1126    srcBox.x = srcRect.left;
     1127    srcBox.y = srcRect.top;
     1128    srcBox.z = 0;
     1129    srcBox.w = srcRect.right - srcRect.left;
     1130    srcBox.h = srcRect.bottom - srcRect.top;
     1131    srcBox.d = 1;
     1132
     1133    VMSVGA3D_MAPPED_SURFACE srcMap;
     1134    rc = vmsvga3dSurfaceMap(pThisCC, &srcImage, &srcBox, VMSVGA3D_SURFACE_MAP_READ, &srcMap);
     1135    if (RT_SUCCESS(rc))
     1136    {
     1137        uint8_t const *pu8Src = (uint8_t *)srcMap.pvData;
     1138
     1139        uint32_t const cbDst = pScreen->cHeight * pScreen->cbPitch;
     1140        uint8_t *pu8Dst;
     1141        if (pScreen->pvScreenBitmap)
     1142            pu8Dst = (uint8_t *)pScreen->pvScreenBitmap;
     1143        else
     1144            pu8Dst = (uint8_t *)pThisCC->pbVRam + pScreen->offVRAM;
     1145
     1146        SVGASignedRect dstClipRect;
     1147        if (cDstClipRects == 0)
     1148        {
     1149            /* Entire source rect "relative to the top-left corner of destRect." */
     1150            dstClipRect.left   = 0;
     1151            dstClipRect.top    = 0;
     1152            dstClipRect.right  = dstBox.w;
     1153            dstClipRect.bottom = dstBox.h;
     1154
     1155            cDstClipRects = 1;
     1156            paDstClipRect = &dstClipRect;
     1157        }
     1158
     1159        for (uint32_t i = 0; i < cDstClipRects; i++)
     1160        {
     1161            SVGASignedRect const *pDstClipRect = &paDstClipRect[i];
     1162
     1163            SVGA3dBox box;
     1164            box.x = pDstClipRect->left;
     1165            box.y = pDstClipRect->top;
     1166            box.z = 0;
     1167            box.w = pDstClipRect->right - pDstClipRect->left;
     1168            box.h = pDstClipRect->bottom - pDstClipRect->top;
     1169            box.d = 1;
     1170
     1171            vmsvgaR3ClipBox(&dstBound, &box);
     1172            ASSERT_GUEST_CONTINUE(box.w > 0 && box.h > 0);
     1173
     1174            /* 'pu8Src' points to the mapped 'srcRect'. Take the clipping box into account. */
     1175            uint8_t const *pu8SrcBox = pu8Src
     1176                + ((box.x + pSurface->cxBlock - 1) / pSurface->cxBlock) * pSurface->cxBlock * pSurface->cbBlock
     1177                + ((box.y + pSurface->cyBlock - 1) / pSurface->cyBlock) * pSurface->cyBlock * srcMap.cbRowPitch;
     1178
     1179            /* The 'box' is actually in the destination coordinates relative to the top-left corner of destRect.
     1180             * Therefore it is relative to the top-left corner of srcRect as well.
     1181             */
     1182            box.x += srcBox.x;
     1183            box.y += srcBox.y;
     1184
     1185            VMSGA3D_BOX_DIMENSIONS srcDims;
     1186            rc = vmsvga3dGetBoxDimensions(pThisCC, &srcImage, &box, &srcDims);
     1187            if (RT_SUCCESS(rc))
     1188            {
     1189                AssertContinue(srcDims.cyBlocks > 0);
     1190
     1191                ASSERT_GUEST_BREAK(   srcDims.offBox <= cbDst
     1192                                   && pScreen->cbPitch * (srcDims.cyBlocks - 1) + srcDims.cbRow <= cbDst - srcDims.offBox);
     1193                RT_UNTRUSTED_VALIDATED_FENCE();
     1194
     1195                uint8_t *pu8DstBox = pu8Dst + srcDims.offBox;
     1196
     1197                if (   pSurface->format == SVGA3D_R8G8B8A8_UNORM
     1198                    || pSurface->format == SVGA3D_R8G8B8A8_UNORM_SRGB)
     1199                {
     1200                    for (uint32_t iRow = 0; iRow < srcDims.cyBlocks; ++iRow)
     1201                    {
     1202                        for (uint32_t x = 0; x < box.w * 4; x += 4) /* 'x' is a byte index. */
     1203                        {
     1204                            pu8DstBox[x    ] = pu8SrcBox[x + 2];
     1205                            pu8DstBox[x + 1] = pu8SrcBox[x + 1];
     1206                            pu8DstBox[x + 2] = pu8SrcBox[x    ];
     1207                            pu8DstBox[x + 3] = pu8SrcBox[x + 3];
     1208                        }
     1209
     1210                        pu8SrcBox += srcMap.cbRowPitch;
     1211                        pu8DstBox += pScreen->cbPitch;
     1212                    }
     1213                }
     1214                else
     1215                {
     1216                    for (uint32_t iRow = 0; iRow < srcDims.cyBlocks; ++iRow)
     1217                    {
     1218                        memcpy(pu8DstBox, pu8SrcBox, srcDims.cbRow);
     1219
     1220                        pu8SrcBox += srcMap.cbRowPitch;
     1221                        pu8DstBox += pScreen->cbPitch;
     1222                    }
     1223                }
     1224            }
     1225        }
     1226
     1227        vmsvga3dSurfaceUnmap(pThisCC, &srcImage, &srcMap, /* fWritten =  */ false);
     1228
     1229        vmsvgaR3UpdateScreen(pThisCC, pScreen, dstBox.x, dstBox.y, dstBox.w, dstBox.h);
     1230    }
     1231
     1232    return rc;
     1233}
     1234
    10521235int vmsvga3dCommandPresent(PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t sid, uint32_t cRects, SVGA3dCopyRect *pRect)
    10531236{
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h

    r95231 r95288  
    116116int vmsvga3dDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen);
    117117int vmsvga3dDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen);
     118
     119int vmsvga3dScreenUpdate(PVGASTATECC pThisCC, uint32_t idDstScreen, SVGASignedRect const &dstRect,
     120                         SVGA3dSurfaceImageId const &srcImage, SVGASignedRect const &srcRect,
     121                         uint32_t cDstClipRects, SVGASignedRect *paDstClipRect);
    118122
    119123int vmsvga3dSetTransform(PVGASTATECC pThisCC, uint32_t cid, SVGA3dTransformType type, float matrix[16]);
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