基本概念

注意

針對Windows 10上的應用程式,我們建議使用 Windows.UI.Composition API,而不是 DirectComposition。 如需詳細資訊,請參閱 使用視覺層將傳統型應用程式現代化

本主題提供 Microsoft DirectComposition 基本概念的概觀。 它包含下列區段:

撰寫

DirectComposition 會套用各種轉換、效果和動畫,以在應用程式 UI 中產生視覺效果結果,將 組合 定義為結合及操作的點陣圖集合。 DirectComposition 僅適用于點陣圖內容;它不支援向量或文字。 DirectComposition 不提供點陣圖內容。 而是提供介面,讓使用者可以使用 D2D、DXGI 繪製,或上傳自己的紋理內容。

DirectComposition 應用程式會建立兩組物件來撰寫場景:組合在一起的點陣圖,以及定義點陣圖之間空間關聯性的視覺效果。 如需 DirectComposition 所支援之點陣圖物件的詳細資訊,請參閱 Bitmap 物件

視覺效果

視覺效果 (或 視覺物件) 是 DirectComposition 的基本元素。 它們是您在應用程式 UI 中用來建立組合和動畫的基本建置組塊。

在程式設計詞彙中,視覺效果是具有一組屬性的物件,並公開您用來設定屬性值的介面。 視覺效果的 Content 屬性會將特定點陣圖與視覺效果產生關聯,而其他屬性則控制 DirectComposition 在呈現至畫面時如何放置及操作視覺效果。

如需詳細資訊,請參閱 視覺效果的屬性

視覺化樹狀結構

DirectComposition 會從稱為視覺化 狀結構之視覺物件的階層式集合建立組合。 樹狀結構根目錄的 視覺效果稱為根視覺效果 ,它可以有一或多個 與其相關聯的子視覺效果 。 子視覺效果可以有自己的一或多個子視覺效果。 任何具有相關聯子 視覺效果的視覺效果稱為父視覺效果,而共用相同父系的所有子視覺效果稱為 同層級視覺效果。 特定視覺效果及其所有子系和子系視覺效果稱為 視覺化子樹

視覺效果在樹狀結構中的位置有助於判斷其相對於組合中其他視覺效果的螢幕位置和 Z 順序。 根視覺效果會相對於轉譯組合之目標視窗的左上角位置。 所有子視覺效果都位於其父視覺效果的左上角 (或 TransformParent 屬性所指定的視覺效果) ,而且一律會以 z 順序出現在父系前面。

下圖顯示視覺效果的組成,以及用來產生組合的視覺化樹狀結構。 Visual 1 是根視覺效果,也是子視覺效果 2 和 3 的父系,也就是同層級視覺效果。 Visual 3 有自己的兩個子視覺效果,Visuals 4 和 5。 視覺效果 3 到 5 組成視覺化子樹。

視覺效果和對應的視覺化樹狀結構組合

父視覺效果會維護其子視覺效果的已排序清單。 當同層級視覺效果定位成彼此重迭時,DirectComposition 會根據父視覺效果子系列表中出現的順序,設定同層級的 z 順序。 清單稍後出現的同層級會放在清單中稍早出現的所有同層級前面。 下圖顯示重迭子視覺效果的迭置順序。

重迭子視覺效果的迭置順序

視覺物件的屬性

視覺物件會公開一組屬性,可讓您設定視覺效果的點陣圖內容,以及控制 DirectComposition 如何放置及操作視覺內容。 下列各節詳細說明每個屬性。

內容屬性

視覺效果的 Content 屬性會指定與視覺效果相關聯的點陣圖內容。 這是 DirectComposition 在組合中包含視覺效果時所使用的點陣圖。

您可以呼叫 IDCompositionVisual::SetContent 方法來設定視覺效果的 Content 屬性。

如需 DirectComposition 所支援之點陣圖內容類型的詳細資訊,請參閱 Bitmap 物件

Clip 屬性

視覺效果的 Clip 屬性會指定矩形區域,稱為 裁剪區域 (或 裁剪矩形) 。 轉譯視覺效果時,只會顯示落在裁剪區域中的視覺效果部分,而任何在裁剪區域外延伸的內容都會裁剪 (,而不是顯示) 。 DirectComposition 支援圓角或平方角的裁剪區域。

您可以藉由呼叫 IDCompositionVisual::SetClip 方法來設定視覺效果的 Clip 屬性。

如需詳細資訊,請參閱 裁剪

BorderMode 屬性

BorderMode 屬性會指定如何撰寫與這個視覺效果相關聯之點陣圖和剪輯的邊緣,或與這個視覺效果根目錄的子樹狀結構中的視覺效果組成。

框線模式會影響點陣圖的邊緣在轉換時如何組成,讓邊緣與整數座標不對齊。 它也會影響內容如何裁剪在具有圓角的剪輯角落,以及轉換的剪輯邊緣,讓邊緣與整數座標不對齊。

如需詳細資訊,請參閱 IDCompositionVisual::SetBorderMode

BitmapInterpolationMode 屬性

BitmapInterpolationMode 屬性會告訴 DirectComposition 如何在轉換點陣圖時撰寫點陣圖,使點陣圖與螢幕上的圖元之間沒有一對一的對應。

您可以呼叫 IDCompositionVisual::SetBitmapInterpolationMode 方法來設定視覺效果的 BitmapInterpolationMode 屬性。

CompositeMode 屬性

CompositeMode 屬性會告訴 DirectComposition 如何將視覺效果的點陣圖內容與轉譯目標混合。 如需支援複合模式的描述,請參閱 DCOMPOSITION_COMPOSITE_MODE

您可以藉由呼叫 IDCompositionVisual::SetCompositeMode 方法來設定視覺效果的 CompositeMode 屬性。

OffsetX 和 OffsetY 屬性

OffsetX 和 OffsetY 屬性會告訴 DirectComposition 水準和垂直放置視覺效果的位置。 他們會定義計算視覺效果之所有轉換和效果的二維固定位置。

針對根視覺效果,OffsetX 和 OffsetY 屬性會定義相對於裝載視覺效果之視窗左上角之點的 x 座標和 Y 座標。 對於子視覺效果,座標會相對於父系的左上角,或者,如果指定 TransformParent 屬性 ,則為指定之視覺效果的左上角。 呈現視覺效果時,其位置會讓視覺效果的左上角與指定的座標一致。

您可以藉由呼叫 IDCompositionVisual::SetOffsetX 和 SetOffsetY 方法來設定視覺效果的 OffsetX 和 OffsetY 屬性。

Effect 屬性

Effect 屬性可讓您指定效果或效果群組,以修改視覺效果及其子樹的撰寫方式。 例如,您可以指定控制視覺效果不透明度的效果、以各種方式將視覺效果與另一個點陣圖混合,並將檢視方塊轉換套用至視覺效果。

您可以藉由呼叫 IDCompositionVisual::SetEffect 方法來設定視覺效果的 Effect 屬性。

如需詳細資訊,請參閱效果

Transform 屬性

Transform 屬性會指定二維 (2D) 轉換或 2D 轉換群組,讓 DirectComposition 在視覺效果上執行。 轉換 (或轉換) 是一項作業,可修改視覺效果相對於其父系的座標系統,或是 相對於 TransformParent 屬性所指定的視覺效果。 您可以使用轉換來改變視覺效果的位置、大小或本質,方法是將它移至另一個位置 (轉譯) 、讓它變大或縮小 (縮放) 、將它 (旋轉) 、扭曲其圖形 (扭曲) 等等。

您可以呼叫 IDCompositionVisual::SetTransform 方法來設定視覺效果的 Transform 屬性。

如需詳細資訊,請參閱轉換

TransformParent 屬性

視覺效果的座標系統是由 OffsetX、OffsetY 和 Transform 屬性修改。 一般而言,這些屬性會定義視覺效果相對於其直接父系的座標系統。 若要使用父系以外的一些視覺效果做為子視覺效果座標系統的基礎,請使用 TransformParent 屬性將不同的視覺效果指定為「parent」,以供轉換之用。

您可以呼叫 IDCompositionVisual::SetTransformParent 方法來設定視覺效果的 TransformParent 屬性。

裝置物件

若要使用 DirectComposition,您必須建立及操作各種元件物件模型, (COM) 物件。 您需要建立的第一個物件是 DirectComposition 裝置物件 ,因為它可作為建立組合中使用的所有其他物件的處理站。

您可以呼叫會傳回IDCompositionDevice介面指標的DCompositionCreateDevice函式來建立裝置物件。 這個介面會公開一組您用來建立視覺物件、裁剪物件、動畫物件、轉換物件、效果物件等的方法。

裝置物件除了做為建立其他物件的處理站之外,還有另一個用途。 它會公開稱為 Commit 的方法,將視覺化樹狀結構傳遞至 DirectComposition 進行處理。 如需詳細資訊,請參閱 交易式組合

請記住,雖然您可以在應用程式中建立多個裝置物件的實例,但您在特定組合中使用的所有物件都必須由相同的裝置物件建立,但有一個例外:您可以將來自相同視覺化樹狀結構中不同裝置物件的視覺物件合併。 當您這樣做時,DirectComposition 會將視覺化樹狀結構視為一般情況,但樹狀結構中特定視覺物件的變更只會在建立視覺物件的裝置物件上呼叫 Commit 方法時生效。

能夠在同一個視覺化樹狀結構中使用來自不同裝置的視覺效果,可讓多個執行緒建立及操作單一視覺化樹狀結構,同時維護兩個可用來非同步認可變更的獨立裝置。 如需詳細資訊,請參閱 跨裝置視覺化樹狀結構

組合目標視窗

視覺化樹狀結構必須系結至視窗,才能在螢幕上顯示任何樹狀結構的視覺效果。 稱為 組合目標視窗的視窗可以是最上層視窗或子視窗。 此外,組合目標視窗可以是分層視窗;也就是說,它可以有 WS_EX_LAYERED 視窗樣式。

DirectComposition 可讓應用程式將最多兩個視覺化樹狀結構系結至每個視窗。 視覺化樹狀結構包含一個包含在視窗本身的頂端,但位於所有視窗子視窗後方,另一個是由視窗頂端和子視窗頂端所組成。 換句話說,每個視窗都有四個概念層,而且所有圖層都會裁剪到目標視窗的可見區域。 下圖顯示視窗的四個概念層。

視窗的概念層

交易式組合

DirectComposition 會使用交易模型,在其中建立視覺效果的批次變更集,然後將集合「認可」為 DirectComposition 一次全部處理。 您可以修改相同的 DirectComposition 視覺效果物件,並認可任何次數的變更。 當桌面視窗管理員 (DWM) 挑選批次時,它會挑選所有擱置的批次,並以認可的順序將它們套用至下一個框架。

單一認可內的所有變更都保證會套用至單一框架。 因為 DWM 會針對每個畫面收集一次批次,所以每個畫面只能修改一次特定的物件。 後續修改不同物件的認可也可能會套用至目前的框架,但 DirectComposition 不保證變更會發生在相同的框架中。

IDCompositionSurface::BeginDrawIDCompositionSurface::EndDraw方法可讓您同步處理轉譯更新與視覺更新。 例如,您可以呼叫 IDCompositionSurface::BeginDraw、更新視覺效果的 OffsetX 和 Clip 屬性、呼叫 IDCompositionDevice::Commit、使用 Microsoft DirectX 繪製內容,然後呼叫 IDCompositionSurface::EndDraw。 在此情況下,Microsoft DirectComposition 可確保點陣圖內容和視覺屬性同時更新。

批次處理

您可以將多個變更認可至相同的視覺效果,或在同一個畫面內對不同視覺效果進行多個變更。 在相同畫面格內對相同視覺效果進行多個變更時,請記住下列幾點:

  • 如果您對視覺效果的相同屬性進行多個變更,則只會套用最後一個變更。 例如,如果您將不透明度設定為 0,則設為 0.5,最後設定為 1.0,則只會將不透明度 1.0 套用至視覺效果。

  • 如果您變更相同視覺效果的多個屬性,DirectComposition 會先將變更套用至視覺效果,然後再套用至任何子視覺效果。 不論您指定屬性的順序為何,屬性都會以下列順序套用:

    1. Offset
    2. 轉換
    3. 裁剪
    4. 效果

    下圖顯示將所有四個屬性套用至視覺效果的結果。

    將這四個屬性全部套用至視覺效果的結果

    請記住,所有變更都會一次套用至相同畫面格內容中的視覺效果。 這表示,從使用者的觀點來看,視覺效果的變更會立即發生。

  • 針對 Transform 屬性,您可以使用 IDCompositionDevice::CreateTransformGroup 來建立一組轉換,以一次套用至視覺效果。 DirectComposition 會依您指定的順序套用轉換。

  • 對於 Effect 屬性,您可以使用 IDCompositionEffectGroup 來套用一組效果。 DirectComposition 會依您指定的順序套用效果。 此外,3D 檢視方塊轉換會在套用目前視覺效果中的所有 3D 轉換之後,產生視覺化樹狀結構的扁平化。 這有助於確保產生的視覺效果盡可能接近 3D。

同步處理

您的應用程式可以同時從多個執行緒呼叫 DirectComposition。 循序呼叫可保證執行順序,但不適用於並行呼叫。 例如,如果執行緒 A 修改視覺效果,而執行緒 B 同時認可批次,則不會定義該視覺變更是否包含在認可的批次中,或是否啟動新的批次。 另一方面,如果您的應用程式使用其他同步處理機制來確保在另一個方法之前呼叫一個方法,DirectComposition 會接受呼叫順序,並處理它們,就像從單一線程發出這兩個呼叫一樣。

跨裝置視覺化樹狀結構

DirectComposition 物件不是執行緒系結;您可以使用多個執行緒來修改同一組物件。 不過,在共用相同的裝置物件時,請注意下列問題。

  • 這兩個執行緒都必須能夠呼叫 IDCompositionDevice::Commit。 如果只有其中一個執行緒呼叫 IDCompositionDeviceDevice::Commit,另一個執行緒就無法將其任何變更認可至 DirectComposition。
  • 如果某個執行緒呼叫 IDCompositionDevice::Commit ,而另一個執行緒仍在進行屬於相同交易的變更,則交易行為可能會遺失。

如果您需要將多個同時交易認可至 DirectComposition,則必須使用多個裝置物件,可能是來自多個執行緒。 在此案例中,相同的視覺化樹狀結構會由兩個裝置物件共用,而每個裝置物件都會認可自己的交易。

下圖顯示兩個裝置物件共用的視覺化樹狀結構。 視覺效果 1、2、4 和 5 是由一個裝置或另一個裝置所擁有,但視覺效果 3 是由這兩個裝置共用,因此可用來將兩個子樹連接到單一較大的視覺化樹狀結構。 共用視覺化樹狀結構可讓兩個裝置以非同步方式從兩個不同的執行緒操作。

由兩部裝置共用的視覺化樹狀結構

為了說明在兩個裝置之間共用視覺化樹狀結構的實用性,請考慮啟用低延遲觸控輸入的架構。 此架構可以使用兩個執行緒,一個處理大部分 UI 工作,另一個執行緒專用於處理觸控輸入事件。 觸控執行緒會根據使用者輸入手勢更新特定視覺效果的轉換。 藉由更新轉換,觸控執行緒可以讓該視覺效果下的整個子樹遵循使用者的手指、在使用者執行多點觸控手勢時相應增加或縮小等。 UI 執行緒會保留大部分組合樹狀結構的擁有權,而觸控執行緒只擁有幾個標記為非同步觸控回應的視覺效果。 下圖顯示這類組合樹狀結構的簡化版本:

UI 執行緒與觸控執行緒之間共用的視覺化樹狀結構

一般而言,UI 執行緒只會修改它獨佔擁有的視覺效果,而觸控執行緒只會修改共用視覺效果。 唯一的例外狀況會在建立或終結啟用觸控的子樹時發生。

IDCompositionSurface::BeginDraw

IDCompositionSurface::EndDraw

IDCompositonDevice::Commit

DirectComposition 概念