Delen via


De prestaties van Direct2D-apps verbeteren

Hoewel Direct2D- hardware versneld is en bedoeld is voor hoge prestaties, moet u de functies juist gebruiken om de doorvoer te maximaliseren. De technieken die hier worden weergegeven, zijn afgeleid van het bestuderen van veelvoorkomende scenario's en zijn mogelijk niet van toepassing op alle app-scenario's. Daarom kan een zorgvuldig begrip van het gedrag en de prestatiedoelen van apps helpen de gewenste resultaten te bereiken.

Resourcegebruik

Een resource is een toewijzing van een bepaald soort, in het video- of systeemgeheugen. Bitmaps en penselen zijn voorbeelden van hulpbronnen.

In Direct2D kunnen resources zowel in software als hardware worden gemaakt. Het maken en verwijderen van resources op hardware zijn dure bewerkingen omdat er veel overhead nodig is voor de communicatie met de videokaart. Laten we eens kijken hoe Direct2D inhoud weergeeft aan een doel.

In Direct2D bevinden alle renderingopdrachten zich tussen een aanroep van BeginDraw- en een aanroep van EndDraw-. Deze aanroepen worden gedaan naar een rendertarget. U moet de methode BeginDraw aanroepen voordat u renderingbewerkingen aanroept. Nadat u BeginDraw hebt aangeroepen, wordt in een context meestal een batch renderingopdrachten opgebouwd, maar wordt de verwerking van deze opdrachten vertraagd totdat een van deze instructies waar wordt.

  • EndDraw is opgetreden. Wanneer EndDraw- wordt aangeroepen, worden alle batchbewerkingen voor tekenbewerkingen voltooid en wordt de status van de bewerking geretourneerd.
  • U maakt een expliciete aanroep naar Flush: de methode Flush zorgt ervoor dat de batch wordt verwerkt en dat alle opdrachten die in behandeling zijn, worden uitgegeven.
  • De buffer met de renderingopdrachten is vol. Als deze buffer vol raakt voordat aan de vorige twee voorwaarden wordt voldaan, worden de renderingopdrachten gewist.

Totdat de primitieven worden leeggemaakt, bewaart Direct2D interne verwijzingen naar bijbehorende resources, zoals bitmaps en borstels.

Resources opnieuw gebruiken

Zoals al vermeld, is het maken en verwijderen van resources duur op hardware. Gebruik dus waar mogelijk resources opnieuw. Neem het voorbeeld van bitmapcreatie in gameontwikkeling. Bitmaps waaruit een scène in een game bestaat, worden meestal allemaal tegelijkertijd gemaakt met alle verschillende variaties die nodig zijn voor latere frame-to-frame rendering. Op het moment dat de scène wordt weergegeven en opnieuw wordt weergegeven, worden deze bitmaps opnieuw gebruikt in plaats van opnieuw te maken.

Notitie

U kunt resources niet opnieuw gebruiken voor de bewerking voor het wijzigen van het formaat van het venster. Wanneer het formaat van een venster wordt gewijzigd, moeten sommige schaalafhankelijke resources, zoals compatibele renderdoelen, en mogelijk sommige laagresources opnieuw worden gemaakt omdat de vensterinhoud opnieuw moet worden getekend. Dit kan belangrijk zijn voor het behoud van de algehele kwaliteit van de gerenderde scène.

 

Het gebruik van spoelen beperken

Omdat de methode Flush ervoor zorgt dat de batched rendering-opdrachten worden verwerkt, wordt u aangeraden deze niet te gebruiken. Voor de meest voorkomende scenario's laat u resourcebeheer over naar Direct2D.

Bitmaps

Zoals eerder vermeld, zijn het maken en verwijderen van resources zeer dure bewerkingen in hardware. Een bitmap is een soort resource die vaak wordt gebruikt. Het maken van bitmaps op de videokaart is duur. Door ze opnieuw te gebruiken, kan de toepassing sneller werken.

Grote bitmaps maken

Videokaarten hebben doorgaans een minimale geheugentoewijzingsgrootte. Als een toewijzing wordt aangevraagd die kleiner is dan deze, wordt een resource van deze minimale grootte toegewezen en wordt het overschotgeheugen verspild en niet beschikbaar voor andere zaken. Als u veel kleine bitmaps nodig hebt, kunt u beter één grote bitmap toewijzen en alle kleine bitmapinhoud in deze grote bitmap opslaan. Vervolgens kunnen subgebieden van de grotere bitmap worden gelezen waar de kleinere bitmaps nodig zijn. Vaak moet u opvulling (transparante zwarte pixels) tussen de kleine bitmaps opnemen om interactie tussen de kleinere afbeeldingen tijdens bewerkingen te voorkomen. Dit wordt ook wel een atlasgenoemd en het vermindert de belasting door overhead bij het maken van bitmaps en het verspillen van geheugen door kleine bitmaptoewijzingen. U wordt aangeraden de meeste bitmaps tot ten minste 64 kB te behouden en het aantal bitmaps te beperken dat kleiner is dan 4 kB.

Een atlas met bitmaps maken

Er zijn enkele veelvoorkomende scenario's waarvoor een bitmapatlas zeer goed kan dienen. Kleine bitmaps kunnen worden opgeslagen in een grote bitmap. Deze kleine bitmaps kunnen uit de grotere bitmap worden gehaald wanneer u ze nodig hebt door de doelrechthoek op te geven. Een toepassing moet bijvoorbeeld meerdere pictogrammen tekenen. Alle bitmaps die aan de pictogrammen zijn gekoppeld, kunnen vooraf in een grote bitmap worden geladen. En tijdens de rendering kunnen ze worden opgehaald uit de grote bitmap.

Notitie

Een Direct2D-bitmap die is gemaakt in het videogeheugen, is beperkt tot de maximale bitmapgrootte die wordt ondersteund door de adapter waarop deze wordt opgeslagen. Het maken van een bitmap groter dan dat kan resulteren in een fout.

 

Notitie

Vanaf Windows 8 bevat Direct2D een Atlas-effect waarmee dit proces eenvoudiger kan worden.

 

Gedeelde bitmaps maken

Door gedeelde bitmaps te maken, kunnen geavanceerde bellers Direct2D-bitmapobjecten maken die rechtstreeks worden ondersteund door een bestaand object, dat al compatibel is met het renderdoel. Dit voorkomt dat er meerdere oppervlakken worden gemaakt en helpt de prestatie-overhead te verminderen.

Notitie

Gedeelde bitmaps zijn meestal beperkt tot softwaredoelen of doelen die interoperabel zijn met DXGI. Gebruik de CreateBitmapFromDxgiSurface, CreateBitmapFromWicBitmapen CreateSharedBitmap methoden om gedeelde bitmaps te maken.

 

Bitmaps kopiëren

Het maken van een DXGI-oppervlak is een dure bewerking, dus hergebruik bestaande oppervlakken wanneer u dat kunt. Zelfs in software, als een bitmap meestal in de gewenste vorm is, met uitzondering van een klein deel, is het beter om dat gedeelte bij te werken dan om de hele bitmap weg te gooien en alles opnieuw te maken. Hoewel u CreateCompatibleRenderTarget kunt gebruiken om dezelfde resultaten te bereiken, is rendering doorgaans een veel duurdere bewerking dan kopiëren. Dit komt doordat, om de lokaliteit van de cache te verbeteren, de hardware niet daadwerkelijk een bitmap opslaat in dezelfde geheugenvolgorde die door de bitmap wordt geadresseerd. In plaats daarvan kan de bitmap worden omgegooid. De zwenk is verborgen voor de CPU door het stuurprogramma (dat traag is en alleen wordt gebruikt op onderste delen), of door de geheugenbeheerder op de GPU. Vanwege beperkingen bij het schrijven van gegevens naar een renderdoel tijdens het renderen, worden renderdoelen doorgaans niet geswizzled of op een manier geswizzled die minder optimaal is dan kan worden bereikt als u weet dat u nooit naar het oppervlak hoeft te renderen. Daarom worden de methoden CopyFrom* geboden voor het kopiëren van rechthoeken van een bron naar de Direct2D-bitmap.

CopyFrom kan worden gebruikt in elk van de drie vormen:

Een betegelde bitmap gebruiken in plaats van stippellijnen

Het weergeven van een stippellijn is een zeer dure bewerking vanwege de hoge kwaliteit en nauwkeurigheid van het onderliggende algoritme. In de meeste gevallen waarbij geen rechtlijnige geometrieën worden gebruikt, kan hetzelfde effect sneller worden gegenereerd met behulp van betegelde bitmaps.

Algemene richtlijnen voor het weergeven van complexe statische inhoud

Cache de inhoud als u hetzelfde inhoudsframe herhaaldelijk weergeeft, met name wanneer de scène complex is.

Er zijn drie caching technieken die u kunt gebruiken:

  • Volledige scène opslaan in cache met behulp van een kleuren bitmap.
  • Per primitieve caching met behulp van een A8-bitmap en de FillOpacityMask-methode .
  • Per primitive caching met behulp van geometrie-realisaties.

Laten we eens kijken naar elk van deze in meer detail.

Volledige scène opslaan in cache met behulp van een kleuren bitmap

Wanneer u statische inhoud weergeeft, maakt u in scenario's zoals animatie een andere bitmap met volledige kleur in plaats van rechtstreeks naar de scherm bitmap te schrijven. Sla het huidige doel op, stel het doel in op de tussenliggende bitmap en geef de statische inhoud weer. Ga vervolgens terug naar de oorspronkelijke scherm bitmap en teken de tussenliggende bitmap erop.

Hier volgt een voorbeeld:

// 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());

In dit voorbeeld worden tussenliggende bitmaps gebruikt voor caching en wordt de bitmap, waarnaar de apparaatcontext verwijst, gewisseld op het moment dat het renderen plaatsvindt. Dit voorkomt dat u voor hetzelfde doel een compatibel renderdoel hoeft te maken.

Per primitieve caching met behulp van een A8-bitmap en de methode FillOpacityMask

Wanneer de volledige scène niet statisch is, maar bestaat uit elementen zoals geometrie of tekst die statisch zijn, kunt u een primitieve cachingtechniek gebruiken. Deze techniek behoudt de antialiasingkenmerken van het element dat wordt gecached en werkt met wisselende kwasttypen. Het maakt gebruik van een A8-bitmap waarbij A8 een soort pixelindeling is die een alfakanaal met 8 bits vertegenwoordigt. A8-bitmaps zijn handig voor het tekenen van geometrie/tekst als masker. Wanneer u de dekking van statische inhoud moet manipuleren in plaats van de inhoud zelf te bewerken, kunt u de dekking van het masker vertalen, draaien, scheeftrekken of schalen.

Hier volgt een voorbeeld:

// 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);

Per-primitieve caching met geometrie-realisaties

Een andere per-primitieve cachingtechniek, genaamd geometrie-realisaties, biedt meer flexibiliteit bij het omgaan met geometrie. Wanneer u herhaaldelijk gealiasde of anti-gealiasde geometrieën wilt tekenen, is het sneller om ze te converteren naar geometrie-representaties en herhaaldelijk deze representaties te tekenen dan de geometrieën zelf herhaaldelijk te tekenen. Geometrierealisaties verbruiken over het algemeen minder geheugen dan dekkingsmaskers (vooral voor grote geometrieën) en ze zijn minder gevoelig voor veranderingen in schaal. Zie Geometry Realizations Overviewvoor meer informatie.

Hier volgt een voorbeeld:

    // 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();

Geometrieweergave

Gebruik specifieke tekenprimitieven in plaats van tekengeometrie

Gebruik specifiekere teken-primitieve--aanroepen, zoals DrawRectangle- boven algemene DrawGeometry--aanroepen. Dit komt doordat met DrawRectanglede geometrie al bekend is, zodat rendering sneller is.

Statische geometrie weergeven

In scenario's waarin de geometrie statisch is, gebruikt u de hierboven beschreven technieken voor primitieve caching. Ondoorzichtigheidsmaskers en geometrierealisaties kunnen de renderingsnelheid van scènes die statische geometrie bevatten aanzienlijk verbeteren.

Een multithreaded apparaatcontext gebruiken

Toepassingen die verwachten dat aanzienlijke hoeveelheden complexe geometrische inhoud worden weergegeven, moeten overwegen om de vlag D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTI_THREADED_OPTIMIZATIONS op te geven bij het maken van een Direct2D- apparaatcontext. Wanneer deze vlag is opgegeven, distribueert Direct2D rendering over alle logische kernen die aanwezig zijn op het systeem, waardoor de totale renderingtijd aanzienlijk kan afnemen.

Notities:

  • Vanaf Windows 8.1 is deze vlag alleen van invloed op de weergave van padgeometrie. Het heeft geen invloed op scènes die alleen andere primitieve typen bevatten (zoals tekst, bitmaps of geometrie-realisaties).
  • Deze vlag heeft ook geen invloed op het weergeven in software (bijvoorbeeld bij rendering met een WARP Direct3D-apparaat). Wanneer u software-multithreading wilt beheren, moeten oproepprogramma's de parameter D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS gebruiken bij het aanmaken van het WARP Direct3D-apparaat.
  • Als u deze vlag opgeeft, kan het piekgebruik van werkgeheugen tijdens de rendering toenemen en kan de threadconcurrentie toenemen in applicaties die al gebruikmaken van multithreadverwerking.

Tekentekst met Direct2D

Direct2D-functionaliteit voor het weergeven van tekst wordt in twee delen aangeboden. Het eerste deel, weergegeven als de ID2D1RenderTarget::DrawText en de ID2D1RenderTarget::DrawTextLayout methode, stelt een aanroeper in staat om een tekenreeks en opmaakparameters of een DWrite-tekstindelingobject door te geven voor meerdere opmaakstijlen. Dit moet geschikt zijn voor de meeste bellers. De tweede manier om tekst weer te geven, weergegeven als de methode ID2D1RenderTarget::D rawGlyphRun, biedt rasterisering voor klanten die al de positie van de glyphs kennen die ze willen weergeven. De volgende twee algemene regels kunnen helpen bij het verbeteren van de tekstprestaties bij het tekenen in Direct2D.

DrawTextLayout versus DrawText

Zowel DrawText als DrawTextLayout een toepassing in staat stellen om eenvoudig tekst weer te geven die is opgemaakt door de DirectWrite-API. DrawTextLayout een bestaand DWriteTextLayout object naar het RenderTarget-tekent en DrawText een DirectWrite-indeling voor de aanroeper samenstelt op basis van de parameters die worden doorgegeven. Als dezelfde tekst meerdere keren moet worden weergegeven, gebruikt u DrawTextLayout- in plaats van DrawText-, omdat DrawText een indeling maakt telkens wanneer deze wordt aangeroepen.

De juiste tekstweergavemodus kiezen

Stel de antialiasmodus voor tekst in op D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE expliciet. De kwaliteit van het weergeven van grijswaardentekst is vergelijkbaar met ClearType, maar is veel sneller.

Cache

Gebruik volledige scèneweergave of per primitieve bitmapcaching, net zoals bij het tekenen van andere primitieve vormen.

Een willekeurige vorm uitsnijden

In de afbeelding ziet u het resultaat van het toepassen van een clip op een afbeelding.

een afbeelding met een voorbeeld van een afbeelding vóór en na een clip.

U kunt dit resultaat verkrijgen door gebruik te maken van lagen met een geometriemasker of de FillGeometry-methode met een dekkingsborstel.

Hier volgt een voorbeeld waarin een laag wordt gebruikt:

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

Hier volgt een voorbeeld waarin de methode FillGeometry wordt gebruikt:

// 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()); 

In dit codevoorbeeld, wanneer u de PushLayer-methode aanroept, geeft u geen door de app gemaakte laag door. Direct2D maakt een laag voor u. Direct2D kan de toewijzing en vernietiging van deze resource beheren zonder tussenkomst van de app. Hierdoor kan Direct2D lagen intern opnieuw gebruiken en optimalisaties voor resourcebeheer toepassen.

In Windows 8 zijn veel optimalisaties aangebracht in het gebruik van lagen. We raden u aan laag-API's te gebruiken in plaats van FillGeometry- waar mogelijk.

PushLayer in Windows 8

De ID2D1DeviceContext interface is afgeleid van de interface ID2D1RenderTarget en is essentieel voor het weergeven van Direct2D-inhoud in Windows 8. Zie apparaten en apparaatcontextenvoor meer informatie over deze interface. Met de apparaatcontextinterface kunt u het aanroepen van de methode CreateLayer overslaan en vervolgens NULL doorgeven aan de methode ID2D1DeviceContext::P ushLayer. Direct2D beheert automatisch de laagresource en kan resources delen tussen lagen en effectgrafieken.

Uit de as uitgelijnde clips

Als het gebied dat moet worden bijgesneden, is uitgelijnd met de as van het tekenoppervlak, in plaats van willekeurig. In dit geval is het geschikt om een cliprechthoek te gebruiken in plaats van een laag. De prestatiewinst is groter voor geometrie met aliasing dan voor geometrie met anti-aliasing. Voor meer informatie over as-uitgelijnde clips, zie het onderwerp PushAxisAlignedClip.

DXGI-interoperabiliteit: vermijd frequente switches

Direct2D kan naadloos samenwerken met Direct3D-oppervlakken. Dit is erg handig voor het maken van toepassingen die een combinatie van 2D- en 3D-inhoud weergeven. Maar elke schakeloptie tussen het tekenen van Direct2D- en Direct3D-inhoud is van invloed op de prestaties.

Wanneer Direct2D naar een DXGI-oppervlak renderen uitvoert, wordt de status van de Direct3D-apparaten opgeslagen tijdens het renderen en hersteld nadat de rendering is voltooid. Telkens wanneer een batch Direct2D-rendering is voltooid, worden de kosten van het opslaan en herstellen en de kosten van het flushen van alle 2D-bewerkingen betaald, en toch wordt het Direct3D-apparaat niet geflusht. Beperk daarom het aantal renderingswitches tussen Direct2D en Direct3D om de prestaties te verbeteren.

Uw pixelindeling kennen

Wanneer u een renderdoel maakt, kunt u de D2D1_PIXEL_FORMAT-structuur gebruiken om de pixelindeling en alfamodus op te geven die door het renderdoel worden gebruikt. Een alfakanaal maakt deel uit van de pixelindeling waarmee de dekkingswaarde of dekkingsgegevens worden opgegeven. Als een renderdoel het alfakanaal niet gebruikt, moet het worden gemaakt met behulp van de D2D1_ALPHA_MODE_IGNORE alfamodus. Dit bespaart de tijd die wordt besteed aan het weergeven van een alfakanaal dat niet nodig is.

Zie Ondersteunde pixelindelingen en alfamodivoor meer informatie over pixelindelingen en alfamodi.

Complexiteit van scènes

Wanneer u de hot spots voor prestaties analyseert in een scène die wordt weergegeven, kan het weten of de scène afhankelijk is van de vullingssnelheid of van vertexbeperkingen nuttige informatie bieden.

  • Fill Rate: Fill rate verwijst naar het aantal pixels dat een grafische kaart kan weergeven en schrijven naar videogeheugen per seconde.
  • Hoekpunt gebonden: een scène is afhankelijk van een hoekpunt wanneer deze veel complexe geometrie bevat.

Inzicht in scènecomplexiteit

U kunt de complexiteit van uw scène analyseren door de grootte van het renderdoel te wijzigen. Als prestatieverbeteringen zichtbaar zijn bij een proportionele vermindering van de grootte van de renderdoelstelling, dan wordt de toepassing beperkt door de vulgraad. Anders is de complexiteit van de scène het knelpunt van de prestaties.

Wanneer een scène afhankelijk is van de doorvoersnelheid, kan het verkleinen van het renderdoel de prestaties verbeteren. Dit komt doordat het aantal pixels dat moet worden weergegeven, proportioneel wordt verminderd met de grootte van het renderdoel.

Wanneer een scène afhankelijk is van een hoekpunt, vermindert u de complexiteit van de geometrie. Maar vergeet niet dat dit ten koste gaat van de beeldkwaliteit. Daarom moet er een zorgvuldige afweging worden gemaakt tussen de gewenste kwaliteit en de prestaties die nodig zijn.

Betere prestaties voor Direct2D-afdruk-apps

Direct2D- biedt compatibiliteit met afdrukken. U kunt dezelfde Direct2D-tekenopdrachten (in de vorm van Direct2D-opdrachtlijsten) verzenden naar het direct2D-afdrukbesturingselement voor afdrukken, als u niet weet naar welke apparaten u tekent of hoe de tekening wordt omgezet in afdrukken.

U kunt hun gebruik van de Direct2D afdrukbesturing en uw Direct2D-tekenopdrachten verder verfijnen om afdrukresultaten met betere prestaties te bereiken.

De Direct2D print control voert foutopsporingsberichten uit wanneer er een Direct2D-codepatroon wordt weergegeven dat leidt tot lagere afdrukkwaliteit of -prestaties (zoals codepatronen die verderop in dit onderwerp worden vermeld) om u eraan te herinneren waar u prestatieproblemen kunt voorkomen. Als u deze foutopsporingsberichten wilt zien, moet u Direct2D-foutopsporingslaag inschakelen in uw code. Zie Foutopsporingsberichten voor instructies voor het inschakelen van uitvoer van foutopsporingsberichten.

De juiste eigenschapswaarden instellen wanneer u het D2D-afdrukbesturingselement maakt

Er zijn drie eigenschappen die u kunt instellen wanneer u het Direct2D afdrukbesturingselement maakt. Twee van deze eigenschappen zijn van invloed op de manier waarop het direct2D-afdrukbesturingselement bepaalde Direct2D-opdrachten verwerkt en op zijn beurt invloed heeft op de algehele prestaties.

  • Modus Lettertypesubset: de Direct2D afdrukcontrole subset lettertypebronnen die op elke pagina worden gebruikt voordat de pagina wordt afgedrukt. Deze modus vermindert de grootte van paginabronnen die nodig zijn om af te drukken. Afhankelijk van het gebruik van lettertypen op de pagina, kunt u verschillende subsetmodi voor lettertypen kiezen voor de beste prestaties.
    • D2D1_PRINT_FONT_SUBSET_MODE_DEFAULT biedt in de meeste gevallen de beste afdrukprestaties. Wanneer deze modus is ingesteld, gebruikt de Direct2D afdrukcontrole een heuristische strategie om te bepalen wanneer lettertypen moeten worden gesubset.
    • Voor korte afdruktaken met 1 of 2 pagina's raden we D2D1_PRINT_FONT_SUBSET_MODE_EACHPAGE aan, waarbij de Direct2D--afdrukbesturingselementen subsets van lettertypebronnen op elke pagina insluiten en vervolgens dat lettertypesubset wordt weggegooid nadat de pagina is afgedrukt. Met deze optie zorgt u ervoor dat elke pagina direct nadat deze is gegenereerd, kan worden afgedrukt, maar neemt de grootte van de paginabronnen die nodig zijn voor afdrukken enigszins toe (met meestal grote lettertypesubsets).
    • Voor afdruktaken met veel pagina's met tekst en kleine tekengrootten (zoals 100 pagina's met één lettertype), raden we D2D1_PRINT_FONT_SUBSET_MODE_NONEaan, waarbij het Direct2D- afdrukbesturingselement helemaal geen subsetletterbronnen bevat; In plaats daarvan worden de oorspronkelijke lettertyperesources samen met de pagina die het lettertype gebruikt, verzonden en worden de lettertyperesources opnieuw gebruikt voor latere pagina's zonder ze opnieuw te verzenden.
  • Rasterisatie-DPI: wanneer de Direct2D- afdrukbeheer Direct2D-opdrachten tijdens Direct2D-XPS conversie moet rasteriseren, wordt deze DPI gebruikt voor rasterisatie. Met andere woorden, als de pagina geen rasterinhoud heeft, verandert het instellen van DPI de prestaties en kwaliteit niet. Afhankelijk van het rastergebruik op de pagina kunt u verschillende rasterisatie-DPO's kiezen voor de beste balans tussen betrouwbaarheid en prestaties.
    • 150 is de standaardwaarde als u geen waarde opgeeft wanneer u het Direct2D afdrukbeheer maakt. Dit is in de meeste gevallen de beste balans tussen afdrukkwaliteit en afdrukprestaties.
    • Hogere DPI-waarden resulteren meestal in een betere afdrukkwaliteit (zoals in meer details behouden), maar lagere prestaties als gevolg van de grotere bitmaps die worden gegenereerd. We raden geen DPI-waarde aan die groter is dan 300, omdat er geen extra informatie visueel zichtbaar is door menselijke ogen.
    • Lagere DPI kan betere prestaties betekenen, maar kan ook een lagere kwaliteit produceren.

Vermijd het gebruik van bepaalde Direct2D-tekenpatronen

Er zijn verschillen tussen wat Direct2D- visueel kan voorstellen en wat het afdruksubsysteem kan onderhouden en vervoeren langs de hele afdrukpijplijn. De Direct2D-afdrukbesturing overbrugt die hiaten door Direct2D-primitieven te benaderen of te rasteren die het afdruksubsysteem niet systeemeigen ondersteunt. Een dergelijke benadering resulteert meestal in een lagere afdrukkwaliteit, lagere afdrukprestaties of beide. Hoewel een klant dezelfde tekenpatronen voor zowel scherm- als afdrukweergave kan gebruiken, is dit in alle gevallen niet ideaal. Het is raadzaam om dergelijke Direct2D-primitieven en -patronen niet zoveel mogelijk te gebruiken voor het afdrukpad of om uw eigen rasterisatie uit te voeren waarbij u volledige controle hebt over de kwaliteit en de grootte van de rasterafbeeldingen.

Hier volgt een lijst met gevallen waarin de afdrukprestaties en -kwaliteit niet ideaal zijn en het is mogelijk dat u het codepad wilt wijzigen voor optimale afdrukprestaties.

  • Vermijd het gebruik van een primitieve mengmodus anders dan D2D1_PRIMITIVE_BLEND_SOURCEOVER.
  • Vermijd het gebruik van samenstellingsmodi bij het tekenen van een andere afbeelding dan D2D1_COMPOSITE_MODE_SOURCE_OVER en D2D1_COMPOSITE_MODE_DESTINATION_OVER.
  • Vermijd het tekenen van een GDI-metabestand.
  • Vermijd het gebruik van een laagresource die de bronachtergrond kopieert (door PushLayer- aan te roepen en D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND door te geven aan de D2D1_LAYER_PARAMETERS1-struct).
  • Vermijd het aanmaken van een Bitmap Brush of Afbeeldingsbrush met D2D1_EXTEND_MODE_CLAMP. U wordt aangeraden D2D1_EXTEND_MODE_MIRROR te gebruiken als het u helemaal niet uitmaakt dat er pixels buiten de afbeeldingsgrens vallen, bijvoorbeeld wanneer de afbeelding die aan de kwast is gekoppeld groter is dan het gevulde doelgebied.
  • Vermijd het tekenen van bitmaps met perspectieftransformaties.

Tekst op een directe en eenvoudige manier tekenen

Direct2D heeft verschillende optimalisaties bij het weergeven van teksten om weer te geven voor betere prestaties en/of betere visuele kwaliteit. Maar niet alle optimalisaties verbeteren de afdrukprestaties en -kwaliteit, omdat het afdrukken op papier meestal een veel hogere DPI heeft en afdrukken niet nodig is voor scenario's zoals animatie. Daarom raden we u aan de oorspronkelijke tekst of glyphs rechtstreeks te tekenen en de volgende optimalisaties te vermijden bij het maken van de opdrachtlijst voor afdrukken.

  • Vermijd het tekenen van tekst met de FillOpacityMask methode.
  • Vermijd tekst tekenen in de alias-modus.

De oorspronkelijke bitmaps tekenen indien mogelijk

Als de doel bitmap een JPEG, PNG, TIFF of JPEG-XR is, kunt u een WIC-bitmap maken op basis van een schijfbestand of vanuit een in-memory stream, en vervolgens een Direct2D bitmap van die WIC-bitmap maken met behulp van ID2D1DeviceContext::CreateBitmapFromWicBitmapen ten slotte rechtstreeks die Direct2D-bitmap doorgeven aan het direct2D-afdrukbesturingselement zonder verdere manipulatie. Hierdoor kan het direct2D-afdrukbeheer de bitmapstroom hergebruiken, wat meestal leidt tot betere afdrukprestaties (door redundante bitmapcodering en -decodering over te slaan) en betere afdrukkwaliteit (wanneer metagegevens, zoals kleurprofielen, in de bitmap behouden blijven).

Het tekenen van de oorspronkelijke bitmap biedt het volgende voordeel voor toepassingen.

  • Over het algemeen behoudt Direct2D-afdruk de oorspronkelijke informatie (zonder verlies of ruis) tot laat in de pijplijn, vooral wanneer apps de details van de afdrukpijplijn niet kennen (of niet willen weten), zoals welke printer wordt gebruikt, wat de doel-DPI van de printer is, enzovoort.
  • In veel gevallen betekent het vertragen van bitmaprastering betere prestaties (bijvoorbeeld bij het afdrukken van een 96dpi-foto naar een printer van 600dpi).
  • In bepaalde gevallen is het doorgeven van de oorspronkelijke afbeeldingen de enige manier om hoge kwaliteit te respecteren (zoals ingesloten kleurprofielen).

U kunt echter niet kiezen voor dergelijke optimalisatie, omdat:

  • Door een query uit te voeren op printergegevens en vroege rasterisatie, kunt u inhoud zelf rasteren met volledige controle over het uiteindelijke uiterlijk op papier.
  • In bepaalde gevallen kan vroege rasterisatie de end-to-end prestaties van een app verbeteren (zoals foto's van portemonneesformaat afdrukken).
  • In bepaalde gevallen vereist het doorgeven van de oorspronkelijke bitmaps een aanzienlijke wijziging van de bestaande codearchitectuur (zoals het vertraagd laden van afbeeldingen en het bijwerken van resources in bepaalde toepassingen).

Conclusie

Hoewel Direct2D hardware versneld is en bedoeld is voor hoge prestaties, moet u de functies correct gebruiken om de doorvoer te maximaliseren. De technieken die we hier hebben bekeken, zijn afgeleid van het bestuderen van algemene scenario's en zijn mogelijk niet van toepassing op alle toepassingsscenario's.