Meningkatkan performa aplikasi Direct2D
Meskipun Direct2D dipercepat perangkat keras dan dimaksudkan untuk performa tinggi, Anda harus menggunakan fitur dengan benar untuk memaksimalkan throughput. Teknik yang kami tunjukkan di sini berasal dari mempelajari skenario umum dan mungkin tidak berlaku untuk semua skenario aplikasi. Oleh karena itu, pemahaman yang cermat tentang perilaku aplikasi dan tujuan performa dapat membantu mencapai hasil yang Anda inginkan.
- Penggunaan sumber daya
- Membatasi penggunaan flush
- Bitmap
- Gunakan bitmap petak peta melalui garis putus-putus
- Panduan umum untuk merender konten statis yang kompleks
- Penembolokan per primitif menggunakan realisasi geometri
- Penyajian geometri
- Menggambar teks dengan Direct2D
- Mengklip bentuk arbitrer
- Interoperabilitas DXGI: hindari sakelar yang sering
- Mengetahui Format Piksel Anda
- Kompleksitas Adegan
- Meningkatkan performa untuk aplikasi pencetakan Direct2D
- Kesimpulan
Penggunaan sumber daya
Sumber daya adalah alokasi semacam itu, baik dalam memori video atau sistem. Bitmap dan kuas adalah contoh sumber daya.
Di Direct2D, sumber daya dapat dibuat baik dalam perangkat lunak maupun perangkat keras. Pembuatan dan penghapusan sumber daya pada perangkat keras adalah operasi yang mahal karena membutuhkan banyak overhead untuk berkomunikasi dengan kartu video. Mari kita lihat bagaimana Direct2D merender konten ke target.
Di Direct2D, semua perintah penyajian diapit antara panggilan ke BeginDraw dan panggilan ke EndDraw. Panggilan ini dilakukan ke target render. Anda harus memanggil metode BeginDraw sebelum Anda memanggil operasi penyajian . Setelah Anda memanggil BeginDraw , konteks biasanya membangun batch perintah penyajian, tetapi menunda pemrosesan perintah ini sampai salah satu pernyataan ini benar:
- EndDraw terjadi. Ketika EndDraw dipanggil, itu menyebabkan operasi gambar batch selesai dan mengembalikan status operasi.
- Anda melakukan panggilan eksplisit ke Flush: Metode Flush menyebabkan batch diproses dan semua perintah yang tertunda dikeluarkan.
- Buffer yang memegang perintah penyajian penuh. Jika buffer ini menjadi penuh sebelum dua kondisi sebelumnya terpenuhi, perintah penyajian akan dihapus.
Sampai primitif dibersihkan, Direct2D menyimpan referensi internal ke sumber daya yang sesuai seperti bitmap dan kuas.
Menggunakan kembali sumber daya
Seperti yang telah disebutkan, pembuatan dan penghapusan sumber daya mahal pada perangkat keras. Jadi gunakan kembali sumber daya jika memungkinkan. Ambil contoh pembuatan bitmap dalam pengembangan game. Biasanya, bitmap yang membentuk adegan dalam permainan semuanya dibuat pada saat yang sama dengan semua variasi berbeda yang diperlukan untuk penyajian frame-to-frame nanti. Pada saat rendering dan rendering adegan aktual, bitmap ini digunakan kembali alih-alih dibuat ulang.
Catatan
Anda tidak dapat menggunakan kembali sumber daya untuk operasi mengubah ukuran jendela. Ketika jendela diubah ukurannya, beberapa sumber daya yang bergantung pada skala seperti target render yang kompatibel dan mungkin beberapa sumber daya lapisan harus dibuat ulang karena konten jendela harus digambar ulang. Ini bisa menjadi penting untuk mempertahankan kualitas keseluruhan adegan yang dirender.
Membatasi penggunaan flush
Karena metode Flush menyebabkan perintah penyajian batch diproses, kami sarankan Anda tidak menggunakannya. Untuk skenario yang paling umum, tinggalkan manajemen sumber daya ke Direct2D.
Bitmap
Seperti disebutkan sebelumnya, pembuatan dan penghapusan sumber daya adalah operasi yang sangat mahal dalam perangkat keras. Bitmap adalah jenis sumber daya yang sering digunakan. Membuat bitmap pada kartu video mahal. Menggunakannya kembali dapat membantu membuat aplikasi lebih cepat.
Membuat bitmap besar
Kartu video biasanya memiliki ukuran alokasi memori minimum. Jika alokasi diminta yang lebih kecil dari ini, sumber daya dengan ukuran minimum ini dialokasikan dan memori surplus terbuang sia-sia dan tidak tersedia untuk hal-hal lain. Jika Anda membutuhkan banyak bitmap kecil, teknik yang lebih baik adalah mengalokasikan satu bitmap besar dan menyimpan semua konten bitmap kecil dalam bitmap besar ini. Kemudian subarea dari bitmap yang lebih besar dapat dibaca di mana bitmap yang lebih kecil diperlukan. Seringkali, Anda harus menyertakan padding (piksel hitam transparan) di antara bitmap kecil untuk menghindari interaksi antara gambar yang lebih kecil selama operasi. Ini juga dikenal sebagai atlas, dan memiliki manfaat mengurangi overhead pembuatan bitmap dan limbah memori alokasi bitmap kecil. Kami menyarankan agar Anda menyimpan sebagian besar bitmap hingga setidaknya 64 KB dan membatasi jumlah bitmap yang lebih kecil dari 4 KB.
Membuat atlas bitmap
Ada beberapa skenario umum di mana atlas bitmap dapat berfungsi dengan sangat baik. Bitmap kecil dapat disimpan di dalam bitmap besar. Bitmap kecil ini dapat ditarik keluar dari bitmap yang lebih besar ketika Anda membutuhkannya dengan menentukan persegi panjang tujuan. Misalnya, aplikasi harus menggambar beberapa ikon. Semua bitmap yang terkait dengan ikon dapat dimuat ke dalam bitmap besar di depan. Dan pada waktu penyajian, mereka dapat diambil dari bitmap besar.
Catatan
Bitmap Direct2D yang dibuat dalam memori video terbatas pada ukuran bitmap maksimum yang didukung oleh adaptor tempat bitmap disimpan. Membuat bitmap yang lebih besar dari itu dapat mengakibatkan kesalahan.
Catatan
Mulai dari Windows 8, Direct2D menyertakan efek Atlas yang dapat mempermudah proses ini.
Membuat bitmap bersama
Membuat bitmap bersama memungkinkan pemanggil tingkat lanjut untuk membuat objek bitmap Direct2D yang didukung langsung oleh objek yang ada, sudah kompatibel dengan target render. Ini menghindari pembuatan beberapa permukaan dan membantu mengurangi overhead performa.
Catatan
Bitmap bersama biasanya terbatas pada target perangkat lunak atau untuk menargetkan dapat dioperasikan dengan DXGI. Gunakan metode CreateBitmapFromDxgiSurface, CreateBitmapFromWicBitmap, dan CreateSharedBitmap untuk membuat bitmap bersama.
Menyalin bitmap
Membuat permukaan DXGI adalah operasi yang mahal sehingga menggunakan kembali permukaan yang ada ketika Anda bisa. Bahkan dalam perangkat lunak, jika bitmap sebagian besar dalam bentuk yang Anda inginkan kecuali untuk sebagian kecil, lebih baik memperbarui bagian itu daripada membuang seluruh bitmap dan membuat ulang semuanya. Meskipun Anda dapat menggunakan CreateCompatibleRenderTarget untuk mencapai hasil yang sama, penyajian umumnya merupakan operasi yang jauh lebih mahal daripada menyalin. Ini karena, untuk meningkatkan lokalitas cache, perangkat keras tidak benar-benar menyimpan bitmap dalam urutan memori yang sama dengan bitmap yang ditangani. Sebaliknya, bitmap mungkin bergetar. Gerimis disembunyikan dari CPU baik oleh driver (yang lambat dan hanya digunakan pada bagian ujung bawah), atau oleh manajer memori pada GPU. Karena kendala tentang bagaimana data ditulis ke dalam target render saat penyajian, target render biasanya tidak tergesek, atau tergeser dengan cara yang kurang optimal daripada yang dapat dicapai jika Anda tahu bahwa Anda tidak perlu merender ke permukaan. Oleh karena itu, metode CopyFrom* disediakan untuk menyalin persegi panjang dari sumber ke bitmap Direct2D.
CopyFrom dapat digunakan dalam salah satu dari tiga bentuknya:
Gunakan bitmap petak peta melalui garis putus-putus
Merender garis putus-putus adalah operasi yang sangat mahal karena kualitas tinggi dan akurasi algoritma yang mendasar. Untuk sebagian besar kasus yang tidak melibatkan geometri rectilinear, efek yang sama dapat dihasilkan lebih cepat dengan menggunakan bitmap ubin.
Panduan umum untuk merender konten statis yang kompleks
Konten cache jika Anda merender bingkai konten yang sama di atas bingkai, terutama ketika adegan kompleks.
Ada tiga teknik penembolokan yang dapat Anda gunakan:
- Penembolokan adegan penuh menggunakan bitmap warna.
- Per penembolokan primitif menggunakan bitmap A8 dan metode FillOpacityMask .
- Penembolokan per primitif menggunakan realisasi geometri.
Mari kita lihat masing-masing secara lebih rinci.
Penembolokan adegan penuh menggunakan bitmap warna
Saat Anda merender konten statis, dalam skenario seperti animasi, buat bitmap warna penuh lainnya alih-alih menulis langsung ke bitmap layar. Simpan target saat ini, atur target ke bitmap perantara, dan render konten statis. Kemudian, beralih kembali ke bitmap layar asli dan gambar bitmap perantara di atasnya.
Berikut contohnya:
// 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());
Contoh ini menggunakan bitmap perantara untuk penembolokan dan mengalihkan bitmap yang dituju konteks perangkat saat dirender. Ini menghindari kebutuhan untuk membuat target render yang kompatibel untuk tujuan yang sama.
Per penembolokan primitif menggunakan bitmap A8 dan metode FillOpacityMask
Ketika adegan penuh tidak statis, tetapi terdiri dari elemen seperti geometri atau teks yang statis, Anda dapat menggunakan teknik penembolokan per primitif. Teknik ini mempertahankan karakteristik antialisis dari primitif yang di-cache dan bekerja dengan jenis kuas yang berubah. Ini menggunakan bitmap A8 di mana A8 adalah jenis format piksel yang mewakili saluran alfa dengan 8 bit. Bitmap A8 berguna untuk menggambar geometri/teks sebagai masker. Ketika Anda harus memanipulasi keburaman konten statis , alih-alih memanipulasi konten itu sendiri, Anda dapat menerjemahkan, memutar, condong, atau menskalakan opasitas masker.
Berikut contohnya:
// 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);
Penembolokan per primitif menggunakan realisasi geometri
Teknik penembolokan per primitif lainnya, yang disebut realisasi geometri, memberikan fleksibilitas yang lebih besar saat berhadapan dengan geometri. Ketika Anda ingin berulang kali menggambar geometri alias atau anti-alias, lebih cepat untuk mengonversinya ke realisasi geometri dan berulang kali menarik realisasi daripada menggambar geometri itu sendiri berulang kali. Realisasi geometri juga umumnya mengonsumsi lebih sedikit memori daripada masker opasitas (terutama untuk geometri besar), dan mereka kurang sensitif terhadap perubahan skala. Untuk informasi selengkapnya, lihat Gambaran Umum Realisasi Geometri.
Berikut contohnya:
// 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();
Penyajian geometri
Gunakan gambar primitif tertentu atas geometri gambar
Gunakan panggilanprimitif gambar yang lebih spesifik seperti DrawRectangle melalui panggilan DrawGeometry generik. Ini karena dengan DrawRectangle, geometri sudah diketahui sehingga penyajian lebih cepat.
Merender geometri statis
Dalam skenario di mana geometri statis, gunakan teknik penembolokan per primitif yang dijelaskan di atas. Masker opasitas dan realisasi geometri dapat sangat meningkatkan kecepatan penyajian adegan yang berisi geometri statis..
Menggunakan konteks perangkat multithreaded
Aplikasi yang mengharapkan untuk merender konten geometris kompleks dalam jumlah signifikan harus mempertimbangkan untuk menentukan bendera D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTI_THREADED_OPTIMIZATIONS saat membuat konteks perangkat Direct2D . Ketika bendera ini ditentukan, Direct2D akan mendistribusikan penyajian di semua inti logis yang ada pada sistem, yang dapat secara signifikan mengurangi waktu penyajian keseluruhan.
Catatan:
- Pada Windows 8.1, bendera ini hanya memengaruhi penyajian geometri jalur. Ini tidak berdampak pada adegan yang hanya berisi jenis primitif lainnya (seperti teks, bitmap, atau realisasi geometri).
- Bendera ini juga tidak berdampak saat merender dalam perangkat lunak (yaitu saat merender dengan perangkat WARP Direct3D). Untuk mengontrol multithreading perangkat lunak, pemanggil harus menggunakan bendera D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS saat membuat perangkat WARP Direct3D.
- Menentukan bendera ini dapat meningkatkan set kerja puncak selama penyajian dan juga dapat meningkatkan ketidakcocokan utas dalam aplikasi yang sudah memanfaatkan pemrosesan multithread.
Menggambar teks dengan Direct2D
Fungsionalitas penyajian teks Direct2D ditawarkan dalam dua bagian. Bagian pertama, diekspos sebagai metode ID2D1RenderTarget::D rawText dan ID2D1RenderTarget::D rawTextLayout , memungkinkan pemanggil untuk meneruskan parameter string dan pemformatan atau objek tata letak teks DWrite untuk beberapa format. Ini harus cocok untuk sebagian besar penelepon. Cara kedua untuk merender teks, diekspos sebagai metode ID2D1RenderTarget::D rawGlyphRun , memberikan rasterisasi bagi pelanggan yang sudah mengetahui posisi glyph yang ingin mereka render. Dua aturan umum berikut dapat membantu meningkatkan performa teks saat menggambar di Direct2D.
DrawTextLayout Vs. DrawText
DrawText dan DrawTextLayout memungkinkan aplikasi untuk dengan mudah merender teks yang diformat oleh API DirectWrite. DrawTextLayout menggambar objek DWriteTextLayout yang ada ke RenderTarget, dan DrawText membuat tata letak DirectWrite untuk pemanggil, berdasarkan parameter yang diteruskan. Jika teks yang sama harus dirender beberapa kali, gunakan DrawTextLayout alih-alih DrawText, karena DrawText membuat tata letak setiap kali dipanggil.
Memilih mode penyajian teks yang tepat
Atur mode antialias teks ke D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE secara eksplisit. Kualitas penyajian teks skala abu-abu sebanding dengan ClearType tetapi jauh lebih cepat.
penembolokan
Gunakan adegan penuh atau penembolokan bitmap primitif seperti dengan menggambar primitif lainnya.
Mengklip bentuk arbitrer
Gambar di sini menunjukkan hasil penerapan klip ke gambar.
Anda bisa mendapatkan hasil ini dengan menggunakan lapisan dengan masker geometri atau metode FillGeometry dengan kuas opasitas.
Berikut adalah contoh yang menggunakan lapisan:
// Call PushLayer() and pass in the clipping geometry.
m_d2dContext->PushLayer(
D2D1::LayerParameters(
boundsRect,
geometricMask));
Berikut adalah contoh yang menggunakan metode 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());
Dalam contoh kode ini, saat Anda memanggil metode PushLayer, Anda tidak meneruskan lapisan yang dibuat aplikasi. Direct2D membuat lapisan untuk Anda. Direct2D dapat mengelola alokasi dan penghancuran sumber daya ini tanpa keterlibatan dari aplikasi. Ini memungkinkan Direct2D untuk menggunakan kembali lapisan secara internal dan menerapkan pengoptimalan manajemen sumber daya.
Dalam Windows 8 banyak pengoptimalan telah dilakukan untuk penggunaan lapisan dan kami sarankan Anda mencoba menggunakan API lapisan alih-alih FillGeometry jika memungkinkan.
PushLayer di Windows 8
Antarmuka ID2D1DeviceContext berasal dari antarmuka ID2D1RenderTarget dan merupakan kunci untuk menampilkan konten Direct2D di Windows 8, untuk informasi selengkapnya tentang antarmuka ini lihat Perangkat dan Konteks Perangkat. Dengan antarmuka konteks perangkat, Anda dapat melewati panggilan metode CreateLayer lalu meneruskan NULL ke metode ID2D1DeviceContext::P ushLayer . Direct2D secara otomatis mengelola sumber daya lapisan dan dapat berbagi sumber daya antara lapisan dan grafik efek.
Klip rata sumbu
Jika wilayah yang akan dipotong selaras dengan sumbu permukaan gambar, alih-alih arbitrer. Kasus ini cocok untuk menggunakan persegi klip alih-alih lapisan. Perolehan performa lebih untuk geometri alias daripada geometri yang dianalisa. Untuk informasi selengkapnya tentang klip rata sumbu, lihat topik PushAxisAlignedClip .
Interoperabilitas DXGI: hindari sakelar yang sering
Direct2D dapat beroperasi dengan mulus dengan permukaan Direct3D. Ini sangat berguna untuk membuat aplikasi yang merender campuran konten 2D dan 3D. Tetapi setiap peralihan antara menggambar konten Direct2D dan Direct3D memengaruhi performa.
Saat merender ke permukaan DXGI, Direct2D menyimpan status perangkat Direct3D saat merender dan memulihkannya saat penyajian selesai. Setiap kali batch penyajian Direct2D selesai, biaya penghematan dan pemulihan ini dan biaya pembilasan semua operasi 2D dibayar, namun, perangkat Direct3D tidak dibersihkan. Oleh karena itu, untuk meningkatkan performa, batasi jumlah sakelar penyajian antara Direct2D dan Direct3D.
Ketahui Format Piksel Anda
Saat membuat target render, Anda dapat menggunakan struktur D2D1_PIXEL_FORMAT menentukan format piksel dan mode alfa yang digunakan oleh target render. Saluran alfa adalah bagian dari format piksel yang menentukan nilai cakupan atau informasi opasitas. Jika target render tidak menggunakan saluran alfa, target tersebut harus dibuat dengan menggunakan mode alfa D2D1_ALPHA_MODE_IGNORE . Ini meluangkan waktu yang dihabiskan untuk merender saluran alfa yang tidak diperlukan.
Untuk informasi selengkapnya tentang format piksel dan mode alfa, lihat Format Piksel dan Mode Alfa yang Didukung.
Kompleksitas Adegan
Saat Anda menganalisis titik panas performa dalam adegan yang akan dirender, mengetahui apakah adegan terikat tingkat pengisian atau terikat puncak dapat memberikan informasi yang berguna.
- Tingkat Isian: Tingkat isian mengacu pada jumlah piksel yang dapat dirender dan ditulis kartu grafis ke memori video per detik.
- Vertex Bound: Adegan terikat vertex ketika berisi banyak geometri kompleks.
Memahami Kompleksitas Adegan
Anda dapat menganalisis kompleksitas adegan dengan mengubah ukuran target render. Jika perolehan performa terlihat untuk pengurangan ukuran target render yang proporsional, maka aplikasi terikat tingkat pengisian. Jika tidak, kompleksitas adegan adalah penyempitan performa.
Saat adegan terikat tingkat pengisian, mengurangi ukuran target render dapat meningkatkan performa. Ini karena jumlah piksel yang akan dirender akan dikurangi secara proporsional dengan ukuran target render.
Saat adegan terikat vertex, kurangi kompleksitas geometri. Tetapi ingatlah bahwa ini dilakukan dengan mengorbankan kualitas gambar. Oleh karena itu, keputusan tradeoff yang cermat harus dibuat antara kualitas yang diinginkan dan performa yang diperlukan.
Meningkatkan performa untuk aplikasi pencetakan Direct2D
Direct2D menawarkan kompatibilitas dengan pencetakan. Anda dapat mengirim perintah gambar Direct2D yang sama (dalam bentuk daftar perintah Direct2D) ke kontrol cetak Direct2D untuk pencetakan, jika Anda tidak tahu perangkat apa yang Anda gambar, atau bagaimana gambar diterjemahkan ke pencetakan.
Anda selanjutnya dapat menyempurnakan penggunaan kontrol cetak Direct2D dan perintah gambar Direct2D Anda untuk memberikan hasil pencetakan dengan performa yang lebih baik.
Kontrol cetak Direct2D menghasilkan pesan debug ketika melihat pola kode Direct2D yang mengarah ke kualitas atau performa pencetakan yang lebih rendah (seperti, pola kode yang tercantum nanti dalam topik ini) untuk mengingatkan Anda di mana Anda dapat menghindari masalah performa. Untuk melihat pesan debug tersebut, Anda perlu mengaktifkan Lapisan Debug Direct2D dalam kode Anda. Lihat Pesan Debug untuk petunjuk mengaktifkan output pesan debug.
Mengatur nilai properti yang tepat saat Anda membuat kontrol cetak D2D
Ada tiga properti yang dapat Anda atur saat membuat kontrol cetak Direct2D . Dua properti ini berdampak pada bagaimana kontrol cetak Direct2D menangani perintah Direct2D tertentu dan pada gilirannya memengaruhi performa keseluruhan.
- Mode Subset Font: Kontrol cetak Direct2D mem-subset sumber daya font yang digunakan di setiap halaman sebelum mengirim halaman untuk dicetak. Mode ini mengurangi ukuran sumber daya halaman yang diperlukan untuk mencetak. Bergantung pada penggunaan font pada halaman, Anda dapat memilih mode subset font yang berbeda untuk performa terbaik.
- D2D1_PRINT_FONT_SUBSET_MODE_DEFAULT memberikan performa pencetakan terbaik dalam banyak kasus. Ketika diatur ke mode ini, kontrol cetak Direct2D menggunakan strategi heuristik untuk memutuskan kapan harus subset font.
- Untuk pekerjaan cetak singkat dengan 1 atau 2 halaman, sebaiknya D2D1_PRINT_FONT_SUBSET_MODE_EACHPAGE , di mana subset kontrol cetak Direct2D dan menyematkan sumber daya font di setiap halaman, lalu membuang subset font tersebut setelah halaman dicetak. Opsi ini memastikan setiap halaman dapat dicetak segera setelah dibuat tetapi sedikit meningkatkan ukuran sumber daya halaman yang diperlukan untuk pencetakan (dengan subset font yang biasanya besar).
- Untuk pekerjaan cetak dengan banyak halaman teks dan ukuran font kecil (seperti 100 halaman teks yang menggunakan satu font), kami sarankan D2D1_PRINT_FONT_SUBSET_MODE_NONE, di mana kontrol cetak Direct2D tidak mensubset sumber daya font sama sekali; sebaliknya, ia mengirimkan sumber daya font asli bersama dengan halaman yang pertama kali menggunakan font, dan menggunakan kembali sumber daya font untuk halaman selanjutnya tanpa mengirimnya kembali.
- DPI Rasterisasi: Ketika kontrol cetak Direct2D perlu melakukan rasterisasi perintah Direct2D selama konversi Direct2D-XPS, ia menggunakan DPI ini untuk rasterisasi. Dengan kata lain, jika halaman tidak memiliki konten yang diraster, mengatur DPI apa pun tidak akan mengubah performa dan kualitas. Bergantung pada penggunaan rasterisasi di halaman, Anda dapat memilih DPI rasterisasi yang berbeda untuk keseimbangan terbaik antara keakuratan dan performa.
- 150 adalah nilai default jika Anda tidak menentukan nilai saat membuat kontrol cetak Direct2D , yang merupakan keseimbangan terbaik dari kualitas pencetakan dan performa pencetakan dalam banyak kasus.
- Nilai DPI yang lebih tinggi biasanya menghasilkan kualitas pencetakan yang lebih baik (seperti dalam detail lebih lanjut yang dipertahankan) tetapi performa yang lebih rendah karena bitmap yang lebih besar yang dihasilkannya. Kami tidak merekomendasikan nilai DPI yang lebih besar dari 300 karena itu tidak akan memperkenalkan informasi tambahan yang dapat dirasakan secara visual oleh mata manusia.
- DPI yang lebih rendah dapat berarti performa yang lebih baik tetapi juga dapat menghasilkan kualitas yang lebih rendah.
Hindari menggunakan pola gambar Direct2D tertentu
Ada perbedaan antara apa yang dapat diwakili Direct2D secara visual dan apa yang dapat dipertahankan dan diangkut oleh subsistem cetak di sepanjang seluruh alur cetak. Kontrol cetak Direct2D menjenjangkan celah tersebut dengan mengurangi atau mem-rasterisasi primitif Direct2D yang tidak didukung oleh subsistem cetak secara asli. Perkiraan tersebut biasanya menghasilkan keakuratan pencetakan yang lebih rendah, performa pencetakan yang lebih rendah, atau keduanya. Oleh karena itu, meskipun pelanggan dapat menggunakan pola gambar yang sama untuk penyajian layar dan cetak, itu tidak ideal dalam semua kasus. Sebaiknya jangan gunakan primitif dan pola Direct2D sebanyak mungkin untuk jalur cetak, atau untuk melakukan rasterisasi sendiri di mana Anda memiliki kontrol penuh atas kualitas dan ukuran gambar yang dirasterisasi.
Berikut adalah daftar kasus di mana performa dan kualitas cetak tidak akan ideal dan Anda mungkin ingin mempertimbangkan untuk memvariasikan jalur kode untuk performa cetak yang optimal.
- Hindari menggunakan mode campuran primitif selain D2D1_PRIMITIVE_BLEND_SOURCEOVER.
- Hindari menggunakan Mode Komposisi saat menggambar gambar selain D2D1_COMPOSITE_MODE_SOURCE_OVER dan D2D1_COMPOSITE_MODE_DESTINATION_OVER.
- Hindari menggambar File Meta GDI.
- Hindari mendorong sumber daya lapisan yang menyalin latar belakang sumber (memanggil PushLayer dengan meneruskan D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND ke struct D2D1_LAYER_PARAMETERS1 ).
- Hindari membuat Bitmap Brush atau Image Brush dengan D2D1_EXTEND_MODE_CLAMP. Kami sarankan Anda menggunakan D2D1_EXTEND_MODE_MIRROR jika tidak peduli dengan piksel di luar gambar yang terikat sama sekali (seperti, gambar yang melekat pada kuas diketahui lebih besar dari wilayah target yang diisi).
- Hindari menggambar Bitmap dengan Transformasi Perspektif.
Menggambar teks dengan cara langsung dan biasa
Direct2D memiliki beberapa pengoptimalan saat merender teks untuk ditampilkan untuk performa yang lebih baik dan/atau kualitas visual yang lebih baik. Tetapi tidak semua pengoptimalan meningkatkan performa dan kualitas pencetakan karena pencetakan pada kertas biasanya dalam DPI yang jauh lebih tinggi, dan pencetakan tidak perlu mengakomodasi skenario seperti animasi. Jadi, kami sarankan Anda menggambar teks atau glyph asli secara langsung dan menghindari salah satu pengoptimalan berikut saat membuat daftar perintah untuk pencetakan.
- Hindari menggambar teks dengan metode FillOpacityMask .
- Hindari menggambar teks dalam Mode Alias.
Gambar bitmap asli jika memungkinkan
Jika bitmap target adalah JPEG, PNG, TIFF, atau JPEG-XR, Anda dapat membuat bitmap WIC baik dari file disk atau dari aliran dalam memori, lalu membuat bitmap Direct2D dari bitmap WIC tersebut menggunakan ID2D1DeviceContext::CreateBitmapFromWicBitmap, dan akhirnya langsung meneruskan bitmap Direct2D tersebut ke kontrol cetak Direct2D tanpa manipulasi lebih lanjut. Dengan demikian, kontrol cetak Direct2D dapat menggunakan kembali aliran bitmap, yang biasanya mengarah pada performa pencetakan yang lebih baik (dengan melewatkan pengodean dan pendekodean bitmap redundan), dan kualitas pencetakan yang lebih baik (ketika metadata, seperti profil warna, dalam bitmap akan dipertahankan).
Menggambar bitmap asli memberikan manfaat berikut untuk aplikasi.
- Secara umum, cetak Direct2D mempertahankan informasi asli (tanpa kehilangan atau kebisingan) hingga terlambat di alur, terutama ketika aplikasi tidak tahu (atau tidak ingin tahu) detail alur cetak (seperti printer mana yang dicetaknya, DPI apa yang menjadi printer target, dan sebagainya).
- Dalam banyak kasus, menunda rasterisasi bitmap berarti performa yang lebih baik (seperti saat mencetak foto 96dpi ke printer 600dpi).
- Dalam kasus tertentu, meneruskan gambar asli adalah satu-satunya cara untuk menghormati keakuratan tinggi (seperti profil warna yang disematkan).
Namun, Anda tidak dapat memilih pengoptimalan tersebut karena:
- Dengan mengkueri info printer dan rasterisasi awal, Anda dapat mem-rasterisasi konten itu sendiri dengan kontrol penuh atas penampilan akhir di atas kertas.
- Dalam kasus tertentu, rasterisasi awal mungkin benar-benar meningkatkan performa end-to-end aplikasi (seperti mencetak foto ukuran dompet).
- Dalam kasus tertentu, melewati bitmap asli memerlukan perubahan signifikan dari arsitektur kode yang ada (seperti pemuatan penundaan gambar dan jalur pembaruan sumber daya yang ditemukan dalam aplikasi tertentu).
Kesimpulan
Meskipun Direct2D dipercepat perangkat keras dan dimaksudkan untuk performa tinggi, Anda harus menggunakan fitur dengan benar untuk memaksimalkan throughput. Teknik yang kita lihat di sini berasal dari mempelajari skenario umum dan mungkin tidak berlaku untuk semua skenario aplikasi.