2015-10-15 3 views
5

मैं विंडोज स्टोर के लिए एक ईबुक रीडर ऐप लिख रहा हूं। मैं स्क्रीन पर पुस्तक पृष्ठों को प्रस्तुत करने के लिए Direct2D + DXGI स्वैप श्रृंखला का उपयोग कर रहा हूं।कुशल डायरेक्ट 2 डी मल्टीथ्रेडिंग

मेरी पुस्तक सामग्री कभी-कभी काफी जटिल (ज्यामिति, बिटमैप्स, मास्क इत्यादि) होती है, इसलिए इसे प्रस्तुत करने में 100 एमएस तक लग सकते हैं। इसलिए मैं एक अलग थ्रेड में बिटमैप को ऑफ़-स्क्रीन प्रतिपादन करने की कोशिश कर रहा हूं, और फिर मुख्य थ्रेड में बस इस बिटमैप को दिखाएं।

हालांकि, मैं समझ नहीं पा रहा हूं कि इसे कुशलता से कैसे किया जाए।

अब तक मैं कोशिश की है दो दृष्टिकोण:

  1. D2D1_FACTORY_TYPE_MULTI_THREADED ध्वज के साथ उपयोग के लिए एक एकल ID2D1Factory, ID2D1BitmapRenderTarget बना सकते हैं और ऑफ स्क्रीन प्रतिपादन के लिए पृष्ठभूमि सूत्र में इसका इस्तेमाल करते हैं। (इसके अतिरिक्त ID2D1Multithread::Enter/LeaveIDXGISwapChain::Present संचालन के लिए आवश्यक है)। समस्या यह है कि ID2D1RenderTarget::EndDraw पृष्ठभूमि थ्रेड में ऑपरेशन कभी-कभी 100ms तक ले जाता है, और आंतरिक डायरेक्ट 2 डी लॉकिंग के कारण इस अवधि के लिए मुख्य थ्रेड प्रतिपादन अवरुद्ध है।

  2. पृष्ठभूमि थ्रेड में एक अलग ID2D1Factory का उपयोग करें (जैसा कि http://www.sdknews.com/ios/using-direct2d-for-server-side-rendering में वर्णित है) और आंतरिक डायरेक्ट 2 डी सिंक्रनाइज़ेशन को बंद करें। इस मामले में दो धागे betwen कोई क्रॉस लॉकिंग नहीं है। दुर्भाग्यवश, इस मामले में मैं परिणामस्वरूप बिटमैप का उपयोग मुख्य ID2D1Factory में सीधे नहीं कर सकता, क्योंकि यह एक अलग कारखाने से संबंधित है। मुझे बिटमैप डेटा को सीपीयू मेमोरी में ले जाना है, फिर इसे मुख्य ID2D1Factory की जीपीयू मेमोरी में कॉपी करें। यह ऑपरेशन भी महत्वपूर्ण झंडे पेश करता है (मुझे विश्वास है कि यह बड़ी मेमोरी एक्सेस के कारण होगा, लेकिन मुझे यकीन नहीं है)।

क्या यह कुशलतापूर्वक करने का कोई तरीका है?

पीएस यहां सभी समय एसर स्विच 10 टैबलेट के लिए दिए गए हैं। नियमित कोर i7 पीसी पर दोनों दृष्टिकोण किसी भी दृश्य अंतराल के बिना काम करते हैं।

उत्तर

4

ठीक है, मुझे एक समाधान मिला है।

असल में, मुझे केवल दो डायरेक्टएक्स फैक्ट्री सेटों के बीच डीएक्सजीआई संसाधन साझा करने के लिए दृष्टिकोण 2 को संशोधित करना है। मैं सभी रक्तमय विवरण छोड़ देंगे (वे यहां पाया जा सकता: http://xboxforums.create.msdn.com/forums/t/66208.aspx), लेकिन बुनियादी कदम हैं:

  1. DirectX संसाधनों के दो सेट बनाएँ: मुख्य (जो परदे पर प्रतिपादन करने के लिए इस्तेमाल किया जाएगा), और माध्यमिक (ऑफस्क्रीन प्रतिपादन के लिए)।
  2. मुख्य संसाधन सेट से ID3D11Device2 का उपयोग करना, CreateTexture2DD3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_RESOURCE_MISC_SHARED_NTHANDLE और D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX झंडे द्वारा D3D 2 डी बनावट पैदा करते हैं।
  3. इसे IDXGIResource1 पर कास्ट करके इसे और DXGI_SHARED_RESOURCE_WRITE से CreateSharedHandle पर कॉल करके साझा करेंडल प्राप्त करें।
  4. ID3D11Device2::OpenSharedResource1 पर कॉल करके पृष्ठभूमि थ्रेड में द्वितीयक संसाधन सेट में इस साझा बनावट को खोलें।
  5. इस बनावट (IDXGIKeyedMutex::AcquireSync) के कुंजी वाले म्यूटेक्स प्राप्त करें, इसे (ID2D1Factory2::CreateDxgiSurfaceRenderTarget) से रेंडर लक्ष्य बनाएं, इसे ड्रॉ करें और म्यूटेक्स (IDXGIKeyedMutex::ReleaseSync) जारी करें।
  6. मुख्य थ्रेड पर, मुख्य संसाधन सेट में, म्यूटेक्स प्राप्त करें और चरण 2 में बनाए गए बनावट से साझा बिटमैप बनाएं, इस बिटमैप को खींचें, फिर म्यूटेक्स को छोड़ दें।

ध्यान दें कि म्यूटेक्स लॉकिंग सामान आवश्यक है। ऐसा नहीं कर रहा है कुछ क्रिप्टिक डायरेक्टएक्स डीबग त्रुटि संदेश, और ग़लत ऑपरेशन या यहां तक ​​कि क्रैशिंग में भी परिणाम।

0

टीएल; डॉ: सॉफ़्टवेयर मोड में पृष्ठभूमि थ्रेड पर बिटमैप्स को प्रस्तुत करें। हार्डवेयर मोड में यूआई थ्रेड पर लक्ष्य प्रस्तुत करने के लिए बिटमैप्स से ड्रा करें।

सबसे अच्छा तरीका मैं अब तक पता लगाने के लिए कर लिया है साथ सॉफ्टवेयर प्रतिपादन (IWICImagingFactory::CreateBitmap और ID2D1Factory::CreateWicBitmapRenderTarget) पृष्ठभूमि धागे का उपयोग करने के लिए और फिर ID2D1RenderTarget::CreateBitmapFromWicBitmap के माध्यम से लक्ष्य एक हार्डवेयर बिटमैप पर प्रतिलिपि धागे पर वापस हार्डवेयर के साथ प्रस्तुत है । और फिर ID2D1RenderTarget::DrawBitmap का उपयोग करके उस पर विस्फोट करें।

इस प्रकार पेंटनेट 4.0 चयन प्रतिपादन करता है। जब आप लासो टूल के साथ चयन कर रहे होते हैं, तो यह चयन रूपरेखा को अतुल्यकालिक रूप से खींचने के लिए पृष्ठभूमि थ्रेड का उपयोग करेगा (UI थ्रेड पूर्ण होने के लिए प्रतीक्षा नहीं करता है)। आप स्ट्रोक शैली और एनिमेशन के कारण एक बहुत ही जटिल बहुभुज के साथ समाप्त कर सकते हैं। मैं इसे 4 बार प्रस्तुत करता हूं, जहां प्रत्येक एनीमेशन फ्रेम में धराशायी स्ट्रोक शैली के लिए थोड़ा अलग ऑफ़सेट होता है।

जाहिर है कि इस प्रतिपादन में कुछ समय लग सकता है क्योंकि बहुभुज अधिक जटिल हो जाता है (यानी, यदि आप थोड़ी देर के लिए लिखते रहते हैं)। मेरे पास मूव चयन टूल का उपयोग करने के लिए कुछ अन्य विशेष अनुकूलन हैं जो आपको ट्रांसफॉर्मेशन (घुमाने, अनुवाद करने, स्केल) करने की अनुमति देता है: यदि पृष्ठभूमि थ्रेड ने अभी तक नए ट्रांसफॉर्म के साथ वर्तमान बहुभुज को फिर से प्रस्तुत नहीं किया है, तो मैं लागू नए ट्रांसफॉर्म के साथ पुराने बिटमैप (वर्तमान बहुभुज और पुराने परिवर्तन के साथ) प्रस्तुत करेगा। पृष्ठभूमि की थ्रेड कैच होने पर चयन रूपरेखा विकृत (स्केलिंग) या क्लिप (देखने योग्य क्षेत्र के बाहर अनुवादित) हो सकती है, लेकिन यह 60fps प्रतिक्रिया के लिए भुगतान करने के लिए एक छोटी सी कीमत है।यह अनुकूलन बहुत अच्छी तरह से काम करता है क्योंकि आप एक ही समय में चयन के बहुभुज और को संशोधित नहीं कर सकते हैं।

संबंधित मुद्दे