다음을 통해 공유


잉크 스레딩 모델

태블릿 PC에서 잉크의 이점 중 하나는 일반 펜으로 종이에 쓰는 것과 같은 느낌을 준다는 점입니다. 이를 위해 태블릿 펜은 마우스보다 훨씬 빠른 속도로 입력 데이터를 수집하고 사용자가 쓸 때 잉크를 렌더링합니다. 애플리케이션의 UI(사용자 인터페이스) 스레드는 차단될 수 있으므로 펜 데이터를 수집하고 잉크를 렌더링하는 데 충분하지 않습니다. 이 문제를 해결하기 위해 WPF 애플리케이션은 사용자가 잉크를 쓸 때 추가 스레드 두 개를 사용합니다.

다음 목록에서는 디지털 잉크 수집과 렌더링에 관여하는 스레드를 설명합니다.

  • 펜 스레드 - 스타일러스의 입력을 사용하는 스레드입니다. (실제로는 스레드 풀이지만 이 토픽에서는 펜 스레드라고 합니다.)

  • 애플리케이션 사용자 인터페이스 스레드 - 애플리케이션 사용자 인터페이스를 제어하는 스레드입니다.

  • 동적 렌더링 스레드 - 사용자가 스트로크를 그리는 동안 잉크를 렌더링하는 스레드입니다. 동적 렌더링 스레드는 Window Presentation Foundation 스레딩 모델의 설명대로 애플리케이션의 다른 UI 요소를 렌더링하는 스레드와 다릅니다.

잉크 입력 모델은 애플리케이션에서 InkCanvas 또는 잉크 입력 컨트롤 만들기의 컨트롤과 비슷한 사용자 지정 컨트롤을 사용하는지에 관계없이 동일합니다. 이 토픽에서는 InkCanvas 관점에서 스레딩을 설명하지만 사용자 지정 컨트롤을 만들 때 같은 개념이 적용됩니다.

스레딩 개요

다음 다이어그램에서는 사용자가 스트로크를 그릴 때의 스레딩 모델을 보여줍니다.

Threading model while drawing a stroke.스트로크를 그리는 스레딩 모델.InkThreading_DrawingInk

  1. 사용자가 스트로크를 그리는 동안 발생하는 작업

    1. 사용자가 스트로크를 그리면 스타일러스 포인트가 펜 스레드에서 수신됩니다. DynamicRenderer를 포함한 스타일러스 플러그 인은 펜 스레드의 스타일러스 포인트를 수락하고 InkCanvas에서 수신하기 전에 수정할 수 있습니다.

    2. DynamicRenderer는 동적 렌더링 스레드의 스타일러스 포인트를 렌더링합니다. 이는 이전 단계와 동시에 발생합니다.

    3. InkCanvas는 UI 스레드의 스타일러스 포인트를 수신합니다.

  2. 사용자가 스트로크를 종료한 후에 발생하는 작업

    1. 사용자가 스트로크 그리기를 마치면 InkCanvas에서 Stroke 개체를 만들고 정적으로 렌더링하는 InkPresenter에 추가합니다.

    2. UI 스레드는 스트로크가 정적으로 렌더링된 DynamicRenderer를 경고하므로 DynamicRenderer에서 스트로크의 시각적 표현을 제거합니다.

잉크 컬렉션 및 스타일러스 플러그 인

UIElement마다 StylusPlugInCollection이 있습니다. StylusPlugInCollection에 있는 StylusPlugIn 개체가 펜 스레드의 스타일러스 포인트를 수신하고 수정할 수 있습니다. StylusPlugIn 개체는 StylusPlugInCollection의 순서에 따라 스타일러스 포인트를 수신합니다.

다음 다이어그램에서는 해당 순서대로 UIElementStylusPlugIns 컬렉션에 stylusPlugin1, DynamicRendererstylusPlugin2가 포함된 가상 상황을 보여줍니다.

Order of Stylus Plugins affect output.스타일러스 플러그인의 주문이 출력에 영향을 줍니다.InkThreading_PluginOrder

이전 다이어그램에서 다음 동작이 수행됩니다.

  1. StylusPlugin1에서 x 값과 y 값을 수정합니다.

  2. DynamicRenderer에서 수정된 스타일러스 포인트를 수신하고 동적 렌더링 스레드에서 렌더링합니다.

  3. StylusPlugin2에서 수정된 스타일러스 포인트를 수신하고 x 값과 y 값을 추가로 수정합니다.

  4. 애플리케이션에서 스타일러스 포인트를 수집하고 사용자가 스트로크를 완료하면 스트로크를 정적으로 렌더링합니다.

stylusPlugin1에서 스타일러스 포인트를 사각형으로 제한하고 stylusPlugin2에서 스타일러스 포인트를 오른쪽으로 변환한다고 가정합니다. 이전 시나리오에서 DynamicRenderer는 제한된 스타일러스 포인트를 수신하지만 변환된 스타일러스 포인트를 수신하지 않습니다. 사용자가 스트로크를 그리면 스트로크는 사각형 범위 내에서 렌더링되지만 사용자가 펜을 들어 올릴 때까지 스트로크가 변환되지 않는 것처럼 보입니다.

UI 스레드에서 스타일러스 플러그 인을 사용하여 작업 수행

펜 스레드에서 정확한 적중 테스트를 수행할 수 없으므로, 일부 요소가 다른 요소에 대 한 스타일러스 입력을 받는 경우도 합니다. 입력이 작업을 수행 하기 전에 올바르게 라우트 되도록 해야 하는 경우 등록 하 고 작업을 수행 합니다 OnStylusDownProcessed, OnStylusMoveProcessed, 또는 OnStylusUpProcessed 메서드. 이러한 메서드는 정확한 적중 테스트가 수행된 후 애플리케이션 스레드에서 호출됩니다. 를 구독 하려면 이러한 메서드 호출을 NotifyWhenProcessed 펜 스레드에서 발생 하는 방법에 대 한 메서드.

다음 다이어그램에서는 StylusPlugIn의 스타일러스 이벤트에 대한 펜 스레드와 UI 스레드 간의 관계를 보여줍니다.

Ink Threading Models (UI and Pen)잉크 스레딩 모델(UI 및 펜)InkThreading_PluginCallbacks

잉크 렌더링

사용자가 스트로크를 그릴 때 DynamicRenderer는 UI 스레드가 사용 중인 경우에도 잉크가 펜에서 "흐름"으로 표시되도록 별도의 스레드에서 잉크를 렌더링합니다. DynamicRenderer는 스타일러스 포인트를 수집할 때 동적 렌더링 스레드에 시각적 트리를 빌드합니다. 사용자가 스트로크를 마치면 애플리케이션이 다음 렌더링을 전달하면 DynamicRenderer에서 알림을 전송합니다. 애플리케이션이 다음 렌더링 전달을 완료하면 DynamicRenderer에서 시각적 트리를 정리합니다. 다음 다이어그램에서는 이 프로세스를 보여 줍니다.

Ink threading diagram잉크 스레딩 다이어그램InkThreading_VisualTree

  1. 사용자가 스트로크를 시작합니다.

    1. DynamicRenderer에서 시각적 트리를 만듭니다.
  2. 사용자가 스트로크를 그리고 있습니다.

    1. DynamicRenderer에서 시각적 트리를 빌드합니다.
  3. 사용자가 스트로크를 종료합니다.

    1. InkPresenter에서 스트로크를 시각적 트리에 추가합니다.

    2. MIL(Media Integration Layer)은 스트로크를 정적으로 렌더링합니다.

    3. DynamicRenderer에서 시각적 개체를 정리합니다.