1/** @file
2  Support for Graphics output spliter.
3
4Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution.  The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13
14**/
15
16#include "ConSplitter.h"
17
18
19CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
20
21/**
22  Returns information for an available graphics mode that the graphics device
23  and the set of active video output devices supports.
24
25  @param  This                  The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
26  @param  ModeNumber            The mode number to return information on.
27  @param  SizeOfInfo            A pointer to the size, in bytes, of the Info buffer.
28  @param  Info                  A pointer to callee allocated buffer that returns information about ModeNumber.
29
30  @retval EFI_SUCCESS           Mode information returned.
31  @retval EFI_BUFFER_TOO_SMALL  The Info buffer was too small.
32  @retval EFI_DEVICE_ERROR      A hardware error occurred trying to retrieve the video mode.
33  @retval EFI_INVALID_PARAMETER One of the input args was NULL.
34  @retval EFI_OUT_OF_RESOURCES  No resource available.
35
36**/
37EFI_STATUS
38EFIAPI
39ConSplitterGraphicsOutputQueryMode (
40  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
41  IN  UINT32                                ModeNumber,
42  OUT UINTN                                 *SizeOfInfo,
43  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
44  )
45{
46  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
47  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
48  EFI_STATUS                      Status;
49  UINTN                           Index;
50
51  if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
52    return EFI_INVALID_PARAMETER;
53  }
54
55  //
56  // retrieve private data
57  //
58  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
59
60  GraphicsOutput = NULL;
61
62  if (Private->CurrentNumberOfGraphicsOutput == 1) {
63    //
64    // Find the only one GraphicsOutput.
65    //
66    for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
67      GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
68      if (GraphicsOutput != NULL) {
69        break;
70      }
71    }
72  }
73
74  if (GraphicsOutput != NULL) {
75    //
76    // If only one physical GOP device exist, return its information.
77    //
78    Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) ModeNumber, SizeOfInfo, Info);
79    return Status;
80  } else {
81    //
82    // If 2 more phyiscal GOP device exist or GOP protocol does not exist,
83    // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().
84    //
85    *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
86    if (*Info == NULL) {
87      return EFI_OUT_OF_RESOURCES;
88    }
89    *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
90    CopyMem (*Info, &Private->GraphicsOutputModeBuffer[ModeNumber], *SizeOfInfo);
91  }
92
93  return EFI_SUCCESS;
94}
95
96
97/**
98  Set the video device into the specified mode and clears the visible portions of
99  the output display to black.
100
101  @param  This                  The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
102  @param  ModeNumber            Abstraction that defines the current video mode.
103
104  @retval EFI_SUCCESS           The graphics mode specified by ModeNumber was selected.
105  @retval EFI_DEVICE_ERROR      The device had an error and could not complete the request.
106  @retval EFI_UNSUPPORTED       ModeNumber is not supported by this device.
107  @retval EFI_OUT_OF_RESOURCES  No resource available.
108
109**/
110EFI_STATUS
111EFIAPI
112ConSplitterGraphicsOutputSetMode (
113  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL * This,
114  IN  UINT32                       ModeNumber
115  )
116{
117  EFI_STATUS                             Status;
118  TEXT_OUT_SPLITTER_PRIVATE_DATA         *Private;
119  UINTN                                  Index;
120  EFI_STATUS                             ReturnStatus;
121  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Mode;
122  EFI_GRAPHICS_OUTPUT_PROTOCOL           *GraphicsOutput;
123  EFI_GRAPHICS_OUTPUT_PROTOCOL           *PhysicalGraphicsOutput;
124  UINTN                                  NumberIndex;
125  UINTN                                  SizeOfInfo;
126  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Info;
127  EFI_UGA_DRAW_PROTOCOL                  *UgaDraw;
128
129  if (ModeNumber >= This->Mode->MaxMode) {
130    return EFI_UNSUPPORTED;
131  }
132
133  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
134  Mode = &Private->GraphicsOutputModeBuffer[ModeNumber];
135
136  ReturnStatus = EFI_SUCCESS;
137  GraphicsOutput = NULL;
138  PhysicalGraphicsOutput = NULL;
139  //
140  // return the worst status met
141  //
142  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
143    GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
144    if (GraphicsOutput != NULL) {
145      PhysicalGraphicsOutput = GraphicsOutput;
146      //
147      // Find corresponding ModeNumber of this GraphicsOutput instance
148      //
149      for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex ++) {
150        Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);
151        if (EFI_ERROR (Status)) {
152          return Status;
153        }
154        if ((Info->HorizontalResolution == Mode->HorizontalResolution) && (Info->VerticalResolution == Mode->VerticalResolution)) {
155          FreePool (Info);
156          break;
157        }
158        FreePool (Info);
159      }
160
161      Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);
162      if (EFI_ERROR (Status)) {
163        ReturnStatus = Status;
164      }
165    } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
166      UgaDraw = Private->TextOutList[Index].UgaDraw;
167      if (UgaDraw != NULL) {
168        Status = UgaDraw->SetMode (
169                            UgaDraw,
170                            Mode->HorizontalResolution,
171                            Mode->VerticalResolution,
172                            32,
173                            60
174                            );
175        if (EFI_ERROR (Status)) {
176          ReturnStatus = Status;
177        }
178      }
179    }
180  }
181
182  This->Mode->Mode = ModeNumber;
183
184  if ((Private->CurrentNumberOfGraphicsOutput == 1) && (PhysicalGraphicsOutput != NULL)) {
185    //
186    // If only one physical GOP device exist, copy physical information to consplitter.
187    //
188    CopyMem (This->Mode->Info, PhysicalGraphicsOutput->Mode->Info, PhysicalGraphicsOutput->Mode->SizeOfInfo);
189    This->Mode->SizeOfInfo = PhysicalGraphicsOutput->Mode->SizeOfInfo;
190    This->Mode->FrameBufferBase = PhysicalGraphicsOutput->Mode->FrameBufferBase;
191    This->Mode->FrameBufferSize = PhysicalGraphicsOutput->Mode->FrameBufferSize;
192  } else {
193    //
194    // If 2 more phyiscal GOP device exist or GOP protocol does not exist,
195    // return GOP information (PixelFormat is PixelBltOnly) created in ConSplitterAddGraphicsOutputMode ().
196    //
197    CopyMem (This->Mode->Info, &Private->GraphicsOutputModeBuffer[ModeNumber], This->Mode->SizeOfInfo);
198  }
199
200  return ReturnStatus;
201}
202
203
204
205/**
206  The following table defines actions for BltOperations.
207
208  EfiBltVideoFill - Write data from the  BltBuffer pixel (SourceX, SourceY)
209  directly to every pixel of the video display rectangle
210  (DestinationX, DestinationY)
211  (DestinationX + Width, DestinationY + Height).
212  Only one pixel will be used from the BltBuffer. Delta is NOT used.
213  EfiBltVideoToBltBuffer - Read data from the video display rectangle
214  (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
215  the BltBuffer rectangle (DestinationX, DestinationY )
216  (DestinationX + Width, DestinationY + Height). If DestinationX or
217  DestinationY is not zero then Delta must be set to the length in bytes
218  of a row in the BltBuffer.
219  EfiBltBufferToVideo - Write data from the  BltBuffer rectangle
220  (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
221  video display rectangle (DestinationX, DestinationY)
222  (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
223  not zero then Delta must be set to the length in bytes of a row in the
224  BltBuffer.
225  EfiBltVideoToVideo - Copy from the video display rectangle
226  (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
227  to the video display rectangle (DestinationX, DestinationY)
228  (DestinationX + Width, DestinationY + Height).
229  The BltBuffer and Delta  are not used in this mode.
230
231  @param  This                    Protocol instance pointer.
232  @param  BltBuffer               Buffer containing data to blit into video buffer.
233                                  This buffer has a size of
234                                  Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
235  @param  BltOperation            Operation to perform on BlitBuffer and video
236                                  memory
237  @param  SourceX                 X coordinate of source for the BltBuffer.
238  @param  SourceY                 Y coordinate of source for the BltBuffer.
239  @param  DestinationX            X coordinate of destination for the BltBuffer.
240  @param  DestinationY            Y coordinate of destination for the BltBuffer.
241  @param  Width                   Width of rectangle in BltBuffer in pixels.
242  @param  Height                  Hight of rectangle in BltBuffer in pixels.
243  @param  Delta                   OPTIONAL.
244
245  @retval EFI_SUCCESS             The Blt operation completed.
246  @retval EFI_INVALID_PARAMETER   BltOperation is not valid.
247  @retval EFI_DEVICE_ERROR        A hardware error occured writting to the video
248                                  buffer.
249
250**/
251EFI_STATUS
252EFIAPI
253ConSplitterGraphicsOutputBlt (
254  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL                  *This,
255  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL                 *BltBuffer, OPTIONAL
256  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION             BltOperation,
257  IN  UINTN                                         SourceX,
258  IN  UINTN                                         SourceY,
259  IN  UINTN                                         DestinationX,
260  IN  UINTN                                         DestinationY,
261  IN  UINTN                                         Width,
262  IN  UINTN                                         Height,
263  IN  UINTN                                         Delta         OPTIONAL
264  )
265{
266  EFI_STATUS                      Status;
267  EFI_STATUS                      ReturnStatus;
268  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
269  UINTN                           Index;
270  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
271  EFI_UGA_DRAW_PROTOCOL           *UgaDraw;
272
273  if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {
274    return EFI_INVALID_PARAMETER;
275  }
276
277  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
278
279  ReturnStatus = EFI_SUCCESS;
280
281  //
282  // return the worst status met
283  //
284  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
285    GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
286    if (GraphicsOutput != NULL) {
287      Status = GraphicsOutput->Blt (
288                              GraphicsOutput,
289                              BltBuffer,
290                              BltOperation,
291                              SourceX,
292                              SourceY,
293                              DestinationX,
294                              DestinationY,
295                              Width,
296                              Height,
297                              Delta
298                              );
299      if (EFI_ERROR (Status)) {
300        ReturnStatus = Status;
301      } else if (BltOperation == EfiBltVideoToBltBuffer) {
302        //
303        // Only need to read the data into buffer one time
304        //
305        return EFI_SUCCESS;
306      }
307    }
308
309    UgaDraw = Private->TextOutList[Index].UgaDraw;
310    if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
311      Status = UgaDraw->Blt (
312                              UgaDraw,
313                              (EFI_UGA_PIXEL *) BltBuffer,
314                              (EFI_UGA_BLT_OPERATION) BltOperation,
315                              SourceX,
316                              SourceY,
317                              DestinationX,
318                              DestinationY,
319                              Width,
320                              Height,
321                              Delta
322                              );
323      if (EFI_ERROR (Status)) {
324        ReturnStatus = Status;
325      } else if (BltOperation == EfiBltVideoToBltBuffer) {
326        //
327        // Only need to read the data into buffer one time
328        //
329        return EFI_SUCCESS;
330      }
331    }
332  }
333
334  return ReturnStatus;
335}
336
337/**
338  Return the current video mode information.
339
340  @param  This                  The EFI_UGA_DRAW_PROTOCOL instance.
341  @param  HorizontalResolution  The size of video screen in pixels in the X dimension.
342  @param  VerticalResolution    The size of video screen in pixels in the Y dimension.
343  @param  ColorDepth            Number of bits per pixel, currently defined to be 32.
344  @param  RefreshRate           The refresh rate of the monitor in Hertz.
345
346  @retval EFI_SUCCESS           Mode information returned.
347  @retval EFI_NOT_STARTED       Video display is not initialized. Call SetMode ()
348  @retval EFI_INVALID_PARAMETER One of the input args was NULL.
349
350**/
351EFI_STATUS
352EFIAPI
353ConSplitterUgaDrawGetMode (
354  IN  EFI_UGA_DRAW_PROTOCOL           *This,
355  OUT UINT32                          *HorizontalResolution,
356  OUT UINT32                          *VerticalResolution,
357  OUT UINT32                          *ColorDepth,
358  OUT UINT32                          *RefreshRate
359  )
360{
361  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
362
363  if ((HorizontalResolution == NULL) ||
364      (VerticalResolution   == NULL) ||
365      (RefreshRate          == NULL) ||
366      (ColorDepth           == NULL)) {
367    return EFI_INVALID_PARAMETER;
368  }
369  //
370  // retrieve private data
371  //
372  Private               = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
373
374  *HorizontalResolution = Private->UgaHorizontalResolution;
375  *VerticalResolution   = Private->UgaVerticalResolution;
376  *ColorDepth           = Private->UgaColorDepth;
377  *RefreshRate          = Private->UgaRefreshRate;
378
379  return EFI_SUCCESS;
380}
381
382
383/**
384  Set the current video mode information.
385
386  @param  This                 The EFI_UGA_DRAW_PROTOCOL instance.
387  @param  HorizontalResolution The size of video screen in pixels in the X dimension.
388  @param  VerticalResolution   The size of video screen in pixels in the Y dimension.
389  @param  ColorDepth           Number of bits per pixel, currently defined to be 32.
390  @param  RefreshRate          The refresh rate of the monitor in Hertz.
391
392  @retval EFI_SUCCESS          Mode information returned.
393  @retval EFI_NOT_STARTED      Video display is not initialized. Call SetMode ()
394  @retval EFI_OUT_OF_RESOURCES Out of resources.
395
396**/
397EFI_STATUS
398EFIAPI
399ConSplitterUgaDrawSetMode (
400  IN  EFI_UGA_DRAW_PROTOCOL           *This,
401  IN UINT32                           HorizontalResolution,
402  IN UINT32                           VerticalResolution,
403  IN UINT32                           ColorDepth,
404  IN UINT32                           RefreshRate
405  )
406{
407  EFI_STATUS                             Status;
408  TEXT_OUT_SPLITTER_PRIVATE_DATA         *Private;
409  UINTN                                  Index;
410  EFI_STATUS                             ReturnStatus;
411  EFI_GRAPHICS_OUTPUT_PROTOCOL           *GraphicsOutput;
412  UINTN                                  NumberIndex;
413  UINTN                                  SizeOfInfo;
414  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Info;
415  EFI_UGA_DRAW_PROTOCOL                  *UgaDraw;
416
417  Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
418
419  ReturnStatus = EFI_SUCCESS;
420
421  //
422  // Update the Mode data
423  //
424  Private->UgaHorizontalResolution  = HorizontalResolution;
425  Private->UgaVerticalResolution    = VerticalResolution;
426  Private->UgaColorDepth            = ColorDepth;
427  Private->UgaRefreshRate           = RefreshRate;
428
429  //
430  // return the worst status met
431  //
432  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
433
434    GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
435    if (GraphicsOutput != NULL) {
436      //
437      // Find corresponding ModeNumber of this GraphicsOutput instance
438      //
439      for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex ++) {
440        Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);
441        if (EFI_ERROR (Status)) {
442          return Status;
443        }
444        if ((Info->HorizontalResolution == HorizontalResolution) && (Info->VerticalResolution == VerticalResolution)) {
445          FreePool (Info);
446          break;
447        }
448        FreePool (Info);
449      }
450
451      Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);
452      if (EFI_ERROR (Status)) {
453        ReturnStatus = Status;
454      }
455    } else if (FeaturePcdGet (PcdUgaConsumeSupport)){
456      UgaDraw = Private->TextOutList[Index].UgaDraw;
457      if (UgaDraw != NULL) {
458        Status = UgaDraw->SetMode (
459                          UgaDraw,
460                          HorizontalResolution,
461                          VerticalResolution,
462                          ColorDepth,
463                          RefreshRate
464                          );
465        if (EFI_ERROR (Status)) {
466          ReturnStatus = Status;
467        }
468      }
469    }
470  }
471
472  return ReturnStatus;
473}
474
475
476/**
477  Blt a rectangle of pixels on the graphics screen.
478
479  The following table defines actions for BltOperations.
480
481  EfiUgaVideoFill:
482    Write data from the  BltBuffer pixel (SourceX, SourceY)
483    directly to every pixel of the video display rectangle
484    (DestinationX, DestinationY)
485    (DestinationX + Width, DestinationY + Height).
486    Only one pixel will be used from the BltBuffer. Delta is NOT used.
487  EfiUgaVideoToBltBuffer:
488    Read data from the video display rectangle
489    (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
490    the BltBuffer rectangle (DestinationX, DestinationY )
491    (DestinationX + Width, DestinationY + Height). If DestinationX or
492    DestinationY is not zero then Delta must be set to the length in bytes
493    of a row in the BltBuffer.
494  EfiUgaBltBufferToVideo:
495    Write data from the  BltBuffer rectangle
496    (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
497    video display rectangle (DestinationX, DestinationY)
498    (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
499    not zero then Delta must be set to the length in bytes of a row in the
500    BltBuffer.
501  EfiUgaVideoToVideo:
502    Copy from the video display rectangle
503    (SourceX, SourceY) (SourceX + Width, SourceY + Height) .
504    to the video display rectangle (DestinationX, DestinationY)
505    (DestinationX + Width, DestinationY + Height).
506    The BltBuffer and Delta  are not used in this mode.
507
508  @param  This           Protocol instance pointer.
509  @param  BltBuffer      Buffer containing data to blit into video buffer. This
510                         buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
511  @param  BltOperation   Operation to perform on BlitBuffer and video memory
512  @param  SourceX        X coordinate of source for the BltBuffer.
513  @param  SourceY        Y coordinate of source for the BltBuffer.
514  @param  DestinationX   X coordinate of destination for the BltBuffer.
515  @param  DestinationY   Y coordinate of destination for the BltBuffer.
516  @param  Width          Width of rectangle in BltBuffer in pixels.
517  @param  Height         Hight of rectangle in BltBuffer in pixels.
518  @param  Delta          OPTIONAL
519
520  @retval EFI_SUCCESS            The Blt operation completed.
521  @retval EFI_INVALID_PARAMETER  BltOperation is not valid.
522  @retval EFI_DEVICE_ERROR       A hardware error occured writting to the video buffer.
523
524**/
525EFI_STATUS
526EFIAPI
527ConSplitterUgaDrawBlt (
528  IN  EFI_UGA_DRAW_PROTOCOL                         *This,
529  IN  EFI_UGA_PIXEL                                 *BltBuffer, OPTIONAL
530  IN  EFI_UGA_BLT_OPERATION                         BltOperation,
531  IN  UINTN                                         SourceX,
532  IN  UINTN                                         SourceY,
533  IN  UINTN                                         DestinationX,
534  IN  UINTN                                         DestinationY,
535  IN  UINTN                                         Width,
536  IN  UINTN                                         Height,
537  IN  UINTN                                         Delta         OPTIONAL
538  )
539{
540  EFI_STATUS                      Status;
541  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;
542  UINTN                           Index;
543  EFI_STATUS                      ReturnStatus;
544  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
545
546  Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
547
548  ReturnStatus = EFI_SUCCESS;
549  //
550  // return the worst status met
551  //
552  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
553    GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
554    if (GraphicsOutput != NULL) {
555      Status = GraphicsOutput->Blt (
556                              GraphicsOutput,
557                              (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltBuffer,
558                              (EFI_GRAPHICS_OUTPUT_BLT_OPERATION) BltOperation,
559                              SourceX,
560                              SourceY,
561                              DestinationX,
562                              DestinationY,
563                              Width,
564                              Height,
565                              Delta
566                              );
567      if (EFI_ERROR (Status)) {
568        ReturnStatus = Status;
569      } else if (BltOperation == EfiUgaVideoToBltBuffer) {
570        //
571        // Only need to read the data into buffer one time
572        //
573        return EFI_SUCCESS;
574      }
575    }
576
577    if (Private->TextOutList[Index].UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
578      Status = Private->TextOutList[Index].UgaDraw->Blt (
579                                                      Private->TextOutList[Index].UgaDraw,
580                                                      BltBuffer,
581                                                      BltOperation,
582                                                      SourceX,
583                                                      SourceY,
584                                                      DestinationX,
585                                                      DestinationY,
586                                                      Width,
587                                                      Height,
588                                                      Delta
589                                                      );
590      if (EFI_ERROR (Status)) {
591        ReturnStatus = Status;
592      } else if (BltOperation == EfiUgaVideoToBltBuffer) {
593        //
594        // Only need to read the data into buffer one time
595        //
596        return EFI_SUCCESS;
597      }
598    }
599  }
600
601  return ReturnStatus;
602}
603
604/**
605  Sets the output device(s) to a specified mode.
606
607  @param  Private                 Text Out Splitter pointer.
608  @param  ModeNumber              The mode number to set.
609
610**/
611VOID
612TextOutSetMode (
613  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,
614  IN  UINTN                           ModeNumber
615  )
616{
617  //
618  // No need to do extra check here as whether (Column, Row) is valid has
619  // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
620  // always be supported.
621  //
622  Private->TextOutMode.Mode          = (INT32) ModeNumber;
623  Private->TextOutMode.CursorColumn  = 0;
624  Private->TextOutMode.CursorRow     = 0;
625  Private->TextOutMode.CursorVisible = TRUE;
626
627  return;
628}
629