mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-26 07:04:28 +02:00
EmulatorPkg/Win: Use FrameBufferBltLib for BLT operation
Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Hao Wu <hao.a.wu@intel.com> Cc: Andrew Fish <afish@apple.com>
This commit is contained in:
parent
ce8c1d92f5
commit
d773459e2f
@ -55,6 +55,7 @@
|
|||||||
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
|
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
|
||||||
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
|
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
|
||||||
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
|
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
|
||||||
|
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# UEFI & PI
|
# UEFI & PI
|
||||||
|
@ -31,6 +31,7 @@ Abstract:
|
|||||||
#include <Protocol/SimpleTextIn.h>
|
#include <Protocol/SimpleTextIn.h>
|
||||||
#include <Protocol/SimpleTextInEx.h>
|
#include <Protocol/SimpleTextInEx.h>
|
||||||
#include <Protocol/GraphicsOutput.h>
|
#include <Protocol/GraphicsOutput.h>
|
||||||
|
#include <Library/FrameBufferBltLib.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// WM_SYSKEYDOWN/WM_SYSKEYUP Notification
|
// WM_SYSKEYDOWN/WM_SYSKEYUP Notification
|
||||||
@ -86,9 +87,8 @@ typedef struct {
|
|||||||
// updated in the main thread and displayed in the windows thread.
|
// updated in the main thread and displayed in the windows thread.
|
||||||
//
|
//
|
||||||
BITMAPV4HEADER *VirtualScreenInfo;
|
BITMAPV4HEADER *VirtualScreenInfo;
|
||||||
RGBQUAD *VirtualScreen;
|
|
||||||
|
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *FillLine;
|
FRAME_BUFFER_CONFIGURE *FrameBufferConfigure;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Keyboard Queue used by Simple Text In.
|
// Keyboard Queue used by Simple Text In.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/** @file
|
/** @file
|
||||||
|
|
||||||
Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -193,15 +193,63 @@ WinNtWndSize (
|
|||||||
IN UINT32 Height
|
IN UINT32 Height
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT32 Size;
|
RETURN_STATUS RStatus;
|
||||||
|
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION Info;
|
||||||
GRAPHICS_PRIVATE_DATA *Private;
|
GRAPHICS_PRIVATE_DATA *Private;
|
||||||
RECT Rect;
|
RECT Rect;
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewFillLine;
|
BITMAPV4HEADER *VirtualScreenInfo;
|
||||||
|
FRAME_BUFFER_CONFIGURE *FrameBufferConfigure;
|
||||||
|
UINTN FrameBufferConfigureSize;
|
||||||
|
|
||||||
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
|
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
|
||||||
Private->Width = Width;
|
|
||||||
Private->Height = Height;
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate DIB frame buffer directly from NT for performance enhancement
|
||||||
|
// This buffer is the virtual screen/frame buffer.
|
||||||
|
//
|
||||||
|
VirtualScreenInfo = HeapAlloc (
|
||||||
|
GetProcessHeap (),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
Width * Height * sizeof (RGBQUAD) + sizeof (BITMAPV4HEADER)
|
||||||
|
);
|
||||||
|
if (VirtualScreenInfo == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update the virtual screen info data structure
|
||||||
|
// Use negative Height to make sure screen/buffer are using the same coordinate.
|
||||||
|
//
|
||||||
|
VirtualScreenInfo->bV4Size = sizeof (BITMAPV4HEADER);
|
||||||
|
VirtualScreenInfo->bV4Width = Width;
|
||||||
|
VirtualScreenInfo->bV4Height = -(LONG)Height;
|
||||||
|
VirtualScreenInfo->bV4Planes = 1;
|
||||||
|
VirtualScreenInfo->bV4BitCount = 32;
|
||||||
|
//
|
||||||
|
// uncompressed
|
||||||
|
//
|
||||||
|
VirtualScreenInfo->bV4V4Compression = BI_RGB;
|
||||||
|
|
||||||
|
Info.HorizontalResolution = Width;
|
||||||
|
Info.VerticalResolution = Height;
|
||||||
|
Info.PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
|
||||||
|
Info.PixelsPerScanLine = Width;
|
||||||
|
FrameBufferConfigureSize = 0;
|
||||||
|
RStatus = FrameBufferBltConfigure (VirtualScreenInfo + 1, &Info, NULL, &FrameBufferConfigureSize);
|
||||||
|
ASSERT (RStatus == EFI_BUFFER_TOO_SMALL);
|
||||||
|
FrameBufferConfigure = AllocatePool (FrameBufferConfigureSize);
|
||||||
|
if (FrameBufferConfigure == NULL) {
|
||||||
|
HeapFree (GetProcessHeap (), 0, VirtualScreenInfo);
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
RStatus = FrameBufferBltConfigure (VirtualScreenInfo + 1, &Info, FrameBufferConfigure, &FrameBufferConfigureSize);
|
||||||
|
ASSERT_RETURN_ERROR (RStatus);
|
||||||
|
|
||||||
|
|
||||||
|
if (Private->FrameBufferConfigure != NULL) {
|
||||||
|
FreePool (Private->FrameBufferConfigure);
|
||||||
|
}
|
||||||
|
Private->FrameBufferConfigure = FrameBufferConfigure;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Free the old buffer. We do not save the content of the old buffer since the
|
// Free the old buffer. We do not save the content of the old buffer since the
|
||||||
@ -211,37 +259,10 @@ WinNtWndSize (
|
|||||||
if (Private->VirtualScreenInfo != NULL) {
|
if (Private->VirtualScreenInfo != NULL) {
|
||||||
HeapFree (GetProcessHeap (), 0, Private->VirtualScreenInfo);
|
HeapFree (GetProcessHeap (), 0, Private->VirtualScreenInfo);
|
||||||
}
|
}
|
||||||
|
Private->VirtualScreenInfo = VirtualScreenInfo;
|
||||||
|
|
||||||
//
|
Private->Width = Width;
|
||||||
// Allocate DIB frame buffer directly from NT for performance enhancement
|
Private->Height = Height;
|
||||||
// This buffer is the virtual screen/frame buffer. This buffer is not the
|
|
||||||
// same a a frame buffer. The first row of this buffer will be the bottom
|
|
||||||
// line of the image. This is an artifact of the way we draw to the screen.
|
|
||||||
//
|
|
||||||
Size = Private->Width * Private->Height * sizeof (RGBQUAD) + sizeof (BITMAPV4HEADER);
|
|
||||||
Private->VirtualScreenInfo = HeapAlloc (
|
|
||||||
GetProcessHeap (),
|
|
||||||
HEAP_ZERO_MEMORY,
|
|
||||||
Size
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Update the virtual screen info data structure
|
|
||||||
//
|
|
||||||
Private->VirtualScreenInfo->bV4Size = sizeof (BITMAPV4HEADER);
|
|
||||||
Private->VirtualScreenInfo->bV4Width = Private->Width;
|
|
||||||
Private->VirtualScreenInfo->bV4Height = Private->Height;
|
|
||||||
Private->VirtualScreenInfo->bV4Planes = 1;
|
|
||||||
Private->VirtualScreenInfo->bV4BitCount = 32;
|
|
||||||
//
|
|
||||||
// uncompressed
|
|
||||||
//
|
|
||||||
Private->VirtualScreenInfo->bV4V4Compression = BI_RGB;
|
|
||||||
|
|
||||||
//
|
|
||||||
// The rest of the allocated memory block is the virtual screen buffer
|
|
||||||
//
|
|
||||||
Private->VirtualScreen = (RGBQUAD *)(Private->VirtualScreenInfo + 1);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Use the AdjuctWindowRect fuction to calculate the real width and height
|
// Use the AdjuctWindowRect fuction to calculate the real width and height
|
||||||
@ -249,8 +270,8 @@ WinNtWndSize (
|
|||||||
//
|
//
|
||||||
Rect.left = 0;
|
Rect.left = 0;
|
||||||
Rect.top = 0;
|
Rect.top = 0;
|
||||||
Rect.right = Private->Width;
|
Rect.right = Width;
|
||||||
Rect.bottom = Private->Height;
|
Rect.bottom = Height;
|
||||||
|
|
||||||
AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0);
|
AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0);
|
||||||
|
|
||||||
@ -267,16 +288,6 @@ WinNtWndSize (
|
|||||||
//
|
//
|
||||||
MoveWindow (Private->WindowHandle, Rect.left, Rect.top, (INT32)Width, (INT32)Height, TRUE);
|
MoveWindow (Private->WindowHandle, Rect.left, Rect.top, (INT32)Width, (INT32)Height, TRUE);
|
||||||
|
|
||||||
NewFillLine = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * Private->Width);
|
|
||||||
if (NewFillLine == NULL) {
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Private->FillLine != NULL) {
|
|
||||||
FreePool (Private->FillLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
Private->FillLine = NewFillLine;
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,68 +333,22 @@ WinNtWndBlt (
|
|||||||
IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args
|
IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
RETURN_STATUS RStatus;
|
||||||
GRAPHICS_PRIVATE_DATA *Private;
|
GRAPHICS_PRIVATE_DATA *Private;
|
||||||
UINTN DstY;
|
|
||||||
UINTN SrcY;
|
|
||||||
RGBQUAD *VScreen;
|
|
||||||
RGBQUAD *VScreenSrc;
|
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
|
|
||||||
UINTN Index;
|
|
||||||
RECT Rect;
|
RECT Rect;
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *FillPixel;
|
|
||||||
UINT32 VerticalResolution;
|
|
||||||
UINT32 HorizontalResolution;
|
|
||||||
|
|
||||||
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
|
Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo);
|
||||||
|
RStatus = FrameBufferBlt (
|
||||||
//
|
Private->FrameBufferConfigure,
|
||||||
// We need to fill the Virtual Screen buffer with the blt data.
|
BltBuffer,
|
||||||
// The virtual screen is upside down, as the first row is the bootom row of
|
BltOperation,
|
||||||
// the image.
|
Args->SourceX, Args->SourceY,
|
||||||
//
|
Args->DestinationX, Args->DestinationY,
|
||||||
VerticalResolution = Private->VirtualScreenInfo->bV4Height;
|
Args->Width, Args->Height,
|
||||||
HorizontalResolution = Private->VirtualScreenInfo->bV4Width;
|
Args->Delta
|
||||||
if (BltOperation == EfiBltVideoToBltBuffer) {
|
);
|
||||||
|
if (RETURN_ERROR (RStatus)) {
|
||||||
for (SrcY = Args->SourceY, DstY = Args->DestinationY; DstY < (Args->Height + Args->DestinationY); SrcY++, DstY++) {
|
return (EFI_STATUS)RStatus;
|
||||||
Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Args->Delta) + Args->DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
|
|
||||||
VScreen = &Private->VirtualScreen[(VerticalResolution - SrcY - 1) * HorizontalResolution + Args->SourceX];
|
|
||||||
CopyMem (Blt, VScreen, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * Args->Width);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (BltOperation == EfiBltVideoFill) {
|
|
||||||
FillPixel = BltBuffer;
|
|
||||||
for (Index = 0; Index < Args->Width; Index++) {
|
|
||||||
Private->FillLine[Index] = *FillPixel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Index = 0; Index < Args->Height; Index++) {
|
|
||||||
if (Args->DestinationY <= Args->SourceY) {
|
|
||||||
SrcY = Args->SourceY + Index;
|
|
||||||
DstY = Args->DestinationY + Index;
|
|
||||||
} else {
|
|
||||||
SrcY = Args->SourceY + Args->Height - Index - 1;
|
|
||||||
DstY = Args->DestinationY + Args->Height - Index - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
VScreen = &Private->VirtualScreen[(VerticalResolution - DstY - 1) * HorizontalResolution + Args->DestinationX];
|
|
||||||
switch (BltOperation) {
|
|
||||||
case EfiBltBufferToVideo:
|
|
||||||
Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Args->Delta) + Args->SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
|
|
||||||
CopyMem (VScreen, Blt, Args->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EfiBltVideoToVideo:
|
|
||||||
VScreenSrc = &Private->VirtualScreen[(VerticalResolution - SrcY - 1) * HorizontalResolution + Args->SourceX];
|
|
||||||
CopyMem (VScreen, VScreenSrc, Args->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EfiBltVideoFill:
|
|
||||||
CopyMem (VScreen, Private->FillLine, Args->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BltOperation != EfiBltVideoToBltBuffer) {
|
if (BltOperation != EfiBltVideoToBltBuffer) {
|
||||||
@ -435,21 +400,12 @@ WinNtGopThreadWindowProc (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
GRAPHICS_PRIVATE_DATA *Private;
|
GRAPHICS_PRIVATE_DATA *Private;
|
||||||
UINTN Size;
|
|
||||||
HDC Handle;
|
HDC Handle;
|
||||||
PAINTSTRUCT PaintStruct;
|
PAINTSTRUCT PaintStruct;
|
||||||
LPARAM Index;
|
LPARAM Index;
|
||||||
EFI_INPUT_KEY Key;
|
EFI_INPUT_KEY Key;
|
||||||
BOOLEAN AltIsPress;
|
BOOLEAN AltIsPress;
|
||||||
|
|
||||||
//
|
|
||||||
// BugBug - if there are two instances of this DLL in memory (such as is
|
|
||||||
// the case for ERM), the correct instance of this function may not be called.
|
|
||||||
// This also means that the address of the mTlsIndex value will be wrong, and
|
|
||||||
// the value may be wrong too.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Use mTlsIndex global to get a Thread Local Storage version of Private.
|
// Use mTlsIndex global to get a Thread Local Storage version of Private.
|
||||||
// This works since each Gop protocol has a unique Private data instance and
|
// This works since each Gop protocol has a unique Private data instance and
|
||||||
@ -460,39 +416,7 @@ WinNtGopThreadWindowProc (
|
|||||||
ASSERT (NULL != Private);
|
ASSERT (NULL != Private);
|
||||||
|
|
||||||
switch (iMsg) {
|
switch (iMsg) {
|
||||||
case WM_CREATE:
|
|
||||||
Size = Private->Width * Private->Height * sizeof (RGBQUAD);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate DIB frame buffer directly from NT for performance enhancement
|
|
||||||
// This buffer is the virtual screen/frame buffer. This buffer is not the
|
|
||||||
// same a a frame buffer. The first fow of this buffer will be the bottom
|
|
||||||
// line of the image. This is an artifact of the way we draw to the screen.
|
|
||||||
//
|
|
||||||
Private->VirtualScreenInfo = HeapAlloc (
|
|
||||||
GetProcessHeap (),
|
|
||||||
HEAP_ZERO_MEMORY,
|
|
||||||
Size
|
|
||||||
);
|
|
||||||
|
|
||||||
Private->VirtualScreenInfo->bV4Size = sizeof (BITMAPV4HEADER);
|
|
||||||
Private->VirtualScreenInfo->bV4Width = Private->Width;
|
|
||||||
Private->VirtualScreenInfo->bV4Height = Private->Height;
|
|
||||||
Private->VirtualScreenInfo->bV4Planes = 1;
|
|
||||||
Private->VirtualScreenInfo->bV4BitCount = 32;
|
|
||||||
//
|
|
||||||
// uncompressed
|
|
||||||
//
|
|
||||||
Private->VirtualScreenInfo->bV4V4Compression = BI_RGB;
|
|
||||||
Private->VirtualScreen = (RGBQUAD *) (Private->VirtualScreenInfo + 1);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
//
|
|
||||||
// I have not found a way to convert hwnd into a Private context. So for
|
|
||||||
// now we use this API to convert hwnd to Private data.
|
|
||||||
//
|
|
||||||
|
|
||||||
Handle = BeginPaint (hwnd, &PaintStruct);
|
Handle = BeginPaint (hwnd, &PaintStruct);
|
||||||
|
|
||||||
SetDIBitsToDevice (
|
SetDIBitsToDevice (
|
||||||
@ -505,7 +429,7 @@ WinNtGopThreadWindowProc (
|
|||||||
0, // Source Y
|
0, // Source Y
|
||||||
0, // DIB Start Scan Line
|
0, // DIB Start Scan Line
|
||||||
Private->Height, // Number of scan lines
|
Private->Height, // Number of scan lines
|
||||||
Private->VirtualScreen, // Address of array of DIB bits
|
Private->VirtualScreenInfo + 1, // Address of array of DIB bits
|
||||||
(BITMAPINFO *) Private->VirtualScreenInfo, // Address of structure with bitmap info
|
(BITMAPINFO *) Private->VirtualScreenInfo, // Address of structure with bitmap info
|
||||||
DIB_RGB_COLORS // RGB or palette indexes
|
DIB_RGB_COLORS // RGB or palette indexes
|
||||||
);
|
);
|
||||||
@ -691,10 +615,6 @@ WinNtGopThreadWinMain (
|
|||||||
// This call will fail after the first time, but thats O.K. since we only need
|
// This call will fail after the first time, but thats O.K. since we only need
|
||||||
// WIN_NT_GOP_CLASS_NAME to exist to create the window.
|
// WIN_NT_GOP_CLASS_NAME to exist to create the window.
|
||||||
//
|
//
|
||||||
// Note: Multiple instances of this DLL will use the same instance of this
|
|
||||||
// Class, including the callback function, unless the Class is unregistered and
|
|
||||||
// successfully registered again.
|
|
||||||
//
|
|
||||||
RegisterClassEx (&Private->WindowsClass);
|
RegisterClassEx (&Private->WindowsClass);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
ThunkProtocolList
|
ThunkProtocolList
|
||||||
PpiListLib
|
PpiListLib
|
||||||
PeiServicesLib
|
PeiServicesLib
|
||||||
|
FrameBufferBltLib
|
||||||
|
|
||||||
[Ppis]
|
[Ppis]
|
||||||
gEmuThunkPpiGuid
|
gEmuThunkPpiGuid
|
||||||
|
Loading…
x
Reference in New Issue
Block a user