2 Support for Graphics output spliter.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "ConSplitter.h"
13 CHAR16 mCrLfString
[3] = { CHAR_CARRIAGE_RETURN
, CHAR_LINEFEED
, CHAR_NULL
};
16 Returns information for an available graphics mode that the graphics device
17 and the set of active video output devices supports.
19 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
20 @param ModeNumber The mode number to return information on.
21 @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.
22 @param Info A pointer to callee allocated buffer that returns information about ModeNumber.
24 @retval EFI_SUCCESS Mode information returned.
25 @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small.
26 @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.
27 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
28 @retval EFI_OUT_OF_RESOURCES No resource available.
33 ConSplitterGraphicsOutputQueryMode (
34 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
36 OUT UINTN
*SizeOfInfo
,
37 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
40 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
41 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
45 if (This
== NULL
|| Info
== NULL
|| SizeOfInfo
== NULL
|| ModeNumber
>= This
->Mode
->MaxMode
) {
46 return EFI_INVALID_PARAMETER
;
50 // retrieve private data
52 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
54 GraphicsOutput
= NULL
;
56 if (Private
->CurrentNumberOfGraphicsOutput
== 1) {
58 // Find the only one GraphicsOutput.
60 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
61 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
62 if (GraphicsOutput
!= NULL
) {
68 if (GraphicsOutput
!= NULL
) {
70 // If only one physical GOP device exist, return its information.
72 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) ModeNumber
, SizeOfInfo
, Info
);
76 // If 2 more phyiscal GOP device exist or GOP protocol does not exist,
77 // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().
79 *Info
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
81 return EFI_OUT_OF_RESOURCES
;
83 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
84 CopyMem (*Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], *SizeOfInfo
);
92 Set the video device into the specified mode and clears the visible portions of
93 the output display to black.
95 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
96 @param ModeNumber Abstraction that defines the current video mode.
98 @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected.
99 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
100 @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.
101 @retval EFI_OUT_OF_RESOURCES No resource available.
106 ConSplitterGraphicsOutputSetMode (
107 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
* This
,
112 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
114 EFI_STATUS ReturnStatus
;
115 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
116 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
117 EFI_GRAPHICS_OUTPUT_PROTOCOL
*PhysicalGraphicsOutput
;
120 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
121 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
123 if (ModeNumber
>= This
->Mode
->MaxMode
) {
124 return EFI_UNSUPPORTED
;
127 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
128 Mode
= &Private
->GraphicsOutputModeBuffer
[ModeNumber
];
130 ReturnStatus
= EFI_SUCCESS
;
131 GraphicsOutput
= NULL
;
132 PhysicalGraphicsOutput
= NULL
;
134 // return the worst status met
136 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
137 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
138 if (GraphicsOutput
!= NULL
) {
139 PhysicalGraphicsOutput
= GraphicsOutput
;
141 // Find corresponding ModeNumber of this GraphicsOutput instance
143 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
144 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
145 if (EFI_ERROR (Status
)) {
148 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) && (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
155 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
156 if (EFI_ERROR (Status
)) {
157 ReturnStatus
= Status
;
159 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
160 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
161 if (UgaDraw
!= NULL
) {
162 Status
= UgaDraw
->SetMode (
164 Mode
->HorizontalResolution
,
165 Mode
->VerticalResolution
,
169 if (EFI_ERROR (Status
)) {
170 ReturnStatus
= Status
;
176 This
->Mode
->Mode
= ModeNumber
;
178 if ((Private
->CurrentNumberOfGraphicsOutput
== 1) && (PhysicalGraphicsOutput
!= NULL
)) {
180 // If only one physical GOP device exist, copy physical information to consplitter.
182 CopyMem (This
->Mode
->Info
, PhysicalGraphicsOutput
->Mode
->Info
, PhysicalGraphicsOutput
->Mode
->SizeOfInfo
);
183 This
->Mode
->SizeOfInfo
= PhysicalGraphicsOutput
->Mode
->SizeOfInfo
;
184 This
->Mode
->FrameBufferBase
= PhysicalGraphicsOutput
->Mode
->FrameBufferBase
;
185 This
->Mode
->FrameBufferSize
= PhysicalGraphicsOutput
->Mode
->FrameBufferSize
;
188 // If 2 more phyiscal GOP device exist or GOP protocol does not exist,
189 // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().
191 CopyMem (This
->Mode
->Info
, &Private
->GraphicsOutputModeBuffer
[ModeNumber
], This
->Mode
->SizeOfInfo
);
200 The following table defines actions for BltOperations.
202 EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY)
203 directly to every pixel of the video display rectangle
204 (DestinationX, DestinationY)
205 (DestinationX + Width, DestinationY + Height).
206 Only one pixel will be used from the BltBuffer. Delta is NOT used.
207 EfiBltVideoToBltBuffer - Read data from the video display rectangle
208 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
209 the BltBuffer rectangle (DestinationX, DestinationY )
210 (DestinationX + Width, DestinationY + Height). If DestinationX or
211 DestinationY is not zero then Delta must be set to the length in bytes
212 of a row in the BltBuffer.
213 EfiBltBufferToVideo - Write data from the BltBuffer rectangle
214 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
215 video display rectangle (DestinationX, DestinationY)
216 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
217 not zero then Delta must be set to the length in bytes of a row in the
219 EfiBltVideoToVideo - Copy from the video display rectangle
220 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
221 to the video display rectangle (DestinationX, DestinationY)
222 (DestinationX + Width, DestinationY + Height).
223 The BltBuffer and Delta are not used in this mode.
225 @param This Protocol instance pointer.
226 @param BltBuffer Buffer containing data to blit into video buffer.
227 This buffer has a size of
228 Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
229 @param BltOperation Operation to perform on BlitBuffer and video
231 @param SourceX X coordinate of source for the BltBuffer.
232 @param SourceY Y coordinate of source for the BltBuffer.
233 @param DestinationX X coordinate of destination for the BltBuffer.
234 @param DestinationY Y coordinate of destination for the BltBuffer.
235 @param Width Width of rectangle in BltBuffer in pixels.
236 @param Height Hight of rectangle in BltBuffer in pixels.
237 @param Delta OPTIONAL.
239 @retval EFI_SUCCESS The Blt operation completed.
240 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
241 @retval EFI_DEVICE_ERROR A hardware error occurred writting to the video
247 ConSplitterGraphicsOutputBlt (
248 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
249 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
250 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
253 IN UINTN DestinationX
,
254 IN UINTN DestinationY
,
257 IN UINTN Delta OPTIONAL
261 EFI_STATUS ReturnStatus
;
262 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
264 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
265 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
267 if (This
== NULL
|| ((UINTN
) BltOperation
) >= EfiGraphicsOutputBltOperationMax
) {
268 return EFI_INVALID_PARAMETER
;
271 Private
= GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
273 ReturnStatus
= EFI_SUCCESS
;
276 // return the worst status met
278 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
279 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
280 if (GraphicsOutput
!= NULL
) {
281 Status
= GraphicsOutput
->Blt (
293 if (EFI_ERROR (Status
)) {
294 ReturnStatus
= Status
;
295 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
297 // Only need to read the data into buffer one time
303 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
304 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
305 Status
= UgaDraw
->Blt (
307 (EFI_UGA_PIXEL
*) BltBuffer
,
308 (EFI_UGA_BLT_OPERATION
) BltOperation
,
317 if (EFI_ERROR (Status
)) {
318 ReturnStatus
= Status
;
319 } else if (BltOperation
== EfiBltVideoToBltBuffer
) {
321 // Only need to read the data into buffer one time
332 Return the current video mode information.
334 @param This The EFI_UGA_DRAW_PROTOCOL instance.
335 @param HorizontalResolution The size of video screen in pixels in the X dimension.
336 @param VerticalResolution The size of video screen in pixels in the Y dimension.
337 @param ColorDepth Number of bits per pixel, currently defined to be 32.
338 @param RefreshRate The refresh rate of the monitor in Hertz.
340 @retval EFI_SUCCESS Mode information returned.
341 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
342 @retval EFI_INVALID_PARAMETER One of the input args was NULL.
347 ConSplitterUgaDrawGetMode (
348 IN EFI_UGA_DRAW_PROTOCOL
*This
,
349 OUT UINT32
*HorizontalResolution
,
350 OUT UINT32
*VerticalResolution
,
351 OUT UINT32
*ColorDepth
,
352 OUT UINT32
*RefreshRate
355 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
357 if ((HorizontalResolution
== NULL
) ||
358 (VerticalResolution
== NULL
) ||
359 (RefreshRate
== NULL
) ||
360 (ColorDepth
== NULL
)) {
361 return EFI_INVALID_PARAMETER
;
364 // retrieve private data
366 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
368 *HorizontalResolution
= Private
->UgaHorizontalResolution
;
369 *VerticalResolution
= Private
->UgaVerticalResolution
;
370 *ColorDepth
= Private
->UgaColorDepth
;
371 *RefreshRate
= Private
->UgaRefreshRate
;
378 Set the current video mode information.
380 @param This The EFI_UGA_DRAW_PROTOCOL instance.
381 @param HorizontalResolution The size of video screen in pixels in the X dimension.
382 @param VerticalResolution The size of video screen in pixels in the Y dimension.
383 @param ColorDepth Number of bits per pixel, currently defined to be 32.
384 @param RefreshRate The refresh rate of the monitor in Hertz.
386 @retval EFI_SUCCESS Mode information returned.
387 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
388 @retval EFI_OUT_OF_RESOURCES Out of resources.
393 ConSplitterUgaDrawSetMode (
394 IN EFI_UGA_DRAW_PROTOCOL
*This
,
395 IN UINT32 HorizontalResolution
,
396 IN UINT32 VerticalResolution
,
397 IN UINT32 ColorDepth
,
398 IN UINT32 RefreshRate
402 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
404 EFI_STATUS ReturnStatus
;
405 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
408 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
409 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
411 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
413 ReturnStatus
= EFI_SUCCESS
;
416 // Update the Mode data
418 Private
->UgaHorizontalResolution
= HorizontalResolution
;
419 Private
->UgaVerticalResolution
= VerticalResolution
;
420 Private
->UgaColorDepth
= ColorDepth
;
421 Private
->UgaRefreshRate
= RefreshRate
;
424 // return the worst status met
426 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
428 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
429 if (GraphicsOutput
!= NULL
) {
431 // Find corresponding ModeNumber of this GraphicsOutput instance
433 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
434 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
435 if (EFI_ERROR (Status
)) {
438 if ((Info
->HorizontalResolution
== HorizontalResolution
) && (Info
->VerticalResolution
== VerticalResolution
)) {
445 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
446 if (EFI_ERROR (Status
)) {
447 ReturnStatus
= Status
;
449 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)){
450 UgaDraw
= Private
->TextOutList
[Index
].UgaDraw
;
451 if (UgaDraw
!= NULL
) {
452 Status
= UgaDraw
->SetMode (
454 HorizontalResolution
,
459 if (EFI_ERROR (Status
)) {
460 ReturnStatus
= Status
;
471 Blt a rectangle of pixels on the graphics screen.
473 The following table defines actions for BltOperations.
476 Write data from the BltBuffer pixel (SourceX, SourceY)
477 directly to every pixel of the video display rectangle
478 (DestinationX, DestinationY)
479 (DestinationX + Width, DestinationY + Height).
480 Only one pixel will be used from the BltBuffer. Delta is NOT used.
481 EfiUgaVideoToBltBuffer:
482 Read data from the video display rectangle
483 (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
484 the BltBuffer rectangle (DestinationX, DestinationY )
485 (DestinationX + Width, DestinationY + Height). If DestinationX or
486 DestinationY is not zero then Delta must be set to the length in bytes
487 of a row in the BltBuffer.
488 EfiUgaBltBufferToVideo:
489 Write data from the BltBuffer rectangle
490 (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
491 video display rectangle (DestinationX, DestinationY)
492 (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
493 not zero then Delta must be set to the length in bytes of a row in the
496 Copy from the video display rectangle
497 (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
498 to the video display rectangle (DestinationX, DestinationY)
499 (DestinationX + Width, DestinationY + Height).
500 The BltBuffer and Delta are not used in this mode.
502 @param This Protocol instance pointer.
503 @param BltBuffer Buffer containing data to blit into video buffer. This
504 buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
505 @param BltOperation Operation to perform on BlitBuffer and video memory
506 @param SourceX X coordinate of source for the BltBuffer.
507 @param SourceY Y coordinate of source for the BltBuffer.
508 @param DestinationX X coordinate of destination for the BltBuffer.
509 @param DestinationY Y coordinate of destination for the BltBuffer.
510 @param Width Width of rectangle in BltBuffer in pixels.
511 @param Height Hight of rectangle in BltBuffer in pixels.
512 @param Delta OPTIONAL
514 @retval EFI_SUCCESS The Blt operation completed.
515 @retval EFI_INVALID_PARAMETER BltOperation is not valid.
516 @retval EFI_DEVICE_ERROR A hardware error occurred writting to the video buffer.
521 ConSplitterUgaDrawBlt (
522 IN EFI_UGA_DRAW_PROTOCOL
*This
,
523 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
524 IN EFI_UGA_BLT_OPERATION BltOperation
,
527 IN UINTN DestinationX
,
528 IN UINTN DestinationY
,
531 IN UINTN Delta OPTIONAL
535 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
537 EFI_STATUS ReturnStatus
;
538 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
540 Private
= UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
542 ReturnStatus
= EFI_SUCCESS
;
544 // return the worst status met
546 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
547 GraphicsOutput
= Private
->TextOutList
[Index
].GraphicsOutput
;
548 if (GraphicsOutput
!= NULL
) {
549 Status
= GraphicsOutput
->Blt (
551 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) BltBuffer
,
552 (EFI_GRAPHICS_OUTPUT_BLT_OPERATION
) BltOperation
,
561 if (EFI_ERROR (Status
)) {
562 ReturnStatus
= Status
;
563 } else if (BltOperation
== EfiUgaVideoToBltBuffer
) {
565 // Only need to read the data into buffer one time
571 if (Private
->TextOutList
[Index
].UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
572 Status
= Private
->TextOutList
[Index
].UgaDraw
->Blt (
573 Private
->TextOutList
[Index
].UgaDraw
,
584 if (EFI_ERROR (Status
)) {
585 ReturnStatus
= Status
;
586 } else if (BltOperation
== EfiUgaVideoToBltBuffer
) {
588 // Only need to read the data into buffer one time
599 Sets the output device(s) to a specified mode.
601 @param Private Text Out Splitter pointer.
602 @param ModeNumber The mode number to set.
607 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
612 // No need to do extra check here as whether (Column, Row) is valid has
613 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
614 // always be supported.
616 Private
->TextOutMode
.Mode
= (INT32
) ModeNumber
;
617 Private
->TextOutMode
.CursorColumn
= 0;
618 Private
->TextOutMode
.CursorRow
= 0;
619 Private
->TextOutMode
.CursorVisible
= TRUE
;