Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Meskipun Direct2D mendapat akselerasi dari perangkat keras dan dirancang 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
- Batasi penggunaan flush
- Bitmap
- Gunakan bitmap berubin di atas garis putus-putus
- Panduan umum untuk merender konten statis yang kompleks
- Penyanggaan per-primitif menggunakan realisasi geometris
- penyajian Geometri
- teks Menggambar dengan Direct2D
- Memotong bentuk arbitrer
- interoperabilitas DXGI: hindari pergantian yang sering
- Mengetahui Format Piksel Anda
- Kompleksitas Adegan
- Meningkatkan performa untuk aplikasi pencetakan Direct2D
- Kesimpulan
Penggunaan sumber daya
Sumber daya adalah bentuk alokasi tertentu, baik dalam memori video maupun memori 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 mengumpulkan kumpulan perintah rendering, tetapi menunda pemrosesan perintah ini sampai salah satu pernyataan ini menjadi 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 menampung perintah pemrosesan penuh. Jika buffer ini menjadi penuh sebelum dua kondisi sebelumnya terpenuhi, perintah penyajian akan dihapus.
Sampai primitif selesai dibersihkan, Direct2D menyimpan referensi internal ke sumber daya terkait seperti bitmap dan kuas.
Gunakan 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 menyusun suatu adegan dalam game semuanya diciptakan sekaligus dengan berbagai variasi berbeda yang diperlukan untuk rendering setiap frame secara berurutan. Pada saat perenderan dan perenderaan ulang adegan berlangsung, bitmap ini digunakan kembali daripada dibuat ulang.
Nota
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.
Batasi penggunaan sistem penyiraman
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 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 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 beban kerja pembuatan bitmap serta pemborosan memori dalam 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 dari awal. Dan saat proses rendering, mereka dapat diambil dari bitmap besar.
Nota
Bitmap Direct2D yang dibuat dalam memori video dibatasi pada ukuran bitmap maksimum yang didukung oleh adaptor tempat bitmap disimpan. Membuat bitmap yang lebih besar dari itu dapat mengakibatkan kesalahan.
Membuat bitmap bersama
Membuat bitmap bersama memungkinkan pengguna tingkat lanjut untuk membuat objek bitmap Direct2D yang didukung secara langsung oleh objek yang sudah ada, yang sudah kompatibel dengan target render. Ini menghindari pembuatan beberapa permukaan dan membantu mengurangi performa overhead.
Nota
Bitmap berbagi biasanya terbatas pada target perangkat lunak atau ke target yang dapat dioperasikan dengan DXGI. Gunakan CreateBitmapFromDxgiSurface, CreateBitmapFromWicBitmap, dan metode CreateSharedBitmap untuk membuat bitmap bersama.
Menyalin bitmap
Membuat permukaan DXGI adalah operasi yang mahal sehingga gunakan kembali permukaan yang ada saat 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 menyimpan bitmap dalam urutan memori yang sama seperti saat bitmap dialamatkan. Sebaliknya, bitmap mungkin bergetar. Penyimpangan disembunyikan dari CPU baik oleh driver (yang lambat dan hanya digunakan pada bagian ujung bawah), atau oleh manajer memori pada GPU. Karena keterbatasan pada cara data ditulis ke dalam target render saat penyajian, target render biasanya tidak di-swizzle, atau di-swizzle dengan cara yang kurang optimal daripada yang dapat dicapai jika diketahui bahwa tidak ada keharusan untuk 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 bertiles daripada garis putus-putus
Menggambar garis putus-putus adalah operasi yang memerlukan biaya tinggi karena kualitas tinggi dan akurasi dari algoritma yang mendasari. Untuk mayoritas kasus yang tidak melibatkan geometri bergaris lurus, efek yang sama dapat dihasilkan lebih cepat dengan menggunakan bitmap ubin.
Panduan umum untuk merender konten statis yang kompleks
Cache konten jika Anda merender bingkai yang sama berulang kali, terutama ketika adegannya kompleks.
Ada tiga teknik penembolokan yang dapat Anda gunakan:
- Cache adegan penuh menggunakan bitmap warna.
- Untuk caching primitif menggunakan bitmap A8 dan metode FillOpacityMask .
- Pengelolaan cache untuk setiap primitif menggunakan realisasi geometri.
Mari kita lihat masing-masing secara lebih rinci.
Caching 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 adalah 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 penyimpanan sementara dan mengalihkan bitmap yang ditunjuk oleh konteks perangkat saat dirender. Ini menghindari kebutuhan untuk membuat target render yang kompatibel untuk tujuan yang sama.
Untuk caching primitif menggunakan bitmap A8 dan metode FillOpacityMask.
Ketika seluruh adegan tidak statis, tetapi terdiri dari elemen seperti geometri atau teks yang statis, Anda dapat menggunakan teknik caching per primitif. Teknik ini mempertahankan karakteristik anti-aliasing dari elemen dasar yang di-cache dan berfungsi dengan berbagai jenis kuas. Ini menggunakan bitmap A8 di mana A8 adalah semacam 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 keburaman masker.
Berikut adalah 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);
Penyimpanan sementara per primitif menggunakan realisasi geometri
Teknik caching 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 mengonversinya menjadi realizasi geometris dan berulang kali menggambar realisasi tersebut daripada berulang kali menggambar geometri itu sendiri. 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 adalah 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();
Penggambaran geometri
Gunakan gambar primitif khusus atas geometri gambar
Gunakan panggilan primitif yang lebih spesifik seperti DrawRectangle daripada panggilan generik DrawGeometry. Ini karena dengan DrawRectangle, geometri sudah diketahui sehingga penyajian lebih cepat.
Merenderkan geometri statis
Dalam sebuah skenario di mana geometri statis, gunakan teknik penyimpanan cache per primitif yang dijelaskan di atas. Masker opasitas dan realisasi geometri dapat sangat meningkatkan kecepatan penyajian adegan yang berisi geometri statis..
Menggunakan konteks perangkat multi-utas
Aplikasi yang bermaksud untuk merender kuantitas besar konten geometrik kompleks harus mempertimbangkan untuk menentukan flag D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTI_THREADED_OPTIMIZATIONS saat membuat konteks perangkat Direct2D . Ketika flag ini ditentukan, Direct2D akan mendistribusikan rendering di semua inti logis yang ada pada sistem, yang dapat secara signifikan mengurangi waktu rendering total.
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 menggunakan perangkat lunak (yaitu saat merender dengan perangkat WARP Direct3D). Untuk mengontrol multithreading perangkat lunak, pemanggil harus menggunakan penanda D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS saat membuat perangkat WARP Direct3D.
- Menentukan flag ini dapat meningkatkan puncak himpunan kerja selama proses render dan juga dapat meningkatkan persaingan 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::DrawText dan ID2D1RenderTarget::DrawTextLayout, memungkinkan pemanggil untuk meneruskan baik string beserta parameter pemformatannya 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::DrawGlyphRun, memberikan rasterisasi bagi pelanggan yang sudah mengetahui posisi glyph yang akan dirender. Dua aturan umum berikut dapat membantu meningkatkan performa teks saat menggambar di Direct2D.
DrawTextLayout Vs. DrawText
Baik DrawText dan DrawTextLayout memungkinkan aplikasi merender teks dengan mudah yang diformat oleh API DirectWrite. DrawTextLayout menggambar objekDWriteTextLayoutyang 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.
Penyimpanan sementara
Gunakan penyimpanan sementara untuk seluruh tampilan atau per primitif bitmap seperti pada penggambaran primitif lainnya.
Memotong bentuk arbitrer
Gambar di sini menunjukkan hasil penerapan klip ke gambar.
Anda bisa mendapatkan hasil ini dengan menggunakan layer 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 buatan aplikasi. Direct2D membuat lapisan untuk Anda. Direct2D dapat mengelola alokasi dan penghancuran sumber daya ini tanpa keterlibatan apa pun dari aplikasi. Ini memungkinkan Direct2D untuk menggunakan kembali lapisan secara internal dan menerapkan pengoptimalan manajemen sumber daya.
Di 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
AntarmukaID2D1DeviceContextberasal dari antarmukaID2D1RenderTargetdan 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 mengabaikan pemanggilan metode CreateLayer lalu meneruskan NULL ke metode ID2D1DeviceContext::PushLayer. Direct2D secara otomatis mengelola sumber daya lapisan dan dapat berbagi sumber daya antara lapisan dan grafik efek.
Klip yang sejajar dengan sumbu
Jika wilayah yang akan diklip diselaraskan ke sumbu permukaan gambar, daripada secara acak. Kasus ini cocok untuk menggunakan persegi klip alih-alih lapisan. Perolehan performa lebih besar untuk geometri yang beralias daripada geometri yang dihaluskan. Untuk informasi selengkapnya tentang klip rata sumbu, lihat topik PushAxisAlignedClip.
Interoperabilitas DXGI: hindari pergantian 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 rendering Direct2D selesai, biaya penyimpanan dan pemulihan ini serta biaya pembilasan semua operasi 2D harus dibayar, namun perangkat Direct3D tidak dilakukan pembilasan. Oleh karena itu, untuk meningkatkan performa, batasi jumlah sakelar penyajian antara Direct2D dan Direct3D.
Mengetahui 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 harus dibuat dengan menggunakan mode alfa D2D1_ALPHA_MODE_IGNORE. Ini menghemat waktu yang digunakan untuk merender saluran alfa yang tidak diperlukan.
Untuk informasi selengkapnya tentang format piksel dan mode alfa, lihat Format Piksel yang Didukung dan Mode Alfa.
Kompleksitas Adegan
Saat Anda menganalisis titik panas performa dalam adegan yang akan dirender, mengetahui apakah adegan dibatasi oleh tingkat pengisian atau oleh vertex dapat memberikan informasi yang berguna.
- Tingkat Pengisian: Tingkat pengisian mengacu pada jumlah piksel yang dapat dirender dan ditulis kartu grafis ke memori video per detik.
- Vertex Bound: Suatu adegan terbatas oleh vertex ketika berisi banyak geometri kompleks.
Memahami Kompleksitas Adegan
Anda dapat menganalisis kompleksitas adegan Anda dengan mengubah ukuran target render. Jika peningkatan performa nampak untuk pengurangan ukuran target render yang proporsional, maka aplikasi terbatas oleh tingkat pengisian. Jika tidak, kompleksitas adegan adalah hambatan 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.
Ketika adegan dibatasi oleh jumlah vertex, kurangi kompleksitas dari 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.
Atur 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 memengaruhi bagaimana kontrol cetak Direct2D menangani perintah Direct2D tertentu dan pada gilirannya memengaruhi performa keseluruhan.
- Mode Subset Font: Direct2D membuat subset sumber daya font yang digunakan pada setiap halaman sebelum halaman tersebut dikirim 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 pendek dengan 1 atau 2 halaman, sebaiknya D2D1_PRINT_FONT_SUBSET_MODE_EACHPAGE , di mana Direct2D mencetak subset kontrol 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 font tunggal), kami sarankan D2D1_PRINT_FONT_SUBSET_MODE_NONE, di mana kontrol cetak Direct2D tidak mensubset sumber daya font sama sekali; sebaliknya, ini 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 merasterisasi perintah Direct2D selama konversi Direct2D-XPS, ia menggunakan DPI berikut untuk rasterisasi. Dengan kata lain, jika halaman tidak memiliki konten yang dirasterisasi, pengaturan DPI apa pun tidak akan mengubah performa dan kualitas. Bergantung pada penggunaan rasterisasi pada 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 lebih banyak detail yang dipertahankan) tetapi menurunkan performa karena bitmap lebih besar yang dihasilkan. 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 kinerja yang lebih baik tetapi juga dapat menghasilkan kualitas yang lebih rendah.
Hindari menggunakan pola gambar Direct2D tertentu
Ada perbedaan antara apa yang dapat diwakili secara visual oleh Direct2D dan apa yang dapat dipertahankan serta diangkut oleh subsistem cetak sepanjang seluruh alur cetak. Kontrol cetak Direct2D menjembatani kesenjangan tersebut dengan mendekati atau merasterisasi primitif Direct2D yang tidak didukung secara asli oleh subsistem cetak. 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 kita tidak menggunakan primitif dan pola Direct2D seminimal mungkin untuk jalur cetak, atau melakukan rasterisasi sendiri dengan kontrol penuh atas kualitas dan ukuran hasil rasterisasi.
Berikut adalah daftar kasus di mana performa dan kualitas cetak tidak akan ideal dan Anda mungkin ingin mempertimbangkan untuk memvariasi 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 menggunakan sumber daya lapisan yang menyalin latar belakang (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 Anda tidak peduli tentang piksel di luar batas gambar sama sekali, misalnya jika gambar yang terpasang pada kuas diketahui lebih besar dari wilayah sasaran yang diisi.
- Hindari menggambar Bitmap dengan Transformasi Perspektif .
Menggambar teks dengan cara langsung dan biasa
Direct2D memiliki beberapa pengoptimalan saat merender teks untuk ditampilkan demi performa yang lebih baik dan/atau kualitas visual yang lebih baik. Tetapi tidak semua pengoptimalan meningkatkan performa dan kualitas pencetakan karena pencetakan di 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 Direct2D bitmap 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 memanfaatkan kembali aliran bitmap, yang biasanya menghasilkan performa pencetakan yang lebih baik (dengan menghindari pengodean dan dekode bitmap yang tidak perlu) dan kualitas pencetakan yang lebih baik (karena metadata, seperti profil warna, dalam bitmap bisa dipertahankan).
Menggambar bitmap asli memberikan manfaat berikut untuk aplikasi.
- Secara umum, cetakan Direct2D mempertahankan informasi asli (tanpa kehilangan atau kebisingan) hingga tahap akhir di alur, terutama ketika aplikasi tidak tahu (atau tidak mau tahu) rincian alur cetak, seperti printer mana yang digunakan untuk mencetak, berapa DPI dari 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 dini, Anda dapat mem-rasterisasi konten itu sendiri dengan kontrol penuh atas penampilan akhir di 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.