Sdílet prostřednictvím


Zlepšení výkonu aplikací Direct2D

I když Direct2D je akcelerovaný hardwarem a je určený pro vysoký výkon, musíte tyto funkce použít správně, abyste maximalizovali propustnost. Zde uvedené techniky jsou odvozené ze studia běžných scénářů a nemusí se vztahovat na všechny scénáře aplikací. Pečlivé porozumění chování aplikací a cílům výkonu proto může pomoct dosáhnout požadovaných výsledků.

Využití prostředků

Prostředek je přidělení určitého typu, ať už ve videopaměti nebo systémové paměti. Rastrové obrázky a štětce jsou příklady prostředků.

V Direct2D je možné prostředky vytvářet jak v softwaru, tak v hardwaru. Vytváření a odstraňování prostředků na hardwaru jsou nákladné operace, protože pro komunikaci s grafickou kartou vyžadují značné režijní náklady. Pojďme se podívat, jak Direct2D vykresluje obsah do cíle.

V Direct2D jsou všechny příkazy vykreslování uzavřeny mezi voláním BeginDraw a voláním EndDraw. Tato volání se provádějí ve vykreslovacím cíli. Před voláním operací vykreslování je nutné volat metodu BeginDraw . Po volání BeginDraw , kontext obvykle sestaví dávku příkazů vykreslování, ale odkládá zpracování těchto příkazů, dokud jedna z těchto podmínek není splněna:

  • Došlo k události EndDraw. Když je volána EndDraw, způsobí dokončení všech hromadných operací kreslení a vrátí stav operace.
  • Explicitní volání Flush: Metoda Flush způsobí zpracování dávky a vystavení všech nevyřízených příkazů.
  • Zásobník uchovávající příkazy vykreslování je plný. Pokud se tato vyrovnávací paměť zaplní před splněním předchozích dvou podmínek, vykreslovací příkazy se vyprázdní.

Dokud nejsou primitiva vyprázdněna, Direct2D uchovává interní odkazy na odpovídající prostředky, jako jsou bitmapy a štětce.

Opakované použití prostředků

Jak už bylo zmíněno, vytváření a mazání zdrojů je na hardware nákladné. Proto prostředky používejte opakovaně, pokud je to možné. Podívejte se na příklad vytváření rastrových obrázků při vývoji her. Rastrové obrázky, které tvoří scénu ve hře, se obvykle vytvářejí současně se všemi různými variantami, které jsou potřeba pro pozdější vykreslování snímků na snímek. V době skutečného vykreslování a opětovného vykreslování scény se tyto rastrové obrázky znovu používají místo opětovného vytvoření.

Poznámka

Nemůžete opakovaně používat prostředky pro operaci změny velikosti okna. Při změně velikosti okna je nutné znovu vytvořit některé prostředky závislé na škálování, například kompatibilní cíle vykreslování a případně i některé prostředky vrstvy, protože obsah okna se musí překreslit. To může být důležité pro zachování celkové kvality vykreslené scény.

 

Omezit používání splachování

Vzhledem k tomu, že metoda Flush způsobí zpracování příkazů dávkového vykreslování, doporučujeme, abyste ji nepoužívali. U nejběžnějších scénářů ponechte správu prostředků na Direct2D.

Rastrové obrázky

Jak už bylo zmíněno dříve, vytváření a odstraňování prostředků jsou velmi nákladné operace v hardwaru. Rastrový obrázek je druh prostředku, který se často používá. Vytváření rastrových obrázků na grafické kartě je nákladné. Opětovné použití může pomoct zrychlit aplikaci.

Vytváření velkých rastrových obrázků

Grafické karty mají obvykle minimální velikost přidělení paměti. Pokud se požaduje přidělení, které je menší než toto, přidělí se zdroj s touto minimální velikostí a nadbytečná paměť je pro ostatní věci nevyužitá a není k dispozici. Pokud potřebujete mnoho malých rastrových obrázků, lepší technikou je přidělit jeden velký rastrový obrázek a uložit veškerý malý obsah rastrového obrázku v tomto velkém rastrovém obrázku. Potom lze přečíst podoblasti většího rastrového obrázku, kde jsou potřeba menší rastrové obrázky. Mezi malými rastrovými obrázky byste často měli zahrnout odsazení (černé průhledné pixely), abyste se vyhnuli vzájemné interakci mezi menšími obrázky při operacích. To se také označuje jako atlasa má výhodu snížení režie vytváření rastrových obrázků a plýtvání paměti malými přiděleními bitmap. Doporučujeme ponechat většinu rastrových obrázků alespoň na 64 kB a omezit počet rastrových obrázků, které jsou menší než 4 kB.

Vytvoření atlasu rastrových obrázků

Existují některé běžné scénáře, pro které rastrový atlas může sloužit velmi dobře. Malé rastrové obrázky mohou být uloženy uvnitř velkého rastrového obrázku. Tyto malé rastrové obrázky lze vytáhnout z větší bitmapy, pokud je potřebujete, zadáním cílového obdélníku. Aplikace například musí nakreslit více ikon. Všechny rastrové obrázky přidružené k ikonám lze načíst do velkého rastrového obrázku předem. A v době vykreslování je možné je načíst z velkého rastrového obrázku.

Poznámka

Rastrový obrázek Direct2D vytvořený v paměti videa je omezen na maximální velikost rastru podporovanou adaptérem, na kterém je uložen. Vytvoření rastrového obrázku většího, než by mohlo vést k chybě.

 

Poznámka

Počínaje Windows 8 obsahuje Direct2D efekt Atlas, který usnadňuje tento proces.

 

Vytvoření sdílených rastrových obrázků

Vytváření sdílených rastrových obrázků umožňuje pokročilým volajícím vytvářet rastrové objekty Direct2D, které jsou podporovány přímo existujícím objektem, které jsou již kompatibilní s cílem vykreslení. Tím se zabrání vytváření více ploch a pomáhá snižovat režijní náklady na výkon.

Poznámka

Sdílené rastrové obrázky jsou obvykle omezené na softwarové cíle nebo cíle interoperabilní s DXGI. Pomocí metod CreateBitmapFromDxgiSurface, CreateBitmapFromWicBitmapa CreateSharedBitmap vytvořte sdílené rastrové obrázky.

 

Kopírování rastrových obrázků

Vytvoření povrchu DXGI je nákladná operace, takže opakovaně používejte existující povrchy, pokud je to možné. I v softwaru, pokud je rastrový obrázek většinou ve formě, kterou chcete s výjimkou malé části, je lepší tuto část aktualizovat, než hodit celý rastrový obrázek pryč a znovu vytvořit vše. I když můžete použít CreateCompatibleRenderTarget k dosažení stejných výsledků, vykreslování je obecně mnohem dražší než kopírování. Důvodem je, že kvůli zlepšení umístění mezipaměti hardware ve skutečnosti neukládá rastrový obrázek ve stejném pořadí paměti, v jakém je rastrový obrázek adresován. Místo toho může být rastrový obrázek přeuspořádaný. Přehazování je pro CPU skryto buď ovladačem (což je pomalé a používá se pouze na hardwaru nižší třídy), nebo správcem paměti na GPU. Vzhledem k omezením způsobu zápisu dat do cíle vykreslování při renderování nejsou cíle vykreslování obvykle swizzleované, nebo jsou swizzleované způsobem, který je méně optimální, než jakého by šlo dosáhnout, pokud víte, že na tento povrch nikdy nepotřebujete renderovat. Proto jsou k dispozici metody CopyFrom* pro kopírování obdélníků ze zdroje do rastrového obrázku Direct2D.

CopyFrom lze použít ve všech třech formách:

Použijte dlaždicový bitmapový obrázek místo přerušovaného vzoru.

Vykreslení přerušované čáry je velmi náročná operace z důvodu vysoké kvality a přesnosti základního algoritmu. U většiny případů, které nezahrnují rektilineární geometrie, může být stejný efekt generován rychleji pomocí dlaždicových rastrových obrázků.

Obecné pokyny pro vykreslování složitého statického obsahu

Ukládejte obsah do mezipaměti, pokud vykreslujete stejný obsah ve více rámcích, zvláště když je scéna složitá.

Existují tři techniky ukládání do mezipaměti, které můžete použít:

  • Ukládání celé scény do mezipaměti pomocí barevného rastrového obrázku
  • Mezipaměť pro jednotlivé prvky pomocí bitmapy A8 a metody FillOpacityMask.
  • Ukládání do mezipaměti na úrovni primitiv pomocí realizace geometrických tvarů.

Pojďme se na každou z těchto možností podívat podrobněji.

Ukládání celé scény do mezipaměti pomocí barevného rastrového obrázku

Při vykreslení statického obsahu ve scénářích, jako je animace, vytvořte místo psaní přímo na rastrový obrázek obrazovky jiný rastrový obrázek s plnou barvou. Uložte aktuální cíl, nastavte cíl na zprostředkující rastrový obrázek a vykreslujte statický obsah. Potom přepněte zpět na původní rastrový obrázek obrazovky a nakreslete na něj zprostředkující rastrový obrázek.

Tady je příklad:

// Create a bitmap.
m_d2dContext->CreateBitmap(size, nullptr, 0,
    D2D1::BitmapProperties(
        D2D1_BITMAP_OPTIONS_TARGET,
        D2D1::PixelFormat(
            DXGI_FORMAT_B8G8R8A8_UNORM,
            D2D1_ALPHA_MODE_PREMULTIPLIED),
        dpiX, dpiY),
    &sceneBitmap);

// Preserve the pre-existing target.
ComPtr<ID2D1Image> oldTarget;
m_d2dContext->GetTarget(&oldTarget);

// Render static content to the sceneBitmap.
m_d2dContext->SetTarget(sceneBitmap.Get());
m_d2dContext->BeginDraw();
…
m_d2dContext->EndDraw();

// Render sceneBitmap to oldTarget.
m_d2dContext->SetTarget(oldTarget.Get());
m_d2dContext->DrawBitmap(sceneBitmap.Get());

Tento příklad používá mezipaměťové rastrové obrázky a během vykreslení přepíná rastrový obrázek, na který zařízení kontextu odkazuje. Tím se zabrání nutnosti vytvořit kompatibilní cíl vykreslení pro stejný účel.

Předběžné ukládání do mezipaměti pro primitivy pomocí A8 bitmapy a metody FillOpacityMask

Pokud celá scéna není statická, ale skládá se z prvků, jako je geometrie nebo text, které jsou statické, můžete použít každou primitivní techniku ukládání do mezipaměti. Tato technika zachovává antialiasingové charakteristiky cachované primitivy a pracuje s měnícími se typy štětců. Používá rastrový obrázek A8, kde A8 je druh formátu pixelů, který představuje alfa kanál s 8 bity. Rastrové obrázky A8 jsou užitečné pro kreslení geometrie nebo textu jako masky. Když musíte manipulovat s neprůhledností statického obsahu , místo manipulace se samotným obsahem, můžete přeložit, otočit, zkosit nebo škálovat neprůhlednost masky.

Tady je příklad:

// Create an opacity bitmap.
m_d2dContext->CreateBitmap(size, nullptr, 0,
    D2D1::BitmapProperties(
        D2D1_BITMAP_OPTIONS_TARGET,
        D2D1::PixelFormat(
            DXGI_FORMAT_A8_UNORM,
            D2D1_ALPHA_MODE_PREMULTIPLIED),
        dpiX, dpiY),
    &opacityBitmap);

// Preserve the pre-existing target.
ComPtr<ID2D1Image> oldTarget;
m_d2dContext->GetTarget(&oldTarget);

// Render to the opacityBitmap.
m_d2dContext->SetTarget(opacityBitmap.Get());
m_d2dContext->BeginDraw();
…
m_d2dContext->EndDraw();

// Call the FillOpacityMask method
// Note: for this call to work correctly the anti alias mode must be D2D1_ANTIALIAS_MODE_ALIASED. 
m_d2dContext->SetTarget(oldTarget.Get());
m_d2dContext->FillOpacityMask(
    opacityBitmap.Get(),
    m_contentBrush().Get(),
    D2D1_OPACITY_MASK_CONTENT_GRAPHICS);

Ukládání do mezipaměti pro každé primitivum pomocí geometrických realizací

Další technika ukládání do mezipaměti zaměřená na jednotlivé primitivy, označovaná jako realizace geometrie, poskytuje větší flexibilitu při práci s geometrií. Pokud chcete opakovaně kreslit aliasované nebo antialiasované geometrie, je rychlejší je převést na realizace a tyto realizace opakovaně kreslit, než kreslit samotné geometrie. Realizace geometrie také obecně spotřebovávají méně paměti než masky neprůhlednosti (zejména u velkých geometrií) a jsou méně citlivé na změny ve velkém měřítku. Další informace naleznete v tématu Přehled realizace geometrie.

Tady je příklad:

    // Compute a flattening tolerance based on the scales at which the realization will be used.
    float flatteningTolerance = D2D1::ComputeFlatteningTolerance(...);

    ComPtr<ID2D1GeometryRealization> geometryRealization;

    // Create realization of the filled interior of the geometry.
    m_d2dDeviceContext1->CreateFilledGeometryRealization(
        geometry.Get(),
        flatteningTolerance,
        &geometryRealization
        );

    // In your app's rendering code, draw the geometry realization with a brush.
    m_d2dDeviceContext1->BeginDraw();
    m_d2dDeviceContext1->DrawGeometryRealization(
        geometryRealization.Get(),
        m_brush.Get()
        );
    m_d2dDeviceContext1->EndDraw();

Vykreslování geometrie

Použijte konkrétní primitivy kresby místo geometrie kresby

Používejte konkrétnější voláníprimitivních, jako je DrawRectangle, místo obecných volání DrawGeometry. Je to proto, že DrawRectangle, geometrie je již známá, takže vykreslování je rychlejší.

Vykreslování statické geometrie

Ve scénářích, kde je geometrie statická, použijte popsané výše techniky ukládání do mezipaměti pro jednotlivé primitivy. Masky neprůhlednosti a realizace geometrie mohou výrazně zlepšit rychlost vykreslování scén, které obsahují statickou geometrii.

Použijte kontext vícevláknového zařízení

Aplikace, které očekávají vykreslování významného množství složitého geometrického obsahu, by při vytváření kontextu zařízení Direct2D měly zvážit specifikaci příznaku D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTI_THREADED_OPTIMIZATIONS. Pokud je tento příznak zadán, Direct2D distribuuje vykreslování napříč všemi logickými jádry, která jsou v systému, což může výrazně snížit celkovou dobu vykreslování.

Poznámky:

  • Od Windows 8.1 má tento příznak vliv pouze na vykreslování geometrie cesty. Nemá žádný vliv na scény obsahující pouze jiné primitivní typy (například text, rastrové obrázky nebo realizace geometrie).
  • Tento příznak také nemá žádný vliv na vykreslování ve softwaru (tj. při renderování pomocí zařízení Direct3D WARP). K řízení softwarového multithreadingu by volající měli při vytváření zařízení WARP Direct3D použít parametr D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS.
  • Určení tohoto příznaku může během vykreslování zvýšit pracovní sadu v nejvyšším zatížení a může také zvýšit konflikty vláken v aplikacích, které již využívají vícevláknové zpracování.

Kreslení textu pomocí Direct2D

Funkce vykreslování textu Direct2D se nabízí ve dvou částech. První část, používaná jako ID2D1RenderTarget::DrawText a ID2D1RenderTarget::DrawTextLayout metoda, umožňuje volajícímu předat buď řetězec a formátovací parametry, nebo objekt rozložení textu DWrite pro různé formáty. To by mělo být vhodné pro většinu volajících. Druhý způsob vykreslení textu, nabízený jako metoda ID2D1RenderTarget::DrawGlyphRun, poskytuje rastrování pro zákazníky, kteří už znají polohu glyfů, které chtějí vykreslit. Následující dvě obecná pravidla můžou pomoct zlepšit výkon textu při kreslení v Direct2D.

DrawTextLayout Vs. DrawText

DrawText a DrawTextLayout umožňují aplikaci snadno vykreslit text, který je formátován pomocí API DirectWrite. DrawTextLayout vykreslí stávající objekt DWriteTextLayout na RenderTargeta DrawText vytvoří rozložení DirectWrite pro volajícího na základě předaných parametrů. Pokud se stejný text musí vykreslit vícekrát, použijte DrawTextLayout místo DrawText, protože DrawText vytvoří rozložení pokaždé, když je volána.

Volba správného režimu vykreslování textu

Nastavte režim vyhlazování textu na D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE explicitně pomocí . Kvalita vykreslování textu ve stupních šedé je srovnatelná s technologií ClearType, ale je podstatně rychlejší.

Ukládání do mezipaměti

Používejte bitmapovou mezipaměť pro celou scénu nebo pro jednotlivé primitivy, podobně jako při kreslení jiných primitivů.

Oříznutí libovolného obrazce

Obrázek zde ukazuje výsledek použití klipu na obrázek.

obrázek, který ukazuje příklad obrázku před klipem a po klipu.

Tento výsledek můžete získat pomocí vrstev s maskou geometrie nebo metodou FillGeometry s štětcem pro průhlednost.

Tady je příklad, který používá vrstvu:

// Call PushLayer() and pass in the clipping geometry.
m_d2dContext->PushLayer(
    D2D1::LayerParameters(
        boundsRect,
        geometricMask));

Tady je příklad, který používá metodu FillGeometry:

// Create an opacity bitmap and render content.
m_d2dContext->CreateBitmap(size, nullptr, 0,
    D2D1::BitmapProperties(
        D2D1_BITMAP_OPTIONS_TARGET,
        D2D1::PixelFormat(
            DXGI_FORMAT_A8_UNORM,
            D2D1_ALPHA_MODE_PREMULTIPLIED),
        dpiX, dpiY),
    &opacityBitmap);

m_d2dContext->SetTarget(opacityBitmap.Get());
m_d2dContext->BeginDraw();
…
m_d2dContext->EndDraw();

// Create an opacity brush from the opacity bitmap.
m_d2dContext->CreateBitmapBrush(opacityBitmap.Get(),
    D2D1::BitmapBrushProperties(),
    D2D1::BrushProperties(),
    &bitmapBrush);

// Call the FillGeometry method and pass in the clip geometry and the opacity brush
m_d2dContext->FillGeometry( 
    clipGeometry.Get(),
    brush.Get(),
    opacityBrush.Get()); 

Při volání metody PushLayer v tomto příkladu kódu nepředáváte vrstvu vytvořenou aplikací. Direct2D vytvoří vrstvu za vás. Direct2D dokáže spravovat přidělení a zničení tohoto prostředku bez jakéhokoli zásahu z aplikace. Díky tomu může Direct2D interně používat vrstvy a používat optimalizace správy prostředků.

Ve Windows 8 jsme provedli řadu optimalizací použití vrstev a doporučujeme místo FillGeometry kdykoli je to možné, vyzkoušet rozhraní API vrstev.

PushLayer ve Windows 8

Rozhraní ID2D1DeviceContext je odvozeno z rozhraní ID2D1RenderTarget a je klíčem k zobrazení obsahu Direct2D v systému Windows 8, další informace o tomto rozhraní naleznete v tématu Zařízení a kontexty zařízení. S kontextovým rozhraním zařízení můžete přeskočit volání metody CreateLayer a pak předat hodnotu NULL metodě ID2D1DeviceContext::P ushLayer. Direct2D automaticky spravuje prostředek vrstvy a může sdílet prostředky mezi vrstvami a grafy efektů.

Klipy zarovnané s osami

Pokud je oblast, která se má oříznout, zarovnána podle osy kreslicí plochy, a ne náhodně. Tento případ je vhodný pro použití výsekového obdélníku místo vrstvy. Zvýšení výkonu je větší u aliasované geometrie než u antialiasované geometrie. Další informace o klipech zarovnaných osou viz téma PushAxisAlignedClip.

Interoperabilita DXGI: vyhněte se častým přepínačům

Direct2D může bez problémů spolupracovat s povrchy Direct3D. To je velmi užitečné při vytváření aplikací, které vykreslují kombinaci 2D a 3D obsahu. Každé přepnutí mezi vykreslováním obsahu Direct2D a Direct3D však ovlivňuje výkon.

Při vykreslování na plochu DXGI Direct2D uloží stav zařízení Direct3D. Stav je obnoven po dokončení vykreslování. Při každém dokončení dávky vykreslování Direct2D se platí náklady na uložení a obnovení a náklady na vyprázdnění všech 2D operací, avšak zařízení Direct3D není vyprázdněno. Pokud tedy chcete zvýšit výkon, omezte počet přepínačů vykreslování mezi Direct2D a Direct3D.

Poznejte formát pixelu

Při vytváření cíle vykreslení můžete použít strukturu D2D1_PIXEL_FORMAT určit formát pixelů a režim alfa používaný cílem vykreslení. Alfa kanál je součástí formátu pixelu, který určuje hodnotu pokrytí nebo informace o neprůhlednosti. Pokud cíl vykreslení nepoužívá alfa kanál, měl by být vytvořen pomocí D2D1_ALPHA_MODE_IGNORE alfa režimu. Tím ušetříte čas strávený vykreslením alfa kanálu, který není potřeba.

Další informace o formátech pixelů a režimech alfa naleznete v tématu Podporované formáty pixelů a režimy alfa.

Složitost scény

Při analýze kritických míst výkonu ve scéně, která se bude vykreslovat, znalost, zda je scéna omezena rychlostí výplně nebo počtem vrcholů, může poskytnout užitečné informace.

  • Rychlost výplně: Rychlost výplně odkazuje na počet pixelů, které může grafická karta vykreslit a zapisovat do paměti videa za sekundu.
  • Geometricky omezená: Scéna je geometricky omezená, pokud obsahuje velké množství složité geometrie.

Vysvětlení složitosti scény

Složitost scény můžete analyzovat změnou velikosti cíle vykreslení. Pokud jsou přínosy výkonu patrné při proporcionálním snížení velikosti renderovacího cíle, pak je aplikace omezená rychlostí vykreslování. Jinak je složitost scény kritickým bodem výkonu.

Pokud je scéna vázána rychlostí výplně, zmenšení velikosti cíle vykreslení může zlepšit výkon. Důvodem je to, že počet pixelů, které se mají vykreslit, se proporcionálně zmenší s velikostí cíle vykreslení.

Pokud je scéna vázaná na vrcholy, snižte složitost geometrie. Mějte ale na paměti, že se to provádí na úkor kvality obrazu. Proto by mělo být provedeno pečlivé rozhodnutí o kompromisu mezi požadovanou kvalitou a požadovaným výkonem.

Zlepšení výkonu pro aplikace pro tisk Direct2D

Direct2D nabízí kompatibilitu s tiskem. Stejné příkazy kresby Direct2D (ve formě příkazových seznamů Direct2D) můžete odeslat do ovládacího prvku tisku Direct2D pro tisk, pokud nevíte, na jaká zařízení kreslíte, nebo jak se kresba překreslí pro tisk.

Pomocí ovládacího prvku Direct2D pro tisk a příkazů kreslení Direct2D můžete dále doladit jejich použití, abyste dosáhli lepších výsledků tisku s vyšším výkonem.

Direct2D vypisuje ladicí zprávy, když zjistí vzor kódu Direct2D, který vede k nižší kvalitě tisku nebo výkonu (například vzory kódu uvedené dále v tomto tématu), aby vás upozornil na místa, kde lze předejít problémům s výkonem. Pokud chcete tyto ladicí zprávy zobrazit, musíte ve svém kódu povolit ladicí vrstvu Direct2D. Pokyny k povolení výstupu ladicích zpráv najdete v části Ladicí zprávy.

Nastavení správných hodnot vlastností při vytváření ovládacího prvku tisk D2D

Při vytváření ovládacího prvku Direct2D tisku můžete nastavit tři vlastnosti. Dvě z těchto vlastností mají vliv na to, jak ovládací prvek tisku Direct2D zpracovává určité příkazy Direct2D a ovlivňuje celkový výkon.

  • Režim podmnožiny písma: Ovládací prvek tisku Direct2D zpracovává podmnožiny prostředků písma použitých na každé stránce před jejím odesláním k tisku. Tento režim zmenšuje velikost prostředků stránky potřebných k tisku. V závislosti na použití písma na stránce můžete pro nejlepší výkon zvolit různé režimy podmnožin písem.
    • D2D1_PRINT_FONT_SUBSET_MODE_DEFAULT ve většině případů poskytuje nejlepší výkon tisku. Při nastavení na tento režim Direct2D ovládací prvek tisku používá heuristickou strategii k rozhodnutí, kdy použít podmnožinu písem.
    • U krátkých tiskových úloh s 1 nebo 2 stránkami doporučujeme D2D1_PRINT_FONT_SUBSET_MODE_EACHPAGE, kde Direct2D tiskový ovládací prvek vytváří podmnožiny písem a vkládá prostředky písma na každou stránku, přičemž tuto podmnožinu písma po vytištění stránky zahodí. Tato možnost zajistí, že se každá stránka dá vytisknout hned po vygenerování, ale mírně se zvětší velikost prostředků stránky potřebných k tisku (u obvykle velkých podmnožin písem).
    • Pro tiskové úlohy s mnoha stránkami textu a malými velikostmi písem (například 100 stránek textu, které používají jedno písmo), doporučujeme D2D1_PRINT_FONT_SUBSET_MODE_NONE, kde Direct2D ovládací prvek tisku vůbec nenastaví prostředky písma; místo toho odešle původní prostředky písma spolu se stránkou, která písmo poprvé používá, a znovu použije prostředky písma pro pozdější stránky bez jejich opětovného odeslání.
  • RASTROVÁNÍ DPI: Když tisková kontrola Direct2D potřebuje rasterizovat příkazy Direct2D během převodu Direct2D-XPS, pro rasterizaci používá toto DPI. Jinými slovy, pokud stránka nemá rastrový obsah, nastavení dpi nezmění výkon a kvalitu. V závislosti na použití rasterizace na stránce můžete zvolit různé rozhraní DPI rasterizace, abyste měli nejlepší rovnováhu mezi věrností a výkonem.
    • 150 je výchozí hodnota, pokud při vytváření ovládacího prvku Direct2D tisk nezadáte hodnotu, což je nejlepší vyvážení kvality tisku a výkonu tisku ve většině případů.
    • Vyšší hodnoty DPI obvykle vedou k lepší kvalitě tisku (stejně jako u zachování dalších podrobností), ale nižší výkon kvůli větším rastrům, které generuje. Nedoporučujeme žádnou hodnotu DPI větší než 300, protože to nezavedá další informace vizuálně prohlédnutelné lidskými očima.
    • Nižší DPI může znamenat lepší výkon, ale může také vést k nižší kvalitě.

Vyhněte se používání určitých vzorů výkresu Direct2D

Existují rozdíly mezi tím, co Direct2D může vizuálně představovat a co může subsystém tisku udržovat a přenášet po celém tiskovém kanálu. Ovládací prvek tisku Direct2D překonává tyto mezery buď přibližováním, nebo rasterizací primitivami Direct2D, které subsystém tisku nativně nepodporuje. Taková aproximace obvykle vede k nižší přesnosti tisku, nižšímu výkonu tisku nebo obojímu. Proto i když zákazník může použít stejné vzory kreslení pro vykreslování obrazovky i tisku, není ideální ve všech případech. Je nejlepší nepoužívat takové primitivy a vzory Direct2D v tiskové cestě, nebo provádět vlastní rasterizaci, kde máte úplnou kontrolu nad kvalitou a velikostí rastrových obrázků.

Tady je seznam případů, kdy výkon a kvalita tisku nebudou ideální a můžete zvážit různé cesty kódu pro optimální výkon tisku.

  • Nepoužívejte žádný jiný režim blendu než D2D1_PRIMITIVE_BLEND_SOURCEOVER.
  • Nepoužívejte režimy složení při kreslení jiného obrázku než D2D1_COMPOSITE_MODE_SOURCE_OVER a D2D1_COMPOSITE_MODE_DESTINATION_OVER.
  • Vyhněte se kreslení metasouboru GDI.
  • Vyhněte se vložení prostředku vrstvy, který kopíruje zdrojové pozadí (volání PushLayer s předáním D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND do struktury D2D1_LAYER_PARAMETERS1).
  • Vyhněte se vytváření rastrového štětce nebo štětce obrázků pomocí D2D1_EXTEND_MODE_CLAMP. Doporučujeme použít D2D1_EXTEND_MODE_MIRROR, pokud vás vůbec nezajímají pixely mimo ohraničení obrázku (například obrázek připojený ke štětci je známý tím, že je větší než vyplněná cílová oblast).
  • Vyhněte se kreslení ‘Bitmaps’ (rastrových obrázků) pomocí transformací perspektivy.

Kreslení textu přímým a prostým způsobem

Direct2D má při vykreslování textu několik optimalizací pro lepší výkon nebo lepší kvalitu vizuálu. Ne všechny optimalizace ale zlepšují výkon a kvalitu tisku, protože tisk na papíře je obvykle mnohem vyšší DPI a tisk nemusí vyhovovat scénářům, jako je animace. Proto při vytváření seznamu příkazů pro tisk doporučujeme nakreslit původní text nebo glyfy přímo a vyhnout se některým z následujících optimalizací.

  • Vyhněte se kreslení textu metodou FillOpacityMask.
  • Vyhněte se kreslení textu v režimu aliasů.

Pokud je to možné, nakreslete původní rastrové obrázky.

Pokud je cílovým rastrovým obrázkem JPEG, PNG, TIFF nebo JPEG-XR, můžete vytvořit bitmapu WIC z disku nebo z datového proudu v paměti, pak vytvořit Direct2D rastrový obrázek z tohoto wic rastru pomocí ID2D1DeviceContext::CreateBitmapFromWicBitmapa nakonec přímo předat direct2D rastrový obrázek do ovládacího prvku tisku Direct2D bez další manipulace. Díky tomu může ovládací prvek tisku Direct2D znovu použít rastrový stream, což obvykle vede k lepšímu výkonu tisku (přeskočením redundantního kódování a dekódování rastrových obrázků) a lepší kvalitou tisku (pokud se metadata, jako jsou barevné profily, v rastrovém obrázku zachovají).

Kreslení původního rastrového obrázku poskytuje následující výhody pro aplikace.

  • Obecně platí, že Direct2D tisk zachová původní informace (bez ztráty nebo šumu) až do pozdější fáze procesu, zejména pokud aplikace neví (nebo nechtějí vědět) podrobnosti o tiskovém procesu (například na jakou tiskárnu tiskne, jaké DPI má cílová tiskárna atd.).
  • V mnoha případech zpoždění bitmapové rasterizace znamená lepší výkon (například při tisku fotografie 96dpi na tiskárnu s rozlišením 600 dpi).
  • V některých případech je předání původních obrázků jediným způsobem, jak respektovat vysokou věrnost (například vložené barevné profily).

Ale nemůžete se rozhodnout pro tuto optimalizaci, protože:

  • Dotazováním informací o tiskárně a časnou rasterizací můžete obsah rasterizovat sami s plnou kontrolou konečného vzhledu na papíře.
  • V některých případech může časná rasterizace ve skutečnosti zlepšit komplexní výkon aplikace (například tisk fotografií velikosti peněženky).
  • V některých případech předání původních rastrových obrázků vyžaduje významnou změnu stávající architektury kódu (například zpoždění načítání obrázku a cesty aktualizace prostředků nalezené v určitých aplikacích).

Závěr

I když je Direct2D hardwarově akcelerovaný a je určený pro vysoký výkon, musíte tyto funkce použít správně, abyste maximalizovali propustnost. Techniky, na které jsme se zde podívali, jsou odvozeny ze studia běžných scénářů a nemusí se vztahovat na všechny scénáře aplikace.