मैं जो हल करता हूं उसे हल करने का प्रयास कर रहा हूं, जो मैंने सोचा था कि एक बहुत ही सरल समस्या होगी। मैं पूरी स्क्रीन सामग्री के साथ एक QPixmap अद्यतन करना चाहता हूं। आप ऐसा करने से इस तरह के एक पिक्समैप प्राप्त कर सकते हैं:X11, XDamage, XRender, और अन्य चालों का उपयोग कर स्क्रीन सामग्री की QPixmap प्रति रखें
QDesktopWidget *w = QApplication::desktop();
if (w)
{
QRect r = w->screenGeometry();
QPixmap p = QPixmap::grabWindow(w->winId(), 0, 0, r.width(), r.height())
QByteArray bitmap;
}
इस के साथ समस्या यह है कि QDesktopWidget समाप्त होता है फिर से हथियाने हर बार जब आप इसके लिए पूछना है, भले ही कुछ भी नहीं बदला है X11 सर्वर से पूरे स्क्रीन पिक्समैप।
मुझे इस कोड को तेज़ होने की आवश्यकता है, इसलिए मैं इसे स्वयं करने की कोशिश कर रहा हूं। मेरा शुरुआती बिंदु qx11mirror demo था, हालांकि, मूल रूप से वही काम करता है। जब कुछ बदल गया है, तो यह काम करने के लिए XDamage एक्सटेंशन का उपयोग करता है, लेकिन कैश किए गए पिक्समैप के उस हिस्से को अपडेट करने के लिए क्षतिग्रस्त आयताकार जानकारी का उपयोग करने के बजाय, यह सिर्फ एक "गंदा" ध्वज सेट करता है, जो किसी भी तरह से ताज़ा रीफ्रेश करता है।
तो मैं विंडोज़ के क्षतिग्रस्त हिस्से को अपडेट करने के लिए qx11mirror उदाहरण को संशोधित करने का प्रयास कर रहा हूं, लेकिन मुझे काम करने के लिए कुछ भी नहीं मिल रहा है - मुझे बस एक खाली (काला) पिक्समैप मिलता है। मैं जिस कोड का उपयोग कर रहा हूं वह है:
void QX11Mirror::x11Event(XEvent *event)
{
if (event->type == m_damageEvent + XDamageNotify)
{
XDamageNotifyEvent *e = reinterpret_cast<XDamageNotifyEvent*>(event);
XWindowAttributes attr;
XGetWindowAttributes(QX11Info::display(), m_window, &attr);
XRenderPictFormat *format = XRenderFindVisualFormat(QX11Info::display(), attr.visual);
bool hasAlpha = (format->type == PictTypeDirect && format->direct.alphaMask);
int x = attr.x;
int y = attr.y;
int width = attr.width;
int height = attr.height;
// debug output so I can see the window pos vs the damaged area:
qDebug() << "repainting dirty area:" << x << y << width << height << "vs" << e->area.x << e->area.y << e->area.width << e->area.height;
XRenderPictureAttributes pa;
pa.subwindow_mode = IncludeInferiors; // Don't clip child widgets
Picture picture = XRenderCreatePicture(QX11Info::display(),
m_window,
format,
CPSubwindowMode,
&pa);
XserverRegion region = XFixesCreateRegionFromWindow(QX11Info::display(),
m_window, WindowRegionBounding);
XFixesTranslateRegion(QX11Info::display(), region, -x, -y);
XFixesSetPictureClipRegion(QX11Info::display(), picture, 0, 0, region);
XFixesDestroyRegion(QX11Info::display(), region);
//QPixmap dest(width, height);
XRenderComposite(QX11Info::display(), // display
hasAlpha ? PictOpOver : PictOpSrc, // operation mode
picture, // src drawable
None, // src mask
dest.x11PictureHandle(), // dest drawable
e->area.x, // src X
e->area.y, // src Y
0, // mask X
0, // mask Y
e->area.x, // dest X
e->area.y, // dest Y
e->area.width, // width
e->area.height); // height
m_px = dest;
XDamageSubtract(QX11Info::display(), e->damage, None, None);
emit windowChanged();
}
else if (event->type == ConfigureNotify)
{
XConfigureEvent *e = &event->xconfigure;
m_position = QRect(e->x, e->y, e->width, e->height);
emit positionChanged(m_position);
}
}
क्या कोई मुझे सही दिशा में इंगित कर सकता है? XRender, XDamage, और अन्य X11 एक्सटेंशन के लिए ड्यूमेटेनेशन बहुत खराब है। XCopyArea
निम्न पाठ here से लिया से अधिक XRender प्रयोग करने के लिए
कारण।
खिड़की के लिए जीसी बनाने और एक्सकॉपीएरिया() का उपयोग विंडो की सामग्री की प्रतिलिपि बनाने के लिए पूरी तरह से संभव है यदि आप कोर प्रोटोकॉल का उपयोग करना चाहते हैं, लेकिन चूंकि समग्र एक्सटेंशन नए दृश्यों को उजागर करता है (अल्फा चैनलों वाले), इस बात की कोई गारंटी नहीं है कि स्रोत खींचने योग्य प्रारूप का प्रारूप गंतव्य से मेल खाता है। कोर प्रोटोकॉल के साथ स्थिति के परिणामस्वरूप एक त्रुटि त्रुटि होगी, जो कुछ Xrender एक्सटेंशन के साथ नहीं होगा।
इसके अतिरिक्त कोर प्रोटोकॉल को अल्फा चैनलों की कोई समझ नहीं है, जिसका अर्थ यह है कि यह नए एआरजीबी दृश्य का उपयोग करने वाली खिड़कियों को मिश्रित नहीं कर सकता है। जब स्रोत और गंतव्य का एक ही प्रारूप होता है, तो X11R6.8 के रूप में कोर प्रोटोकॉल का उपयोग करने के लिए कोई प्रदर्शन लाभ भी नहीं होता है। यह रिलीज नए समग्र एक्सटेंशन का समर्थन करने वाला पहला भी है।
तो निष्कर्ष में कोई कमी नहीं है, और इन परिचालनों के लिए कोर प्रोटोकॉल पर Xrender चुनने के केवल फायदे हैं।
XCopyArea के बजाय XRender का उपयोग क्यों करें? XRender त्रुटि प्रवण है (यदि आप इसे सही तरीके से सही नहीं करते हैं, तो यह काम नहीं करेगा ..) – ypnos
मुझे पता चला है कि स्क्रीन को अपडेट करने का प्रयास केवल क्षतिग्रस्त हिस्सों को अपडेट करना अभ्यास में इतना अच्छा काम नहीं करता है। उदाहरण के लिए, ओपनजीएल अनुप्रयोग कभी भी क्षति की रिपोर्ट नहीं करते हैं। मुझे लगता है कि स्क्रीन को पुनः प्राप्त करना आपकी सबसे अच्छी शर्त है। – ldog
यदि आप इसे स्मार्ट करते हैं तो आप स्क्रीन को वास्तविक समय (10-20 फ्रेम प्रति सेकंड) में पुनः प्राप्त कर सकते हैं। – ldog