/* Called to create DirectDraw surface. * Note: we always return DDHAL_DRIVER_NOTHANDLED, which asks DirectDraw memory manager * to perform actual memory allocation in our DDraw heap. */ DWORD APIENTRY VBoxDispDDCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpCreateSurface->lpDD->dhpdev; LOGF_ENTER(); PDD_SURFACE_LOCAL pSurf = lpCreateSurface->lplpSList[0]; if (pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { LOG(("primary surface")); pSurf->lpGbl->fpVidMem = 0; } else { LOG(("non primary surface")); pSurf->lpGbl->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE; } pSurf->lpGbl->dwReserved1 = 0; #ifdef VBOX_WITH_VIDEOHWACCEL if(pDev->vhwa.bEnabled) { VBOXVHWACMD* pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_CREATE, sizeof(VBOXVHWACMD_SURF_CREATE)); if (pCmd) { VBOXVHWACMD_SURF_CREATE *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE); PVBOXVHWASURFDESC pDesc; int rc; memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE)); rc = VBoxDispVHWAFromDDSURFACEDESC(&pBody->SurfInfo, lpCreateSurface->lpDDSurfaceDesc); VBOX_WARNRC(rc); pBody->SurfInfo.surfCaps = VBoxDispVHWAFromDDSCAPS(pSurf->ddsCaps.dwCaps); pBody->SurfInfo.flags |= DDSD_CAPS; pBody->SurfInfo.height = pSurf->lpGbl->wHeight; pBody->SurfInfo.width = pSurf->lpGbl->wWidth; pBody->SurfInfo.flags |= DDSD_HEIGHT | DDSD_WIDTH; VBoxDispVHWAFromDDPIXELFORMAT(&pBody->SurfInfo.PixelFormat, &pSurf->lpGbl->ddpfSurface); pBody->SurfInfo.flags |= VBOXVHWA_SD_PIXELFORMAT; if (pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { pBody->SurfInfo.offSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, 0); } else { pBody->SurfInfo.offSurface = VBOXVHWA_OFFSET64_VOID; } pDesc = VBoxDispVHWASurfDescAlloc(); if (pDesc) { VBoxDispVHWACommandSubmit(pDev, pCmd); if (RT_SUCCESS(pCmd->rc)) { uint32_t surfSizeX = pBody->SurfInfo.sizeX; uint32_t surfSizeY = pBody->SurfInfo.sizeY; pDesc->hHostHandle = pBody->SurfInfo.hSurf; if(!!(pSurf->ddsCaps.dwCaps & DDSCAPS_OVERLAY) && !!(pSurf->ddsCaps.dwCaps & DDSCAPS_VISIBLE)) { pDesc->bVisible = true; } pSurf->lpGbl->dwBlockSizeX = pBody->SurfInfo.sizeX; pSurf->lpGbl->dwBlockSizeY = pBody->SurfInfo.sizeY; pSurf->lpGbl->lPitch = pBody->SurfInfo.pitch; lpCreateSurface->lpDDSurfaceDesc->lPitch = pSurf->lpGbl->lPitch; lpCreateSurface->lpDDSurfaceDesc->dwFlags |= DDSD_PITCH; /*@todo: it's probably a memory leak, because DDDestroySurface wouldn't be called for * primary surfaces. */ pSurf->lpGbl->dwReserved1 = (ULONG_PTR)pDesc; } else { WARN(("VBoxDispVHWACommandSubmit failed with rc=%#x", rc)); VBoxDispVHWASurfDescFree(pDesc); } } else { WARN(("VBoxDispVHWASurfDescAlloc failed")); } VBoxDispVHWACommandRelease(pDev, pCmd); } else { WARN(("VBoxDispVHWACommandCreate failed")); } return DDHAL_DRIVER_NOTHANDLED; } #endif /*VBOX_WITH_VIDEOHWACCEL*/ LPDDSURFACEDESC pDesc = lpCreateSurface->lpDDSurfaceDesc; if (pDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) { pSurf->lpGbl->lPitch = RT_ALIGN_T(pSurf->lpGbl->wWidth/2, 32, LONG); } else if (pDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { pSurf->lpGbl->lPitch = RT_ALIGN_T(pSurf->lpGbl->wWidth, 32, LONG); } else { pSurf->lpGbl->lPitch = pSurf->lpGbl->wWidth*(pDesc->ddpfPixelFormat.dwRGBBitCount/8); } pSurf->lpGbl->dwBlockSizeX = pSurf->lpGbl->lPitch; pSurf->lpGbl->dwBlockSizeY = pSurf->lpGbl->wHeight; pDesc->lPitch = pSurf->lpGbl->lPitch; pDesc->dwFlags |= DDSD_PITCH; LOGF_LEAVE(); return DDHAL_DRIVER_NOTHANDLED; }
int VBoxDispVHWAFromDDSURFACEDESC(VBOXVHWA_SURFACEDESC *pVHWADesc, DDSURFACEDESC *pDdDesc) { uint32_t unsupds = VBoxDispVHWAUnsupportedDSS(pDdDesc->dwFlags); Assert(!unsupds); if(unsupds) return VERR_GENERAL_FAILURE; pVHWADesc->flags = 0; if(pDdDesc->dwFlags & DDSD_BACKBUFFERCOUNT) { pVHWADesc->flags |= VBOXVHWA_SD_BACKBUFFERCOUNT; pVHWADesc->cBackBuffers = pDdDesc->dwBackBufferCount; } if(pDdDesc->dwFlags & DDSD_CAPS) { uint32_t unsup = VBoxDispVHWAUnsupportedDDSCAPS(pDdDesc->ddsCaps.dwCaps); Assert(!unsup); if(unsup) return VERR_GENERAL_FAILURE; pVHWADesc->flags |= VBOXVHWA_SD_CAPS; pVHWADesc->surfCaps = VBoxDispVHWAFromDDSCAPS(pDdDesc->ddsCaps.dwCaps); } if(pDdDesc->dwFlags & DDSD_CKDESTBLT) { pVHWADesc->flags |= VBOXVHWA_SD_CKDESTBLT; VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->DstBltCK, &pDdDesc->ddckCKDestBlt); } if(pDdDesc->dwFlags & DDSD_CKDESTOVERLAY) { pVHWADesc->flags |= VBOXVHWA_SD_CKDESTOVERLAY; VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->DstOverlayCK, &pDdDesc->ddckCKDestOverlay); } if(pDdDesc->dwFlags & DDSD_CKSRCBLT) { pVHWADesc->flags |= VBOXVHWA_SD_CKSRCBLT; VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->SrcBltCK, &pDdDesc->ddckCKSrcBlt); } if(pDdDesc->dwFlags & DDSD_CKSRCOVERLAY) { pVHWADesc->flags |= VBOXVHWA_SD_CKSRCOVERLAY; VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->SrcOverlayCK, &pDdDesc->ddckCKSrcOverlay); } if(pDdDesc->dwFlags & DDSD_HEIGHT) { pVHWADesc->flags |= VBOXVHWA_SD_HEIGHT; pVHWADesc->height = pDdDesc->dwHeight; } if(pDdDesc->dwFlags & DDSD_WIDTH) { pVHWADesc->flags |= VBOXVHWA_SD_WIDTH; pVHWADesc->width = pDdDesc->dwWidth; } if(pDdDesc->dwFlags & DDSD_PITCH) { pVHWADesc->flags |= VBOXVHWA_SD_PITCH; pVHWADesc->pitch = pDdDesc->lPitch; } if(pDdDesc->dwFlags & DDSD_PIXELFORMAT) { int rc = VBoxDispVHWAFromDDPIXELFORMAT(&pVHWADesc->PixelFormat, &pDdDesc->ddpfPixelFormat); if(RT_FAILURE(rc)) return rc; pVHWADesc->flags |= VBOXVHWA_SD_PIXELFORMAT; } return VINF_SUCCESS; }