µC/GUI 窗口重绘机制与回调流程深度剖析

개요

µC/GUI의 윈도우 재그리기(Repaint) 메커니즘은 이벤트 기반 아키텍처를 이해하는 핵심입니다. 이 시스템은 '할리우드 법칙(Hollywood Principle: "저희에게 전화하지 마세요, 저희가 필요할 때 연락하겠습니다")'을 따르며, 그래픽 관리자가 사용자 정의 콜백 함수를 호출하여 화면을 갱신하는 방식을 취합니다. 이러한 구조는 클리핑 알고리즘과 결합하여 효율적인 화면 업데이트를 보장합니다.

핵심 데이터 구조

윈도우 관리는 WM_Obj 구조체를 중심으로 이루어지며, 각 윈도우는 고유의 콜백 함수 포인터와 무효 영역(Invalid Area) 정보를 포함합니다.

typedef struct {
  GUI_RECT Rect;         // 윈도우 경계 사각형
  GUI_RECT InvalidArea;  // 다시 그려야 할 영역
  WM_CALLBACK* cb;       // 사용자 정의 콜백 함수
  WM_HWIN hNext;         // 형제 윈도우 체인
  WM_HWIN hParent;       // 부모 윈도우
  U16 Status;            // 상태 플래그
} WM_Obj;

메시지 처리는 WM_MESSAGE 구조체를 통해 전달됩니다. 핵심 메시지인 WM_PAINT는 윈도우 관리자가 특정 윈도우를 다시 그려야 할 때 시스템 내부에서 발생시키는 이벤트입니다.

재그리기 처리 파이프라인

화면 갱신은 단순히 함수를 호출하는 것이 아니라, 여러 계층을 거쳐 실행되는 비동기적 흐름을 따릅니다. 주요 호출 스택은 다음과 같습니다:

  1. GUI_Exec(): 최상위 루프, 처리가 필요한 모든 메시지 및 타이머를 처리합니다.
  2. WM_Exec(): 유효하지 않은 윈도우(Invalidated Windows)를 찾아 업데이트 프로세스를 시작합니다.
  3. _DrawNext(): 윈도우 체인을 순회하며 재그리기가 필요한 노드를 식별합니다.
  4. WM__Paint(): 무효 상태인 윈도우를 선택하고, 실제 드로잉 수행 전 클리핑 영역을 계산합니다.
  5. WM__SendMessage(): 최종적으로 등록된 콜백 함수를 실행하여 사용자 정의 그리기 코드를 수행합니다.

메시지 발송 및 콜백 실행

WM__SendMessage 함수는 실제 작업을 수행하는 엔진입니다. 윈도우 객체에 콜백 함수가 등록되어 있다면 이를 직접 호출하고, 없다면 기본 처리 함수를 실행합니다.

void DispatchWindowMessage(WM_HWIN hWin, WM_MESSAGE* pMsg) {
    WM_Obj* pObj = GetWindowPointer(hWin);
    
    if (pObj->cb != NULL) {
        // 등록된 콜백 함수 호출 (이벤트 처리)
        pObj->cb(pMsg);
    } else {
        // 기본 윈도우 프로세스 실행
        DefaultProc(pMsg);
    }
}

재그리기 최적화

GUI 시스템은 효율성을 위해 한 번의 사이클에 전체 화면을 다 그리지 않습니다. _DrawNext 함수를 통해 호출되는 렌더링 로직은 다음 특징을 가집니다:

  • 무효 영역 갱신: WM__NumInvalidWindows 카운터를 사용하여 변경이 필요한 윈도우만 타겟팅합니다.
  • 상태 복구: GUI_SaveContextGUI_RestoreContext를 사용하여 그래픽 컨텍스트(펜 색상, 폰트 등)가 훼손되지 않도록 보존합니다.
  • 분할 처리: 복잡한 윈도우의 경우 WM_ITERATE_START 매크로를 활용해 클리핑 사각형 단위로 메시지를 분할 발송하여 메모리 부하를 줄입니다.

최종적으로 WM__Paint 내부에서 WM_SF_INVALID 플래그를 해제함으로써, 갱신된 영역이 다시 그려지지 않도록 하여 불필요한 연산을 방지합니다.

태그: uCGUI EmbeddedGUI WindowManager Callback Rendering

6월 7일 00:50에 게시됨