VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriverDDraw.cpp@ 69496

Last change on this file since 69496 was 69496, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1/* $Id: VBoxDispDriverDDraw.cpp 69496 2017-10-28 14:55:58Z vboxsync $ */
2/** @file
3 * VBox XPDM Display driver interface functions related to DirectDraw
4 */
5
6/*
7 * Copyright (C) 2011-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "VBoxDisp.h"
19#include "VBoxDispDDraw.h"
20
21static void VBoxDispGetDDHalInfo(PVBOXDISPDEV pDev, DD_HALINFO *pHalInfo)
22{
23 memset(pHalInfo, 0, sizeof(DD_HALINFO));
24 pHalInfo->dwSize = sizeof(DD_HALINFO);
25
26 /* memory info */
27
28 pHalInfo->vmiData.fpPrimary = pDev->layout.offFramebuffer;
29 /*pHalInfo->vmiData.dwFlags /*unused*/
30 pHalInfo->vmiData.dwDisplayWidth = pDev->mode.ulWidth;
31 pHalInfo->vmiData.dwDisplayHeight = pDev->mode.ulHeight;
32 pHalInfo->vmiData.lDisplayPitch = pDev->mode.lScanlineStride;
33
34 pHalInfo->vmiData.ddpfDisplay.dwSize = sizeof(DDPIXELFORMAT);
35 pHalInfo->vmiData.ddpfDisplay.dwFlags = DDPF_RGB;
36 if (pDev->surface.ulFormat == BMF_8BPP)
37 {
38 pHalInfo->vmiData.ddpfDisplay.dwFlags |= DDPF_PALETTEINDEXED8;
39 }
40 pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount = pDev->mode.ulBitsPerPel;
41 pHalInfo->vmiData.ddpfDisplay.dwRBitMask = pDev->mode.flMaskR;
42 pHalInfo->vmiData.ddpfDisplay.dwGBitMask = pDev->mode.flMaskG;
43 pHalInfo->vmiData.ddpfDisplay.dwBBitMask = pDev->mode.flMaskB;
44
45 pHalInfo->vmiData.dwOffscreenAlign = 4;
46 pHalInfo->vmiData.dwTextureAlign = 4;
47 pHalInfo->vmiData.dwZBufferAlign = 4;
48 pHalInfo->vmiData.dwOverlayAlign = 4;
49
50 pHalInfo->vmiData.pvPrimary = pDev->memInfo.FrameBufferBase;
51
52 /* caps */
53
54 pHalInfo->ddCaps.dwSize = sizeof(DDNTCORECAPS);
55 pHalInfo->ddCaps.dwCaps2 = DDCAPS2_WIDESURFACES;
56 pHalInfo->ddCaps.dwVidMemTotal = pDev->layout.cbDDrawHeap;
57 pHalInfo->ddCaps.dwVidMemFree = pDev->layout.cbDDrawHeap;
58 pHalInfo->ddCaps.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
59
60}
61
62/* Called to get supported DirectDraw caps */
63BOOL APIENTRY
64VBoxDispDrvGetDirectDrawInfo(DHPDEV dhpdev, DD_HALINFO *pHalInfo, DWORD *pdwNumHeaps,
65 VIDEOMEMORY *pvmList, DWORD *pdwNumFourCCCodes, DWORD *pdwFourCC)
66{
67 PVBOXDISPDEV pDev = (PVBOXDISPDEV)dhpdev;
68 LOGF_ENTER();
69
70 VBoxDispGetDDHalInfo(pDev, pHalInfo);
71
72#ifdef VBOX_WITH_VIDEOHWACCEL
73 int rc;
74
75 if (!pvmList && !pdwFourCC) /* first call */
76 {
77 rc = VBoxDispVHWAInitHostInfo1(pDev);
78 VBOX_WARNRC_NOBP(rc);
79 }
80
81 if (pDev->vhwa.bEnabled)
82 {
83 rc = VBoxDispVHWAUpdateDDHalInfo(pDev, pHalInfo);
84 VBOX_WARNRC(rc);
85
86 pDev->vhwa.bEnabled = RT_SUCCESS(rc);
87 }
88#endif
89
90 /* we could only have 1 heap, so it's not really a list */
91 if (pvmList && pDev->layout.cbDDrawHeap>0)
92 {
93 pvmList->dwFlags = VIDMEM_ISLINEAR;
94 pvmList->fpStart = pDev->layout.offDDrawHeap;
95 pvmList->fpEnd = pDev->layout.offDDrawHeap + pDev->layout.cbDDrawHeap - 1;
96#ifdef VBOX_WITH_VIDEOHWACCEL
97 if (pDev->vhwa.bEnabled)
98 {
99 pvmList->ddsCaps.dwCaps = 0;
100 }
101 else
102#endif
103 {
104 pvmList->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
105 }
106 pvmList->ddsCapsAlt.dwCaps = 0;
107
108 }
109
110 /* Always report number of heaps and supported FourCC's*/
111 *pdwNumHeaps = (pDev->layout.cbDDrawHeap>0) ? 1:0;
112
113#ifndef VBOX_WITH_VIDEOHWACCEL
114 *pdwNumFourCCCodes = 0;
115#else
116 if (pDev->vhwa.bEnabled)
117 {
118 *pdwNumFourCCCodes = pDev->vhwa.numFourCC;
119 if (pdwFourCC && pDev->vhwa.numFourCC)
120 {
121 rc = VBoxDispVHWAInitHostInfo2(pDev, pdwFourCC);
122 VBOX_WARNRC(rc);
123
124 if (RT_FAILURE(rc))
125 {
126 *pdwNumFourCCCodes = 0;
127 pDev->vhwa.numFourCC = 0;
128 }
129 }
130
131 pHalInfo->GetDriverInfo = VBoxDispDDGetDriverInfo;
132 pHalInfo->dwFlags |= DDHALINFO_GETDRIVERINFOSET;
133 }
134#endif
135
136 LOGF_LEAVE();
137 return TRUE;
138}
139
140BOOL APIENTRY
141VBoxDispDrvEnableDirectDraw(DHPDEV dhpdev, DD_CALLBACKS *pCallBacks, DD_SURFACECALLBACKS *pSurfaceCallBacks,
142 DD_PALETTECALLBACKS *pPaletteCallBacks)
143{
144 LOGF_ENTER();
145
146 pCallBacks->dwSize = sizeof(DD_CALLBACKS);
147 pCallBacks->CreateSurface = VBoxDispDDCreateSurface;
148 pCallBacks->CanCreateSurface = VBoxDispDDCanCreateSurface;
149 pCallBacks->MapMemory = VBoxDispDDMapMemory;
150 pCallBacks->dwFlags = DDHAL_CB32_CREATESURFACE|DDHAL_CB32_CANCREATESURFACE|DDHAL_CB32_MAPMEMORY;
151
152 pSurfaceCallBacks->dwSize = sizeof(DD_SURFACECALLBACKS);
153 pSurfaceCallBacks->Lock = VBoxDispDDLock;
154 pSurfaceCallBacks->Unlock = VBoxDispDDUnlock;
155 pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_LOCK|DDHAL_SURFCB32_UNLOCK;
156
157 pPaletteCallBacks->dwSize = sizeof(DD_PALETTECALLBACKS);
158 pPaletteCallBacks->dwFlags = 0;
159
160#ifdef VBOX_WITH_VIDEOHWACCEL
161 PVBOXDISPDEV pDev = (PVBOXDISPDEV)dhpdev;
162
163 if (pDev->vhwa.bEnabled)
164 {
165 pSurfaceCallBacks->DestroySurface = VBoxDispDDDestroySurface;
166 pSurfaceCallBacks->Flip = VBoxDispDDFlip;
167 pSurfaceCallBacks->GetFlipStatus = VBoxDispDDGetFlipStatus;
168 pSurfaceCallBacks->Blt = VBoxDispDDBlt;
169 pSurfaceCallBacks->GetBltStatus = VBoxDispDDGetBltStatus;
170 pSurfaceCallBacks->SetColorKey = VBoxDispDDSetColorKey;
171 pSurfaceCallBacks->dwFlags |= DDHAL_SURFCB32_DESTROYSURFACE|
172 DDHAL_SURFCB32_FLIP|DDHAL_SURFCB32_GETFLIPSTATUS|
173 DDHAL_SURFCB32_BLT|DDHAL_SURFCB32_GETBLTSTATUS|
174 DDHAL_SURFCB32_SETCOLORKEY;
175
176 if(pDev->vhwa.caps & VBOXVHWA_CAPS_OVERLAY)
177 {
178 pSurfaceCallBacks->UpdateOverlay = VBoxDispDDUpdateOverlay;
179 pSurfaceCallBacks->SetOverlayPosition = VBoxDispDDSetOverlayPosition;
180 pSurfaceCallBacks->dwFlags |= DDHAL_SURFCB32_UPDATEOVERLAY|DDHAL_SURFCB32_SETOVERLAYPOSITION;
181 }
182 }
183#endif
184
185 LOGF_LEAVE();
186 return TRUE;
187}
188
189VOID APIENTRY VBoxDispDrvDisableDirectDraw(DHPDEV dhpdev)
190{
191 RT_NOREF(dhpdev);
192 LOGF_ENTER();
193 LOGF_LEAVE();
194 return;
195}
196
197HBITMAP APIENTRY VBoxDispDrvDeriveSurface(DD_DIRECTDRAW_GLOBAL *pDirectDraw, DD_SURFACE_LOCAL *pSurface)
198{
199 PVBOXDISPDEV pDev = (PVBOXDISPDEV)pDirectDraw->dhpdev;
200 LOGF_ENTER();
201
202 if (pSurface->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
203 {
204 WARN(("Can't derive surface DDSCAPS_NONLOCALVIDMEM"));
205 return NULL;
206 }
207
208 if (pSurface->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
209 {
210 WARN(("Can't derive surface DDSCAPS2_TEXTUREMANAGE"));
211 return NULL;
212 }
213
214 if (pSurface->lpGbl->ddpfSurface.dwRGBBitCount != pDev->mode.ulBitsPerPel)
215 {
216 WARN(("Can't derive surface with different bpp"));
217 return NULL;
218 }
219
220 Assert(pDev->surface.hSurface);
221
222 /* Create GDI managed bitmap, which resides in our DDraw heap memory */
223 HBITMAP hBitmap;
224 SIZEL size;
225
226 size.cx = pDev->mode.ulWidth;
227 size.cy = pDev->mode.ulHeight;
228
229 hBitmap = EngCreateBitmap(size, pSurface->lpGbl->lPitch, pDev->surface.ulFormat,
230 pDev->mode.lScanlineStride>0 ? BMF_TOPDOWN:0,
231 (PBYTE)pDev->memInfo.VideoRamBase + pSurface->lpGbl->fpVidMem);
232
233 if (!hBitmap)
234 {
235 WARN(("EngCreateBitmap failed"));
236 return 0;
237 }
238
239 if (pSurface->lpGbl->fpVidMem == 0)
240 {
241 /* Screen surface, mark it so it will be recognized by the driver.
242 * so the driver will be called on any operations on the surface
243 * (required for VBVA and VRDP).
244 */
245 SURFOBJ *pso;
246
247 if (!EngAssociateSurface((HSURF)hBitmap, pDev->hDevGDI, pDev->flDrawingHooks))
248 {
249 WARN(("EngAssociateSurface failed"));
250 EngDeleteSurface((HSURF)hBitmap);
251 return NULL;
252 }
253
254 pso = EngLockSurface((HSURF)hBitmap);
255 if (!pso)
256 {
257 WARN(("EngLockSurface failed"));
258 EngDeleteSurface((HSURF)hBitmap);
259 return NULL;
260 }
261
262 pso->dhpdev = (DHPDEV)pDev;
263 EngUnlockSurface(pso);
264 }
265
266 LOGF_LEAVE();
267 return hBitmap;
268}
Note: See TracBrowser for help on using the repository browser.

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