VirtualBox

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

Last change on this file was 99739, checked in by vboxsync, 12 months ago

*: doxygen corrections (mostly about removing @returns from functions returning void).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.7 KB
RevLine 
[55401]1/* $Id: vbva.c 99739 2023-05-11 01:01:08Z vboxsync $ */
[6495]2/** @file
[35932]3 * VirtualBox X11 Additions graphics driver 2D acceleration functions
[6495]4 */
5
6/*
[98103]7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[6495]8 *
[69346]9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
[69058]17 *
[69346]18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
[69058]20 *
[69346]21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
[6495]29 */
30
[69079]31#if defined(IN_XF86_MODULE) && !defined(NO_ANSIC)
32# include "xf86_ansic.h"
33#endif
[6495]34#include "compiler.h"
35
36#include "vboxvideo.h"
37
[50485]38#ifdef XORG_7X
39# include <stdlib.h>
[69079]40# include <string.h>
[50485]41#endif
42
[9249]43/**************************************************************************
44* Main functions *
45**************************************************************************/
46
[6495]47/**
48 * Callback function called by the X server to tell us about dirty
49 * rectangles in the video buffer.
50 *
[65122]51 * @param pScrn pointer to the information structure for the current
[6495]52 * screen
53 * @param iRects Number of dirty rectangles to update
54 * @param aRects Array of structures containing the coordinates of the
55 * rectangles
56 */
[55358]57void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
[6495]58{
59 VBVACMDHDR cmdHdr;
60 VBOXPtr pVBox;
61 int i;
[34715]62 unsigned j;
[6495]63
64 pVBox = pScrn->driverPrivate;
[51393]65 if (!pScrn->vtSema)
[6495]66 return;
67
[43310]68 for (j = 0; j < pVBox->cScreens; ++j)
69 {
70 /* Just continue quietly if VBVA is not currently active. */
[52199]71 struct VBVABUFFER *pVBVA = pVBox->pScreens[j].aVbvaCtx.pVBVA;
[43310]72 if ( !pVBVA
73 || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
74 continue;
75 for (i = 0; i < iRects; ++i)
[34715]76 {
[52199]77 if ( aRects[i].x1 > pVBox->pScreens[j].aScreenLocation.x
78 + pVBox->pScreens[j].aScreenLocation.cx
79 || aRects[i].y1 > pVBox->pScreens[j].aScreenLocation.y
80 + pVBox->pScreens[j].aScreenLocation.cy
81 || aRects[i].x2 < pVBox->pScreens[j].aScreenLocation.x
82 || aRects[i].y2 < pVBox->pScreens[j].aScreenLocation.y)
[34715]83 continue;
[55357]84 cmdHdr.x = (int16_t)aRects[i].x1 - pVBox->pScreens[0].aScreenLocation.x;
85 cmdHdr.y = (int16_t)aRects[i].y1 - pVBox->pScreens[0].aScreenLocation.y;
[34715]86 cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
87 cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
[6495]88
[34871]89#if 0
[34747]90 TRACE_LOG("display=%u, x=%d, y=%d, w=%d, h=%d\n",
91 j, cmdHdr.x, cmdHdr.y, cmdHdr.w, cmdHdr.h);
[34871]92#endif
93
[52199]94 if (VBoxVBVABufferBeginUpdate(&pVBox->pScreens[j].aVbvaCtx,
[35208]95 &pVBox->guestCtx))
96 {
[52199]97 VBoxVBVAWrite(&pVBox->pScreens[j].aVbvaCtx, &pVBox->guestCtx, &cmdHdr,
[35208]98 sizeof(cmdHdr));
[52199]99 VBoxVBVABufferEndUpdate(&pVBox->pScreens[j].aVbvaCtx);
[35208]100 }
[6495]101 }
[43310]102 }
[34715]103}
104
[50485]105static DECLCALLBACK(void *) hgsmiEnvAlloc(void *pvEnv, HGSMISIZE cb)
106{
[69066]107 RT_NOREF(pvEnv);
[50485]108 return calloc(1, cb);
109}
110
111static DECLCALLBACK(void) hgsmiEnvFree(void *pvEnv, void *pv)
112{
[69066]113 RT_NOREF(pvEnv);
[50485]114 free(pv);
115}
116
117static HGSMIENV g_hgsmiEnv =
118{
119 NULL,
120 hgsmiEnvAlloc,
121 hgsmiEnvFree
122};
123
[35267]124/**
[55367]125 * Calculate the location in video RAM of and initialise the heap for guest to
[69081]126 * host messages.
[55367]127 */
128void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM)
129{
130 int rc;
131 uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
132 void *pvGuestHeapMemory;
133
134 VBoxHGSMIGetBaseMappingInfo(cbVRAM, &offVRAMBaseMapping, NULL, &offGuestHeapMemory, &cbGuestHeapMemory, NULL);
135 pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping + offGuestHeapMemory;
136 rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory, cbGuestHeapMemory,
137 offVRAMBaseMapping + offGuestHeapMemory, &g_hgsmiEnv);
[69080]138 AssertMsg(RT_SUCCESS(rc), ("Failed to set up the guest-to-host message buffer heap, rc=%d\n", rc));
[55367]139 pVBox->cbView = offVRAMBaseMapping;
140}
141
142/** Callback to fill in the view structures */
[57426]143static DECLCALLBACK(int) vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
[55367]144{
145 VBOXPtr pVBox = (VBOXPtr)pvVBox;
146 unsigned i;
147 for (i = 0; i < cViews; ++i)
148 {
149 pViews[i].u32ViewIndex = i;
150 pViews[i].u32ViewOffset = 0;
151 pViews[i].u32ViewSize = pVBox->cbView;
152 pViews[i].u32MaxScreenSize = pVBox->cbFBMax;
153 }
154 return VINF_SUCCESS;
155}
156
157/**
[35267]158 * Initialise VirtualBox's accelerated video extensions.
159 *
160 * @returns TRUE on success, FALSE on failure
161 */
[55367]162static Bool vboxSetupVRAMVbva(VBOXPtr pVBox)
[35267]163{
164 int rc = VINF_SUCCESS;
165 unsigned i;
166
[55367]167 pVBox->cbFBMax = pVBox->cbView;
[34715]168 for (i = 0; i < pVBox->cScreens; ++i)
[6495]169 {
[35268]170 pVBox->cbFBMax -= VBVA_MIN_BUFFER_SIZE;
[52199]171 pVBox->pScreens[i].aoffVBVABuffer = pVBox->cbFBMax;
[35125]172 TRACE_LOG("VBVA buffer offset for screen %u: 0x%lx\n", i,
[35268]173 (unsigned long) pVBox->cbFBMax);
[52199]174 VBoxVBVASetupBufferContext(&pVBox->pScreens[i].aVbvaCtx,
175 pVBox->pScreens[i].aoffVBVABuffer,
[34715]176 VBVA_MIN_BUFFER_SIZE);
[6495]177 }
[35125]178 TRACE_LOG("Maximum framebuffer size: %lu (0x%lx)\n",
[35268]179 (unsigned long) pVBox->cbFBMax,
180 (unsigned long) pVBox->cbFBMax);
[35102]181 rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
182 vboxFillViewInfo, (void *)pVBox);
[69080]183 AssertMsg(RT_SUCCESS(rc), ("Failed to send the view information to the host, rc=%d\n", rc));
[6495]184 return TRUE;
185}
186
[69064]187static Bool haveHGSMIModeHintAndCursorReportingInterface(VBOXPtr pVBox)
[55373]188{
189 uint32_t fModeHintReporting, fCursorReporting;
190
191 return RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_MODE_HINT_REPORTING, &fModeHintReporting))
192 && RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING, &fCursorReporting))
193 && fModeHintReporting == VINF_SUCCESS
194 && fCursorReporting == VINF_SUCCESS;
195}
196
[69064]197static Bool hostHasScreenBlankingFlag(VBOXPtr pVBox)
[55373]198{
199 uint32_t fScreenFlags;
200
201 return RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_SCREEN_FLAGS, &fScreenFlags))
202 && fScreenFlags & VBVA_SCREEN_F_BLANK;
203}
204
[6495]205/**
206 * Inform VBox that we will supply it with dirty rectangle information
207 * and install the dirty rectangle handler.
208 *
209 * @returns TRUE for success, FALSE for failure
[6508]210 * @param pScrn Pointer to a structure describing the X screen in use
[6495]211 */
212Bool
213vboxEnableVbva(ScrnInfoPtr pScrn)
214{
[69064]215 Bool rc = TRUE;
[34715]216 unsigned i;
[6495]217 VBOXPtr pVBox = pScrn->driverPrivate;
218
[9249]219 TRACE_ENTRY();
[55367]220 if (!vboxSetupVRAMVbva(pVBox))
[34715]221 return FALSE;
222 for (i = 0; i < pVBox->cScreens; ++i)
223 {
224 struct VBVABUFFER *pVBVA;
225
226 pVBVA = (struct VBVABUFFER *) ( ((uint8_t *)pVBox->base)
[52199]227 + pVBox->pScreens[i].aoffVBVABuffer);
228 if (!VBoxVBVAEnable(&pVBox->pScreens[i].aVbvaCtx, &pVBox->guestCtx,
229 pVBVA, i))
[34715]230 rc = FALSE;
231 }
[69080]232 AssertMsg(rc, ("Failed to enable screen update reporting for at least one virtual monitor.\n"));
[55373]233 pVBox->fHaveHGSMIModeHints = haveHGSMIModeHintAndCursorReportingInterface(pVBox);
234 pVBox->fHostHasScreenBlankingFlag = hostHasScreenBlankingFlag(pVBox);
[16980]235 return rc;
[6495]236}
237
238/**
239 * Inform VBox that we will stop supplying it with dirty rectangle
240 * information. This function is intended to be called when an X
241 * virtual terminal is disabled, or the X server is terminated.
242 *
[6508]243 * @param pScrn Pointer to a structure describing the X screen in use
[6495]244 */
[34715]245void
[6495]246vboxDisableVbva(ScrnInfoPtr pScrn)
247{
[34715]248 unsigned i;
[6495]249 VBOXPtr pVBox = pScrn->driverPrivate;
250
[9249]251 TRACE_ENTRY();
[34715]252 for (i = 0; i < pVBox->cScreens; ++i)
[52199]253 VBoxVBVADisable(&pVBox->pScreens[i].aVbvaCtx, &pVBox->guestCtx, i);
[6495]254}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use