लेयर और डिसप्ले, दो ऐसे प्रिमिटिव हैं जो कंपोज़िशन के काम और डिसप्ले हार्डवेयर के साथ इंटरैक्शन को दिखाते हैं.
लेयर
लेयर , कंपोज़िशन की सबसे अहम यूनिट है. लेयर, एक
सरफेस और
SurfaceControl के इंस्टेंस का कॉम्बिनेशन होती है.
हर लेयर में प्रॉपर्टी का एक सेट होता है. इससे यह तय होता है कि वह दूसरी लेयर के साथ कैसे इंटरैक्ट करती है. लेयर की प्रॉपर्टी के बारे में यहां बताया गया है:
| प्रॉपर्टी | ब्यौरा |
|---|---|
| पोज़िशनल | इससे यह तय होता है कि लेयर, डिसप्ले पर कहां दिखती है. इसमें, लेयर के किनारों की पोज़िशन और अन्य लेयर के मुकाबले उसका Z ऑर्डर जैसी जानकारी शामिल होती है. इससे यह तय होता है कि लेयर, अन्य लेयर के आगे दिखनी चाहिए या पीछे. |
| कॉन्टेंट | इससे यह तय होता है कि पोज़िशनल प्रॉपर्टी से सेट की गई सीमाओं के अंदर, लेयर पर कॉन्टेंट कैसे दिखता है. इसमें, कॉन्टेंट को लेयर की सीमाओं तक फैलाने के लिए क्रॉप करना और घुमाए या फ़्लिप किए गए कॉन्टेंट को दिखाने के लिए ट्रांसफ़ॉर्म करना शामिल है. |
| कंपोज़िशन | इससे यह तय होता है कि लेयर को अन्य लेयर के साथ कैसे कंपोज़ किया जाना चाहिए. इसमें, ब्लेंडिंग मोड और अल्फा कंपोज़िशन के लिए, लेयर-वाइड अल्फा वैल्यू जैसी जानकारी शामिल होती है.अल्फा कंपोज़िटिंग |
| ऑप्टिमाइज़ेशन | इसमें ऐसी जानकारी शामिल होती है जो लेयर कंपोज़िशन के लिए ज़रूरी नहीं है. हालांकि, हार्डवेयर कंपोज़र (एचडब्ल्यूसी) डिवाइस, कंपोज़िशन की परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए इस जानकारी का इस्तेमाल कर सकता है. इसमें, लेयर का दिखने वाला हिस्सा और पिछले फ़्रेम के बाद अपडेट किया गया हिस्सा शामिल है. |
डिसप्ले
डिसप्ले , कंपोज़िशन की एक और अहम यूनिट है. किसी सिस्टम में एक से ज़्यादा डिसप्ले हो सकते हैं. साथ ही, सिस्टम के सामान्य ऑपरेशन के दौरान डिसप्ले जोड़े या हटाए जा सकते हैं. एचडब्ल्यूसी या फ़्रेमवर्क के अनुरोध पर, डिसप्ले जोड़े या हटाए जाते हैं.
जब किसी डिवाइस से कोई बाहरी डिसप्ले कनेक्ट या डिसकनेक्ट किया जाता है, तो एचडब्ल्यूसी डिवाइस, डिसप्ले जोड़ने या हटाने का अनुरोध करता है. इसे हॉटप्लगिंग कहा जाता है. क्लाइंट, वर्चुअल डिसप्ले का अनुरोध करते हैं. इनका कॉन्टेंट, फ़िज़िकल डिसप्ले के बजाय ऑफ़-स्क्रीन बफ़र में रेंडर किया जाता है.
वर्चुअल डिसप्ले
SurfaceFlinger इंटरनल डिसप्ले (फ़ोन या टैबलेट में बना), बाहरी डिसप्ले (जैसे, एचडीएमआई से कनेक्ट किया गया टेलीविज़न) के साथ-साथ एक या उससे ज़्यादा वर्चुअल डिसप्ले को सपोर्ट करता है. इससे कंपोज़िट आउटपुट, सिस्टम में उपलब्ध हो जाता है. वर्चुअल डिसप्ले का इस्तेमाल, स्क्रीन रिकॉर्ड करने या स्क्रीन को नेटवर्क पर भेजने के लिए किया जा सकता है. वर्चुअल डिसप्ले के लिए जनरेट किए गए फ़्रेम, BufferQueue में लिखे जाते हैं.
वर्चुअल डिसप्ले, मुख्य डिसप्ले (लेयर स्टैक) के लिए इस्तेमाल की जाने वाली लेयर के एक ही सेट को शेयर कर सकते हैं या उनका अपना सेट हो सकता है. वर्चुअल डिसप्ले के लिए कोई VSync नहीं होता. इसलिए, इंटरनल डिसप्ले के लिए VSync, सभी डिसप्ले के लिए कंपोज़िशन को ट्रिगर करता है.
एचडब्ल्यूसी के उन इंप्लीमेंटेशन पर जहां वर्चुअल डिसप्ले को सपोर्ट किया जाता है, उन्हें OpenGL ES (GLES), एचडब्ल्यूसी या GLES और एचडब्ल्यूसी, दोनों के साथ कंपोज़ किया जा सकता है. जिन इंप्लीमेंटेशन पर वर्चुअल डिसप्ले को सपोर्ट नहीं किया जाता है, उन्हें हमेशा GLES का इस्तेमाल करके कंपोज़ किया जाता है.
केस स्टडी: screenrecord
The screenrecord command की मदद से, उपयोगकर्ता स्क्रीन पर दिखने वाली हर चीज़ को डिस्क पर MP4 फ़ाइल के तौर पर रिकॉर्ड कर सकता है. इसे लागू करने के लिए, सिस्टम को SurfaceFlinger से कंपोज़िट फ़्रेम मिलते हैं. इसके बाद, उन्हें वीडियो एनकोडर में लिखा जाता है. फिर, एनकोड किए गए वीडियो डेटा को किसी फ़ाइल में लिखा जाता है. वीडियो कोडेक को एक अलग प्रोसेस (mediaserver) मैनेज करती है. इसलिए, बड़े ग्राफ़िक्स बफ़र को सिस्टम में इधर-उधर ले जाना पड़ता है. इसे और मुश्किल बनाने के लिए, हमारा लक्ष्य फ़ुल रिज़ॉल्यूशन पर 60 एफपीएस का वीडियो रिकॉर्ड करना है. BufferQueue की मदद से, इसे आसानी से किया जा सकता है.
MediaCodec क्लास की मदद से, कोई ऐप्लिकेशन डेटा को बफ़र में रॉ बाइट के तौर पर या किसी सरफेस के ज़रिए उपलब्ध करा सकता है. जब screenrecord , वीडियो एनकोडर को ऐक्सेस करने का अनुरोध करता है, तो mediaserver प्रोसेस, BufferQueue बनाती है. इसके बाद, वह खुद को कंज्यूमर साइड से कनेक्ट करती है. फिर, प्रोड्यूसर साइड को screenrecord को सरफेस के तौर पर पास करती है.
इसके बाद, screenrecord यूटिलिटी, SurfaceFlinger से एक वर्चुअल डिसप्ले बनाने के लिए कहती है. यह वर्चुअल डिसप्ले, मुख्य डिसप्ले की तरह ही काम करता है. इसका मतलब है कि इसमें वही सभी लेयर होती हैं. साथ ही, यह mediaserver प्रोसेस से मिले सरफेस पर आउटपुट भेजता है. इस मामले में, SurfaceFlinger, बफ़र का प्रोड्यूसर होता है, न कि कंज्यूमर.
कॉन्फ़िगरेशन पूरा होने के बाद, एनकोड किया गया डेटा दिखने पर screenrecord ट्रिगर होता है. जब ऐप्लिकेशन ड्रॉ करते हैं, तो उनके बफ़र, SurfaceFlinger पर जाते हैं. इसके बाद, SurfaceFlinger उन्हें एक बफ़र में कंपोज़ करता है. यह बफ़र, mediaserver प्रोसेस में वीडियो एनकोडर को सीधे भेजा जाता है. screenrecord प्रोसेस को कभी भी पूरे फ़्रेम नहीं दिखते. इंटरनल तौर पर, mediaserver प्रोसेस के पास बफ़र को इधर-उधर ले जाने का अपना तरीका होता है. इससे हैंडल के ज़रिए डेटा भी पास किया जाता है. इससे ओवरहेड कम हो जाता है.
केस स्टडी: अतिरिक्त वर्चुअल डिसप्ले बनाने की सेटिंग
WindowManager, SurfaceFlinger से एक दिखने वाली लेयर बनाने के लिए कह सकता है. इसके लिए, SurfaceFlinger, BufferQueue कंज्यूमर के तौर पर काम करता है. SurfaceFlinger से वर्चुअल डिसप्ले बनाने के लिए भी कहा जा सकता है. इसके लिए, SurfaceFlinger, BufferQueue प्रोड्यूसर के तौर पर काम करता है.
अगर किसी वर्चुअल डिसप्ले को दिखने वाली लेयर से कनेक्ट किया जाता है, तो एक क्लोज़्ड लूप बनता है. इसमें कंपोज़िट स्क्रीन, एक विंडो में दिखती है. अब वह विंडो, कंपोज़िट आउटपुट का हिस्सा है. इसलिए, अगले रीफ़्रेश पर, विंडो के अंदर कंपोज़िट इमेज में विंडो का कॉन्टेंट भी दिखता है. इसे देखने के लिए, सेटिंग में जाकर, डेवल101}पर विकल्प चालू करें. इसके बाद, अतिरिक्त वर्चुअल डिसप्ले बनाने की सेटिंग को चुनें और कोई विंडो चालू करें. अतिरिक्त वर्चुअल डिसप्ले को देखने के लिए, screenrecord का इस्तेमाल करके, डिसप्ले को चालू करने की प्रोसेस को कैप्चर करें. इसके बाद, इसे फ़्रेम-दर-फ़्रेम चलाएं.