VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareOld/VBoxPkg/VBoxVgaDxe/VBoxVgaUgaDraw.c@ 58453

Last change on this file since 58453 was 56292, checked in by vboxsync, 10 years ago

Devices: Updated (C) year.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.9 KB
Line 
1/* $Id: VBoxVgaUgaDraw.c 56292 2015-06-09 14:20:46Z vboxsync $ */
2/** @file
3 * VBoxVgaUgaDraw.c
4 */
5
6/*
7 * Copyright (C) 2009-2015 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*
28 This code is based on:
29
30 This file produces the graphics abstraction of UGA Draw. It is called by
31 VBoxVga.c file which deals with the EFI 1.1 driver model.
32 This file just does graphics.
33
34 Copyright (c) 2006, Intel Corporation
35 All rights reserved. This program and the accompanying materials
36 are licensed and made available under the terms and conditions of the BSD License
37 which accompanies this distribution. The full text of the license may be found at
38 http://opensource.org/licenses/bsd-license.php
39
40 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
41 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
42
43*/
44
45#include "VBoxVga.h"
46
47//
48// UGA Draw Protocol Member Functions
49//
50EFI_STATUS
51EFIAPI
52VBoxVgaUgaDrawGetMode (
53 IN EFI_UGA_DRAW_PROTOCOL *This,
54 OUT UINT32 *HorizontalResolution,
55 OUT UINT32 *VerticalResolution,
56 OUT UINT32 *ColorDepth,
57 OUT UINT32 *RefreshRate
58 )
59{
60 VBOX_VGA_PRIVATE_DATA *Private;
61
62 Private = VBOX_VGA_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);
63
64 if (Private->HardwareNeedsStarting) {
65 return EFI_NOT_STARTED;
66 }
67
68 if ((HorizontalResolution == NULL) ||
69 (VerticalResolution == NULL) ||
70 (ColorDepth == NULL) ||
71 (RefreshRate == NULL)) {
72 return EFI_INVALID_PARAMETER;
73 }
74
75 *HorizontalResolution = Private->ModeData[Private->CurrentMode].HorizontalResolution;
76 *VerticalResolution = Private->ModeData[Private->CurrentMode].VerticalResolution;
77 *ColorDepth = Private->ModeData[Private->CurrentMode].ColorDepth;
78 *RefreshRate = Private->ModeData[Private->CurrentMode].RefreshRate;
79 return EFI_SUCCESS;
80}
81
82EFI_STATUS
83EFIAPI
84VBoxVgaUgaDrawSetMode (
85 IN EFI_UGA_DRAW_PROTOCOL *This,
86 IN UINT32 HorizontalResolution,
87 IN UINT32 VerticalResolution,
88 IN UINT32 ColorDepth,
89 IN UINT32 RefreshRate
90 )
91{
92 VBOX_VGA_PRIVATE_DATA *Private;
93 UINTN Index;
94
95 DEBUG((DEBUG_INFO, "%a:%d VIDEO: %dx%d %d bpp\n", __FILE__, __LINE__, HorizontalResolution, VerticalResolution, ColorDepth));
96 Private = VBOX_VGA_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);
97
98 for (Index = 0; Index < Private->MaxMode; Index++) {
99
100 if (HorizontalResolution != Private->ModeData[Index].HorizontalResolution) {
101 continue;
102 }
103
104 if (VerticalResolution != Private->ModeData[Index].VerticalResolution) {
105 continue;
106 }
107
108 if (ColorDepth != Private->ModeData[Index].ColorDepth) {
109 continue;
110 }
111
112#if 0
113 if (RefreshRate != Private->ModeData[Index].RefreshRate) {
114 continue;
115 }
116#endif
117
118 if (Private->LineBuffer) {
119 gBS->FreePool (Private->LineBuffer);
120 }
121
122 Private->LineBuffer = NULL;
123 Private->LineBuffer = AllocatePool (HorizontalResolution * 4);
124 if (Private->LineBuffer == NULL) {
125 return EFI_OUT_OF_RESOURCES;
126 }
127
128 InitializeGraphicsMode (Private, &VBoxVgaVideoModes[Private->ModeData[Index].ModeNumber]);
129 if (Private->TmpBuf)
130 FreePool(Private->TmpBuf);
131 Private->TmpBuf = AllocatePool(Private->ModeData[Index].HorizontalResolution * Private->ModeData[Index].VerticalResolution * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
132
133 Private->CurrentMode = Index;
134
135 Private->HardwareNeedsStarting = FALSE;
136
137 /* update current mode */
138 Private->CurrentMode = Index;
139 return EFI_SUCCESS;
140 }
141
142 return EFI_NOT_FOUND;
143}
144
145EFI_STATUS
146EFIAPI
147VBoxVgaUgaDrawBlt (
148 IN EFI_UGA_DRAW_PROTOCOL *This,
149 IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL
150 IN EFI_UGA_BLT_OPERATION BltOperation,
151 IN UINTN SourceX,
152 IN UINTN SourceY,
153 IN UINTN DestinationX,
154 IN UINTN DestinationY,
155 IN UINTN Width,
156 IN UINTN Height,
157 IN UINTN Delta
158 )
159{
160 VBOX_VGA_PRIVATE_DATA *Private;
161 EFI_TPL OriginalTPL;
162 UINTN DstY;
163 UINTN SrcY;
164 EFI_UGA_PIXEL *Blt;
165 UINTN X;
166 UINTN ScreenWidth;
167 UINTN Offset;
168 UINTN SourceOffset;
169 UINTN ScreenHeight;
170
171 Private = VBOX_VGA_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);
172
173 if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {
174 return EFI_INVALID_PARAMETER;
175 }
176
177 if (Width == 0 || Height == 0) {
178 return EFI_INVALID_PARAMETER;
179 }
180
181 //
182 // If Delta is zero, then the entire BltBuffer is being used, so Delta
183 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
184 // the number of bytes in each row can be computed.
185 //
186 if (Delta == 0) {
187 Delta = Width * sizeof (EFI_UGA_PIXEL);
188 }
189 Delta /= sizeof (EFI_UGA_PIXEL);
190
191 //
192 // We need to fill the Virtual Screen buffer with the blt data.
193 // The virtual screen is upside down, as the first row is the bootom row of
194 // the image.
195 //
196
197 //
198 // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters
199 // are valid for the operation and the current screen geometry.
200 //
201 if (BltOperation == EfiUgaVideoToBltBuffer) {
202 //
203 // Video to BltBuffer: Source is Video, destination is BltBuffer
204 //
205 if (SourceY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {
206 return EFI_INVALID_PARAMETER;
207 }
208
209 if (SourceX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {
210 return EFI_INVALID_PARAMETER;
211 }
212 } else {
213 //
214 // BltBuffer to Video: Source is BltBuffer, destination is Video
215 //
216 if (DestinationY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {
217 return EFI_INVALID_PARAMETER;
218 }
219
220 if (DestinationX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {
221 return EFI_INVALID_PARAMETER;
222 }
223 }
224 //
225 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
226 // We would not want a timer based event (Cursor, ...) to come in while we are
227 // doing this operation.
228 //
229 OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
230
231 switch (BltOperation) {
232 case EfiUgaVideoToBltBuffer:
233 //
234 // Video to BltBuffer: Source is Video, destination is BltBuffer
235 //
236 for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {
237
238 Offset = (SrcY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + SourceX;
239 Private->PciIo->Mem.Read (
240 Private->PciIo,
241 EfiPciIoWidthUint32,
242 0,
243 Offset * 4,
244 Width,
245 Private->LineBuffer
246 );
247
248 for (X = 0; X < Width; X++) {
249 Blt = (EFI_UGA_PIXEL *) ((UINT32 *) BltBuffer + (DstY * Delta) + (DestinationX + X));
250
251 *(UINT32 *)Blt = Private->LineBuffer[X];
252 }
253 }
254 break;
255
256 case EfiUgaVideoToVideo:
257 //
258 // Perform hardware acceleration for Video to Video operations
259 //
260 ScreenWidth = Private->ModeData[Private->CurrentMode].HorizontalResolution;
261 ScreenHeight = Private->ModeData[Private->CurrentMode].VerticalResolution;
262 SourceOffset = (SourceY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (SourceX);
263 Offset = (DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (DestinationX);
264 VBoxVgaUgaDrawBlt(This, (EFI_UGA_PIXEL *)Private->TmpBuf, EfiUgaVideoToBltBuffer, SourceX, SourceY, 0, 0, ScreenWidth - SourceX, ScreenHeight - SourceY, 0);
265 VBoxVgaUgaDrawBlt(This, (EFI_UGA_PIXEL *)Private->TmpBuf, EfiUgaBltBufferToVideo, 0, 0, DestinationX, DestinationY, ScreenWidth - SourceX, ScreenHeight - SourceY, 0);
266 break;
267
268 case EfiUgaVideoFill:
269 Blt = BltBuffer;
270
271 if (DestinationX == 0 && Width == Private->ModeData[Private->CurrentMode].HorizontalResolution) {
272 Offset = DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution;
273 Private->PciIo->Mem.Write (
274 Private->PciIo,
275 EfiPciIoWidthFillUint32,
276 0,
277 Offset * 4,
278 (Width * Height) ,
279 Blt
280 );
281 } else {
282 for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
283 Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;
284 Private->PciIo->Mem.Write (
285 Private->PciIo,
286 EfiPciIoWidthFillUint32,
287 0,
288 Offset * 4,
289 Width,
290 Blt
291 );
292 }
293 }
294 break;
295
296 case EfiUgaBltBufferToVideo:
297 for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
298
299 for (X = 0; X < Width; X++) {
300 Blt = (EFI_UGA_PIXEL *) ((UINT32 *) BltBuffer + (SrcY * Delta) + (SourceX + X));
301 Private->LineBuffer[X] = *(UINT32 *)Blt;
302 }
303
304 Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;
305
306 Private->PciIo->Mem.Write (
307 Private->PciIo,
308 EfiPciIoWidthUint32,
309 0,
310 Offset * 4,
311 Width,
312 Private->LineBuffer
313 );
314 }
315 break;
316
317 default:
318 break;
319 }
320
321 gBS->RestoreTPL (OriginalTPL);
322
323 return EFI_SUCCESS;
324}
325
326//
327// Construction and Destruction functions
328//
329EFI_STATUS
330VBoxVgaUgaDrawConstructor (
331 VBOX_VGA_PRIVATE_DATA *Private
332 )
333{
334 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
335
336 //
337 // Fill in Private->UgaDraw protocol
338 //
339 UgaDraw = &Private->UgaDraw;
340
341 UgaDraw->GetMode = VBoxVgaUgaDrawGetMode;
342 UgaDraw->SetMode = VBoxVgaUgaDrawSetMode;
343 UgaDraw->Blt = VBoxVgaUgaDrawBlt;
344
345 //
346 // Initialize the private data
347 //
348 Private->CurrentMode = 0;
349 Private->HardwareNeedsStarting = TRUE;
350 Private->LineBuffer = NULL;
351
352 //
353 // Initialize the hardware
354 //
355 UgaDraw->SetMode (
356 UgaDraw,
357 Private->ModeData[Private->CurrentMode].HorizontalResolution,
358 Private->ModeData[Private->CurrentMode].VerticalResolution,
359 Private->ModeData[Private->CurrentMode].ColorDepth,
360 Private->ModeData[Private->CurrentMode].RefreshRate
361 );
362 DrawLogo (
363 Private,
364 Private->ModeData[Private->CurrentMode].HorizontalResolution,
365 Private->ModeData[Private->CurrentMode].VerticalResolution
366 );
367
368 return EFI_SUCCESS;
369}
370
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