VirtualBox

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

Last change on this file since 36308 was 35932, checked in by vboxsync, 14 years ago

Additions/x11/vboxvideo: further split up source files

  • 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-2007 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#include "vboxvideo.h"
31
32/**************************************************************************
33* Main functions *
34**************************************************************************/
35
36/**
37 * Callback function called by the X server to tell us about dirty
38 * rectangles in the video buffer.
39 *
40 * @param pScreen pointer to the information structure for the current
41 * screen
42 * @param iRects Number of dirty rectangles to update
43 * @param aRects Array of structures containing the coordinates of the
44 * rectangles
45 */
46static void
47vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
48{
49 VBVACMDHDR cmdHdr;
50 VBOXPtr pVBox;
51 int i;
52 unsigned j;
53
54 pVBox = pScrn->driverPrivate;
55 if (pVBox->fHaveHGSMI == FALSE || pVBox->vtSwitch)
56 return;
57
58 for (i = 0; i < iRects; ++i)
59 for (j = 0; j < pVBox->cScreens; ++j)
60 {
61 /* Just continue quietly if VBVA is not currently active. */
62 struct VBVABUFFER *pVBVA = pVBox->aVbvaCtx[j].pVBVA;
63 if ( !pVBVA
64 || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
65 continue;
66 if ( aRects[i].x1 > pVBox->aScreenLocation[j].x
67 + pVBox->aScreenLocation[j].cx
68 || aRects[i].y1 > pVBox->aScreenLocation[j].y
69 + pVBox->aScreenLocation[j].cy
70 || aRects[i].x2 < pVBox->aScreenLocation[j].x
71 || aRects[i].y2 < pVBox->aScreenLocation[j].y)
72 continue;
73 cmdHdr.x = (int16_t)aRects[i].x1;
74 cmdHdr.y = (int16_t)aRects[i].y1;
75 cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
76 cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
77
78#if 0
79 TRACE_LOG("display=%u, x=%d, y=%d, w=%d, h=%d\n",
80 j, cmdHdr.x, cmdHdr.y, cmdHdr.w, cmdHdr.h);
81#endif
82
83 if (VBoxVBVABufferBeginUpdate(&pVBox->aVbvaCtx[j],
84 &pVBox->guestCtx))
85 {
86 VBoxVBVAWrite(&pVBox->aVbvaCtx[j], &pVBox->guestCtx, &cmdHdr,
87 sizeof(cmdHdr));
88 VBoxVBVABufferEndUpdate(&pVBox->aVbvaCtx[j]);
89 }
90 }
91}
92
93/** Callback to fill in the view structures */
94static int
95vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
96{
97 VBOXPtr pVBox = (VBOXPtr)pvVBox;
98 unsigned i;
99 for (i = 0; i < cViews; ++i)
100 {
101 pViews[i].u32ViewIndex = i;
102 pViews[i].u32ViewOffset = 0;
103 pViews[i].u32ViewSize = pVBox->cbView;
104 pViews[i].u32MaxScreenSize = pVBox->cbFBMax;
105 }
106 return VINF_SUCCESS;
107}
108
109/**
110 * Initialise VirtualBox's accelerated video extensions.
111 *
112 * @returns TRUE on success, FALSE on failure
113 */
114static Bool
115vboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)
116{
117 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
118 int rc = VINF_SUCCESS;
119
120 pVBox->cScreens = 1;
121 if (!VBoxHGSMIIsSupported())
122 {
123 xf86DrvMsg(scrnIndex, X_ERROR, "The graphics device does not seem to support HGSMI. Disableing video acceleration.\n");
124 return FALSE;
125 }
126
127 /* Set up the dirty rectangle handler. It will be added into a function
128 * chain and gets removed when the screen is cleaned up. */
129 if (ShadowFBInit2(pScreen, NULL, vboxHandleDirtyRect) != TRUE)
130 {
131 xf86DrvMsg(scrnIndex, X_ERROR,
132 "Unable to install dirty rectangle handler for VirtualBox graphics acceleration.\n");
133 return FALSE;
134 }
135 return TRUE;
136}
137
138/**
139 * Initialise VirtualBox's accelerated video extensions.
140 *
141 * @returns TRUE on success, FALSE on failure
142 */
143static Bool
144vboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox)
145{
146 int rc = VINF_SUCCESS;
147 unsigned i;
148 uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
149 void *pvGuestHeapMemory;
150
151 if (!pVBox->fHaveHGSMI)
152 return FALSE;
153 VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping,
154 NULL, &offGuestHeapMemory, &cbGuestHeapMemory,
155 NULL);
156 pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping
157 + offGuestHeapMemory;
158 TRACE_LOG("video RAM: %u KB, guest heap offset: 0x%x, cbGuestHeapMemory: %u\n",
159 pScrn->videoRam, offVRAMBaseMapping + offGuestHeapMemory,
160 cbGuestHeapMemory);
161 rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory,
162 cbGuestHeapMemory,
163 offVRAMBaseMapping + offGuestHeapMemory);
164 if (RT_FAILURE(rc))
165 {
166 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up the guest-to-host communication context, rc=%d\n", rc);
167 return FALSE;
168 }
169 pVBox->cbView = pVBox->cbFBMax = offVRAMBaseMapping;
170 pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);
171 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n",
172 pVBox->cScreens);
173 for (i = 0; i < pVBox->cScreens; ++i)
174 {
175 pVBox->cbFBMax -= VBVA_MIN_BUFFER_SIZE;
176 pVBox->aoffVBVABuffer[i] = pVBox->cbFBMax;
177 TRACE_LOG("VBVA buffer offset for screen %u: 0x%lx\n", i,
178 (unsigned long) pVBox->cbFBMax);
179 VBoxVBVASetupBufferContext(&pVBox->aVbvaCtx[i],
180 pVBox->aoffVBVABuffer[i],
181 VBVA_MIN_BUFFER_SIZE);
182 }
183 TRACE_LOG("Maximum framebuffer size: %lu (0x%lx)\n",
184 (unsigned long) pVBox->cbFBMax,
185 (unsigned long) pVBox->cbFBMax);
186 rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
187 vboxFillViewInfo, (void *)pVBox);
188 if (RT_FAILURE(rc))
189 {
190 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to send the view information to the host, rc=%d\n", rc);
191 return FALSE;
192 }
193 return TRUE;
194}
195
196Bool
197vbox_open(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
198{
199 TRACE_ENTRY();
200
201 pVBox->fHaveHGSMI = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);
202 return pVBox->fHaveHGSMI;
203}
204
205Bool
206vbox_device_available(VBOXPtr pVBox)
207{
208 return pVBox->useDevice;
209}
210
211/**
212 * Inform VBox that we will supply it with dirty rectangle information
213 * and install the dirty rectangle handler.
214 *
215 * @returns TRUE for success, FALSE for failure
216 * @param pScrn Pointer to a structure describing the X screen in use
217 */
218Bool
219vboxEnableVbva(ScrnInfoPtr pScrn)
220{
221 bool rc = TRUE;
222 int scrnIndex = pScrn->scrnIndex;
223 unsigned i;
224 VBOXPtr pVBox = pScrn->driverPrivate;
225
226 TRACE_ENTRY();
227 if (!vboxSetupVRAMVbva(pScrn, pVBox))
228 return FALSE;
229 for (i = 0; i < pVBox->cScreens; ++i)
230 {
231 struct VBVABUFFER *pVBVA;
232
233 pVBVA = (struct VBVABUFFER *) ( ((uint8_t *)pVBox->base)
234 + pVBox->aoffVBVABuffer[i]);
235 if (!VBoxVBVAEnable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, pVBVA, i))
236 rc = FALSE;
237 }
238 if (!rc)
239 {
240 /* Request not accepted - disable for old hosts. */
241 xf86DrvMsg(scrnIndex, X_ERROR,
242 "Failed to enable screen update reporting for at least one virtual monitor.\n");
243 vboxDisableVbva(pScrn);
244 }
245 return rc;
246}
247
248/**
249 * Inform VBox that we will stop supplying it with dirty rectangle
250 * information. This function is intended to be called when an X
251 * virtual terminal is disabled, or the X server is terminated.
252 *
253 * @returns TRUE for success, FALSE for failure
254 * @param pScrn Pointer to a structure describing the X screen in use
255 */
256void
257vboxDisableVbva(ScrnInfoPtr pScrn)
258{
259 int rc;
260 int scrnIndex = pScrn->scrnIndex;
261 unsigned i;
262 VBOXPtr pVBox = pScrn->driverPrivate;
263
264 TRACE_ENTRY();
265 if (!pVBox->fHaveHGSMI) /* Ths function should not have been called */
266 return;
267 for (i = 0; i < pVBox->cScreens; ++i)
268 VBoxVBVADisable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, i);
269}
Note: See TracBrowser for help on using the repository browser.

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