VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/vboxvideo/vbva.c@ 55376

Last change on this file since 55376 was 55373, checked in by vboxsync, 10 years ago

Additions/x11/vboxvideo: test for new host capabilities.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.8 KB
Line 
1/** @file
2 * VirtualBox X11 Additions graphics driver 2D acceleration functions
3 */
4
5/*
6 * Copyright (C) 2006-2012 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#include <VBox/VMMDev.h>
18#include <VBox/VBoxGuestLib.h>
19
20#ifndef PCIACCESS
21# include <xf86Pci.h>
22# include <Pci.h>
23#endif
24
25#include "xf86.h"
26#define NEED_XF86_TYPES
27#include <iprt/string.h>
28#include "compiler.h"
29
30/* ShadowFB support */
31#include "shadowfb.h"
32
33#include "vboxvideo.h"
34
35#ifdef XORG_7X
36# include <stdlib.h>
37#endif
38
39/**************************************************************************
40* Main functions *
41**************************************************************************/
42
43/**
44 * Callback function called by the X server to tell us about dirty
45 * rectangles in the video buffer.
46 *
47 * @param pScreen pointer to the information structure for the current
48 * screen
49 * @param iRects Number of dirty rectangles to update
50 * @param aRects Array of structures containing the coordinates of the
51 * rectangles
52 */
53void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
54{
55 VBVACMDHDR cmdHdr;
56 VBOXPtr pVBox;
57 int i;
58 unsigned j;
59
60 pVBox = pScrn->driverPrivate;
61 if (!pScrn->vtSema)
62 return;
63
64 for (j = 0; j < pVBox->cScreens; ++j)
65 {
66 /* Just continue quietly if VBVA is not currently active. */
67 struct VBVABUFFER *pVBVA = pVBox->pScreens[j].aVbvaCtx.pVBVA;
68 if ( !pVBVA
69 || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
70 continue;
71 for (i = 0; i < iRects; ++i)
72 {
73 if ( aRects[i].x1 > pVBox->pScreens[j].aScreenLocation.x
74 + pVBox->pScreens[j].aScreenLocation.cx
75 || aRects[i].y1 > pVBox->pScreens[j].aScreenLocation.y
76 + pVBox->pScreens[j].aScreenLocation.cy
77 || aRects[i].x2 < pVBox->pScreens[j].aScreenLocation.x
78 || aRects[i].y2 < pVBox->pScreens[j].aScreenLocation.y)
79 continue;
80 cmdHdr.x = (int16_t)aRects[i].x1 - pVBox->pScreens[0].aScreenLocation.x;
81 cmdHdr.y = (int16_t)aRects[i].y1 - pVBox->pScreens[0].aScreenLocation.y;
82 cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
83 cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
84
85#if 0
86 TRACE_LOG("display=%u, x=%d, y=%d, w=%d, h=%d\n",
87 j, cmdHdr.x, cmdHdr.y, cmdHdr.w, cmdHdr.h);
88#endif
89
90 if (VBoxVBVABufferBeginUpdate(&pVBox->pScreens[j].aVbvaCtx,
91 &pVBox->guestCtx))
92 {
93 VBoxVBVAWrite(&pVBox->pScreens[j].aVbvaCtx, &pVBox->guestCtx, &cmdHdr,
94 sizeof(cmdHdr));
95 VBoxVBVABufferEndUpdate(&pVBox->pScreens[j].aVbvaCtx);
96 }
97 }
98 }
99}
100
101static DECLCALLBACK(void *) hgsmiEnvAlloc(void *pvEnv, HGSMISIZE cb)
102{
103 NOREF(pvEnv);
104 return calloc(1, cb);
105}
106
107static DECLCALLBACK(void) hgsmiEnvFree(void *pvEnv, void *pv)
108{
109 NOREF(pvEnv);
110 free(pv);
111}
112
113static HGSMIENV g_hgsmiEnv =
114{
115 NULL,
116 hgsmiEnvAlloc,
117 hgsmiEnvFree
118};
119
120/**
121 * Calculate the location in video RAM of and initialise the heap for guest to
122 * host messages. In the VirtualBox 4.3 and earlier Guest Additions this
123 * function creates the heap structures directly in guest video RAM, so it
124 * needs to be called whenever video RAM is (re-)set-up.
125 */
126void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM)
127{
128 int rc;
129 uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
130 void *pvGuestHeapMemory;
131
132 VBoxHGSMIGetBaseMappingInfo(cbVRAM, &offVRAMBaseMapping, NULL, &offGuestHeapMemory, &cbGuestHeapMemory, NULL);
133 pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping + offGuestHeapMemory;
134 rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory, cbGuestHeapMemory,
135 offVRAMBaseMapping + offGuestHeapMemory, &g_hgsmiEnv);
136 VBVXASSERT(RT_SUCCESS(rc), ("Failed to set up the guest-to-host message buffer heap, rc=%d\n", rc));
137 pVBox->cbView = offVRAMBaseMapping;
138}
139
140/** Callback to fill in the view structures */
141static int
142vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
143{
144 VBOXPtr pVBox = (VBOXPtr)pvVBox;
145 unsigned i;
146 for (i = 0; i < cViews; ++i)
147 {
148 pViews[i].u32ViewIndex = i;
149 pViews[i].u32ViewOffset = 0;
150 pViews[i].u32ViewSize = pVBox->cbView;
151 pViews[i].u32MaxScreenSize = pVBox->cbFBMax;
152 }
153 return VINF_SUCCESS;
154}
155
156/**
157 * Initialise VirtualBox's accelerated video extensions.
158 *
159 * @returns TRUE on success, FALSE on failure
160 */
161static Bool vboxSetupVRAMVbva(VBOXPtr pVBox)
162{
163 int rc = VINF_SUCCESS;
164 unsigned i;
165
166 pVBox->cbFBMax = pVBox->cbView;
167 for (i = 0; i < pVBox->cScreens; ++i)
168 {
169 pVBox->cbFBMax -= VBVA_MIN_BUFFER_SIZE;
170 pVBox->pScreens[i].aoffVBVABuffer = pVBox->cbFBMax;
171 TRACE_LOG("VBVA buffer offset for screen %u: 0x%lx\n", i,
172 (unsigned long) pVBox->cbFBMax);
173 VBoxVBVASetupBufferContext(&pVBox->pScreens[i].aVbvaCtx,
174 pVBox->pScreens[i].aoffVBVABuffer,
175 VBVA_MIN_BUFFER_SIZE);
176 }
177 TRACE_LOG("Maximum framebuffer size: %lu (0x%lx)\n",
178 (unsigned long) pVBox->cbFBMax,
179 (unsigned long) pVBox->cbFBMax);
180 rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
181 vboxFillViewInfo, (void *)pVBox);
182 VBVXASSERT(RT_SUCCESS(rc), ("Failed to send the view information to the host, rc=%d\n", rc));
183 return TRUE;
184}
185
186static bool haveHGSMIModeHintAndCursorReportingInterface(VBOXPtr pVBox)
187{
188 uint32_t fModeHintReporting, fCursorReporting;
189
190 return RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_MODE_HINT_REPORTING, &fModeHintReporting))
191 && RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING, &fCursorReporting))
192 && fModeHintReporting == VINF_SUCCESS
193 && fCursorReporting == VINF_SUCCESS;
194}
195
196static bool hostHasScreenBlankingFlag(VBOXPtr pVBox)
197{
198 uint32_t fScreenFlags;
199
200 return RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_SCREEN_FLAGS, &fScreenFlags))
201 && fScreenFlags & VBVA_SCREEN_F_BLANK;
202}
203
204/**
205 * Inform VBox that we will supply it with dirty rectangle information
206 * and install the dirty rectangle handler.
207 *
208 * @returns TRUE for success, FALSE for failure
209 * @param pScrn Pointer to a structure describing the X screen in use
210 */
211Bool
212vboxEnableVbva(ScrnInfoPtr pScrn)
213{
214 bool rc = TRUE;
215 unsigned i;
216 VBOXPtr pVBox = pScrn->driverPrivate;
217
218 TRACE_ENTRY();
219 if (!vboxSetupVRAMVbva(pVBox))
220 return FALSE;
221 for (i = 0; i < pVBox->cScreens; ++i)
222 {
223 struct VBVABUFFER *pVBVA;
224
225 pVBVA = (struct VBVABUFFER *) ( ((uint8_t *)pVBox->base)
226 + pVBox->pScreens[i].aoffVBVABuffer);
227 if (!VBoxVBVAEnable(&pVBox->pScreens[i].aVbvaCtx, &pVBox->guestCtx,
228 pVBVA, i))
229 rc = FALSE;
230 }
231 VBVXASSERT(rc, ("Failed to enable screen update reporting for at least one virtual monitor.\n"));
232#ifdef VBOXVIDEO_13
233# ifdef RT_OS_LINUX
234 if (rc && pVBox->hACPIEventHandler != NULL)
235 /* We ignore the return value as the fall-back should be active
236 * anyway. */
237 VBoxHGSMISendCapsInfo(&pVBox->guestCtx, VBVACAPS_VIDEO_MODE_HINTS | VBVACAPS_DISABLE_CURSOR_INTEGRATION);
238# endif
239 pVBox->fHaveHGSMIModeHints = haveHGSMIModeHintAndCursorReportingInterface(pVBox);
240 pVBox->fHostHasScreenBlankingFlag = hostHasScreenBlankingFlag(pVBox);
241#endif
242 return rc;
243}
244
245/**
246 * Inform VBox that we will stop supplying it with dirty rectangle
247 * information. This function is intended to be called when an X
248 * virtual terminal is disabled, or the X server is terminated.
249 *
250 * @returns TRUE for success, FALSE for failure
251 * @param pScrn Pointer to a structure describing the X screen in use
252 */
253void
254vboxDisableVbva(ScrnInfoPtr pScrn)
255{
256 int rc;
257 unsigned i;
258 VBOXPtr pVBox = pScrn->driverPrivate;
259
260 TRACE_ENTRY();
261 for (i = 0; i < pVBox->cScreens; ++i)
262 VBoxVBVADisable(&pVBox->pScreens[i].aVbvaCtx, &pVBox->guestCtx, i);
263}
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