2011-09-21 10 views
8

जो मैंने पढ़ा है here ऐसा लगता है कि अधिकांश विंडोज़ जीडीआई कार्यों में तेजी आई है। इसलिए उदाहरण के लिए BitBlt या AlphaBlend पर कॉल होने पर कॉल त्वरण का उपयोग करता है। यह भी उल्लेख करता है कि खिड़की की सामग्री केवल वीडियो मेमोरी में ही रखी जाती है। अब विंडो डीसी के लिए यह सब अच्छा और सच है, लेकिन मैं मेमोरी डीसी का उपयोग कैसे कर सकता हूं जो वीडियो कार्ड मेमोरी में रहता है? और एक बार जब हमने यह निष्कर्ष निकाला है कि पिक्सल तक सीधी पहुंच कैसे प्राप्त करें, मुझे लगता है कि इसमें शामिल होगा 1. सिस्टम मेमोरी में अस्थायी प्रतिलिपि बनाना 2. पिक्सेल डेटा को बदलें 3. वीडियो मेमोरी पर वापस कॉपी करें।CreateCompatibleBitmap और CreateDIBSection (मेमोरी डीसी)

मैं दो तरीकों की कोशिश की है, दोनों सिस्टम स्मृति का आवंटन के रूप में मैं कार्य प्रबंधक में देख सकते हैं ...

  1. CreateCompatibleBitmap

    HDC hDC = GetDC(NULL); 
    m_hDC = CreateCompatibleDC(hDC); 
    m_hBmp = CreateCompatibleBitmap(hDC, cx, cy); 
    ReleaseDC(NULL, hDC); 
    
    m_hOldBmp = (HBITMAP)SelectObject(m_hDC, m_hBmp); 
    

    और फिर बिट्स प्राप्त करने के लिए फोन

    GetBitmapBits(...) 
    

    विभिन्न टिप्पणियों के अनुसार यह वास्तव में वीडियो मेमोर में संगत बिटमैप बनाना चाहिए y, लेकिन मैं अभी भी सिस्टम मेमोरी में वृद्धि क्यों देख सकता हूं (भले ही मैं GetBitmapBits पर कॉल न करें)?

  2. CreateDIBSection

    HDC hDC = GetDC(NULL); 
    m_hDC = CreateCompatibleDC(hDC); 
    
    BITMAPINFO bmi; 
    memset(&bmi, 0, sizeof(BITMAPINFO)); 
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    bmi.bmiHeader.biWidth = cx; 
    bmi.bmiHeader.biHeight = -cy; // top-down 
    bmi.bmiHeader.biPlanes = 1; 
    bmi.bmiHeader.biBitCount = 32; 
    bmi.bmiHeader.biCompression = BI_RGB; 
    m_hBmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&m_pBits, NULL, NULL); 
    
    ReleaseDC(NULL, hDC); 
    
    m_hOldBmp = (HBITMAP)SelectObject(m_hDC, m_hBmp); 
    

    इस मामले में हम तुरंत (m_pBits) बिट्स के लिए सूचक प्राप्त तो यह है कि इन सिस्टम स्मृति में रहते हैं स्पष्ट है ...

या यह एक है कॉपी करें जो दोनों तरीकों के लिए सिस्टम मेमोरी में रखा गया है? लेकिन अगर मैं सिस्टम मेमोरी में बिट्स बदलता हूं तो BitBlt पर कॉल को सिस्टम मेमोरी से फिर से कॉपी/कॉपी करना होगा ... बहुत अनुकूलित आईएमएचओ नहीं।

संपादित करें: मैंने BeginBufferedPaint और GetBufferedPaintBits का उपयोग करके स्मृति डीसी बनाने की भी कोशिश की है। यह सिस्टम मेमोरी को भी आवंटित करता है, इसलिए उस सम्मान में मुझे लगता है कि यह उपरोक्त तरीकों के लिए सिर्फ एक रैपर है लेकिन डीसी के कैश को अगली कॉल को स्मृति डीसी को फिर से बनाना आवश्यक नहीं है। रेमंड चेन के article देखें।

संपादित करें # 2: मुझे लगता है कि वास्तविक प्रश्न यह है: क्या मैं हार्डवेयर त्वरित जीडीआई संचालन प्राप्त करने के लिए विधि 1 या 2 में स्मृति डीसी निर्माण सही कर रहा हूं? मेरे लिए यह सब तेज़ लगता है, और दोनों विधियां भी एक ही गति प्रदान करती हैं, इसलिए इसे जांचने का कोई तरीका नहीं है ...

+0

मैंने सोचा कि यह हमेशा सिस्टम मेमोरी में रहता है और स्क्रीन पर रेंडर होने पर ही वीडियो मेमोरी में बदल जाता है ... – AJG85

+0

तो इसका मतलब यह होगा कि हम इसे वीडियो मेमोरी में नहीं बना सकते हैं और जीडीआई फ़ंक्शन हार्डवेयर पर त्वरित होने पर त्वरित नहीं होते हैं एक स्मृति डीसी? – demorge

+2

* ब्लिटिंग ऑपरेशंस के लिए केवल जीडीआई फ़ंक्शंस * विंडोज 7 पर विशेष रूप से हार्डवेयर तेज हैं। जीडीआई + अभी भी विंडोज 7 पर भी सॉफ्टवेयर प्रदान किया गया है और अभी भी धीमा है। यदि आप कुछ जटिल कर रहे हैं जिसके लिए प्रदर्शन की आवश्यकता है तो सरल उत्तर जीडीआई का उपयोग नहीं करता है। यदि आप हार्डवेयर तक सीधे पहुंच चाहते हैं तो ओपनजीएल या डायरेक्टएक्स का उपयोग करें। जीडीआई हमेशा एक अमूर्त होगा। – AJG85

उत्तर

3

मेमोरी डीसी किसी डिवाइस पर नहीं बनाए जाते हैं। वे जीडीआई आउटपुट को स्मृति में डालने के लिए डिज़ाइन किए गए हैं।

MSDN पर

Memory Device Contexts से:

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

यदि आप हार्डवेयर त्वरित 2 डी ग्राफिक्स चाहते हैं, तो आपको Direct2D का उपयोग करने पर विचार करना चाहिए।

+0

आह जो चीजों को स्पष्ट करता है, और यह भी कहता है: * जब एक डीआईबी या डीडीबी को पैलेट डिवाइस पर डीआईबी से बनाया गया है, तो आप उस गति को बेहतर बना सकते हैं जिस पर छवि को तार्किक पैलेट की व्यवस्था करके मिलान किया जाता है सिस्टम पैलेट का लेआउट। * जो यह स्पष्ट करता है कि 'CreateCompatibleBitmap' सबसे तेज़ तरीका होना चाहिए, लेकिन चूंकि मेरा सिस्टम 32-बिट रंग में चलाया जाता है, इसलिए 32-बिट लेआउट का उपयोग करके' CreateDIBSection' 'जितना तेज़ होता है (यह है एक ही बिटमैप प्रारूप जो दोनों कार्यों द्वारा बनाया गया है)। – demorge

+0

डायरेक्ट 2 डी बनाम जीडीआई के प्रदर्शन के साथ मेरे अनुभव से, मैं Direct2D का उपयोग करने की अनुशंसा नहीं करता। यह धीमी है, जीडीआई के समान गति के बारे में। – Trinidad

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