OpenCanopy: Move absolute pointer querying to timed event

Removes pointer update concurrency and absolute pointer input lag.
This commit is contained in:
Marvin Häuser 2021-03-20 17:50:20 +01:00
parent 18646092b0
commit 9452be4b7e
6 changed files with 31 additions and 69 deletions

View File

@ -234,17 +234,4 @@ OcGetTSCFrequency (
VOID
);
/**
Atomically pre-increment 8-bit integer.
@param[in] Value Pointer to 8-bit integer to increment.
@retval value before incrementing.
**/
UINT8
EFIAPI
OcAtomicPreIncUint8 (
IN OUT volatile UINT8 *Value
);
#endif // OC_CPU_LIB_H_

View File

@ -18,20 +18,6 @@ DEFAULT REL
SECTION .text
;------------------------------------------------------------------------------
; UINT8
; EFIAPI
; OcAtomicPreIncUint8 (
; IN OUT volatile UINT8 *Value
; );
;------------------------------------------------------------------------------
global ASM_PFX(OcAtomicPreIncUint8)
ASM_PFX(OcAtomicPreIncUint8):
mov ecx, [esp + 4]
mov eax, 1
lock xadd byte [ecx], al
ret
;------------------------------------------------------------------------------
; UINT32
; EFIAPI

View File

@ -18,19 +18,6 @@ DEFAULT REL
SECTION .text
;------------------------------------------------------------------------------
; UINT8
; EFIAPI
; OcAtomicPreIncUint8 (
; IN OUT volatile UINT8 *Value
; );
;------------------------------------------------------------------------------
global ASM_PFX(OcAtomicPreIncUint8)
ASM_PFX(OcAtomicPreIncUint8):
mov eax, 1
lock xadd byte [rcx], al
ret
;------------------------------------------------------------------------------
; UINT32
; EFIAPI

View File

@ -13,10 +13,12 @@
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/AppleEventLib.h>
#include <Library/OcCpuLib.h>
#include <Library/OcGuardLib.h>
#include <Library/OcMiscLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include "../OpenCanopy.h"
#include "../GuiIo.h"
@ -28,6 +30,7 @@ struct GUI_POINTER_CONTEXT_ {
APPLE_EVENT_PROTOCOL *AppleEvent;
EFI_ABSOLUTE_POINTER_PROTOCOL *AbsPointer;
APPLE_EVENT_HANDLE AppleEventHandle;
EFI_EVENT AbsPollEvent;
UINT32 MaxX;
UINT32 MaxY;
GUI_PTR_POSITION RawPos;
@ -59,7 +62,6 @@ InternalQueuePointerEvent (
{
UINT32 Tail;
//
// Tail can be accessed concurrently, so increment atomically.
// Due to the modulus, wraparounds do not matter. The size of the queue must
// be a power of two for this to hold.
//
@ -68,10 +70,11 @@ InternalQueuePointerEvent (
"The pointer event queue must have a power of two length."
);
Tail = OcAtomicPreIncUint8 (&Context->EventQueueTail) % ARRAY_SIZE (Context->EventQueue);
Tail = Context->EventQueueTail % ARRAY_SIZE (Context->EventQueue);
Context->EventQueue[Tail].Type = Type;
Context->EventQueue[Tail].Pos.Pos.X = X;
Context->EventQueue[Tail].Pos.Pos.Y = Y;
++Context->EventQueueTail;
}
BOOLEAN
@ -80,9 +83,6 @@ GuiPointerGetEvent (
OUT GUI_PTR_EVENT *Event
)
{
//
// EventQueueHead cannot be accessed concurrently.
//
if (Context->EventQueueHead == Context->EventQueueTail) {
return FALSE;
}
@ -198,21 +198,23 @@ InternalAppleEventNotification (
STATIC
VOID
EFIAPI
InternalUpdateContextAbsolute (
IN OUT GUI_POINTER_CONTEXT *Context
IN EFI_EVENT Event,
IN OUT VOID *NotifyContext
)
{
GUI_POINTER_CONTEXT *Context;
EFI_STATUS Status;
EFI_ABSOLUTE_POINTER_STATE PointerState;
UINT64 NewX;
UINT64 NewY;
GUI_PTR_POSITION NewPos;
ASSERT (Context != NULL);
ASSERT (NotifyContext != NULL);
if (Context->AbsPointer == NULL) {
return;
}
Context = NotifyContext;
ASSERT (Context->AbsPointer != NULL);
//
// Discard absolute pointer updates when simple pointer locked.
//
@ -238,9 +240,7 @@ InternalUpdateContextAbsolute (
NewY,
(UINT32) (Context->AbsPointer->Mode->AbsoluteMaxY - Context->AbsPointer->Mode->AbsoluteMinY)
);
//
// This is not perfectly concurrent, but good enough.
//
Context->CurPos.Uint64 = NewPos.Uint64;
Context->RawPos.Uint64 = NewPos.Uint64;
//
@ -320,17 +320,13 @@ GuiPointerGetPosition (
ASSERT (Context != NULL);
ASSERT (Position != NULL);
//
// Prevent simple pointer updates during state retrieval.
// Prevent pointer updates during state retrieval.
// On 64+-bit systems, the operation is atomic.
//
if (sizeof (UINTN) < sizeof (UINT64)) {
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
}
//
// The simple pointer updates are done in InternalAppleEventNotification().
//
InternalUpdateContextAbsolute (Context);
//
// Return the current pointer position.
//
Position->Uint64 = Context->CurPos.Uint64;
@ -411,6 +407,17 @@ GuiPointerConstruct (
&gEfiAbsolutePointerProtocolGuid,
(VOID **)&Context.AbsPointer
);
if (!EFI_ERROR (Status2)) {
Context.AbsPollEvent = EventLibCreateNotifyTimerEvent (
InternalUpdateContextAbsolute,
&Context,
EFI_TIMER_PERIOD_MILLISECONDS (10),
TRUE
);
if (Context.AbsPollEvent == NULL) {
Status2 = EFI_UNSUPPORTED;
}
}
if (EFI_ERROR (Status) && EFI_ERROR (Status2)) {
return NULL;
@ -428,5 +435,10 @@ GuiPointerDestruct (
ASSERT (Context->AppleEvent != NULL);
Context->AppleEvent->UnregisterHandler (Context->AppleEventHandle);
if (Context->AbsPollEvent != NULL) {
EventLibCancelEvent (Context->AbsPollEvent);
}
ZeroMem (Context, sizeof (*Context));
}

View File

@ -82,3 +82,4 @@
TimerLib
UefiBootServicesTableLib
UefiDriverEntryPoint
OcAppleEventLib

View File

@ -161,17 +161,6 @@ AsmCpuidEx (
#endif
}
UINT8
EFIAPI
OcAtomicPreIncUint8 (
IN OUT volatile UINT8 *Value
)
{
ASSERT (FALSE);
return 0;
}
UINT32
EFIAPI
AsmIncrementUint32 (