BufferQueue और Gralloc

BufferQueue क्लास, ग्राफ़िकल डेटा (प्रोड्यूसर) के बफ़र जनरेट करने वाले कॉम्पोनेंट को, डिसप्ले या आगे प्रोसेस करने (उपभोक्ता) के लिए डेटा स्वीकार करने वाले कॉम्पोनेंट से कनेक्ट करती है. सिस्टम में ग्राफ़िकल डेटा के बफ़र को मूव करने वाली करीब-करीब हर चीज़, BufferQueue पर निर्भर करती है.

Gralloc मेमोरी ऐलोकेटर, बफ़र ऐलोकेशन करता है और इसे दो वेंडर-स्पेसिफ़िक एचआईडीएल इंटरफ़ेस (hardware/interfaces/graphics/allocator/ और hardware/interfaces/graphics/mapper/ देखें) के ज़रिए लागू किया जाता है. allocate() फ़ंक्शन, इस्तेमाल के फ़्लैग के साथ-साथ उम्मीद के मुताबिक आर्ग्युमेंट (चौड़ाई, ऊंचाई, पिक्सल फ़ॉर्मैट) लेता है.

BufferQueue के प्रोड्यूसर और कंज्यूमर

उपभोक्ता, BufferQueue डेटा स्ट्रक्चर बनाते हैं और उनका मालिकाना हक उनके पास होता है. साथ ही, वे डेटा प्रोड्यूसर की तुलना में अलग-अलग प्रोसेस में मौजूद हो सकते हैं. जब किसी प्रोड्यूसर को बफ़र की ज़रूरत होती है, तो वह dequeueBuffer() को कॉल करके, BufferQueue से किसी खाली बफ़र का अनुरोध करता है. साथ ही, बफ़र की चौड़ाई, ऊंचाई, पिक्सल फ़ॉर्मैट, और इस्तेमाल के फ़्लैग की जानकारी देता है. इसके बाद, प्रोड्यूसर बफ़र में डेटा भरता है और queueBuffer() को कॉल करके, बफ़र को सूची में वापस भेजता है. इसके बाद, उपभोक्ता acquireBuffer() की मदद से बफ़र हासिल करता है और बफ़र के कॉन्टेंट का इस्तेमाल करता है. जब उपभोक्ता का काम पूरा हो जाता है, तो वह releaseBuffer() को कॉल करके बफ़र को सूची में वापस कर देता है. सिंक फ़्रेमवर्क यह कंट्रोल करता है कि Android ग्राफ़िक्स पाइपलाइन में बफ़र कैसे चलते हैं.

BufferQueue की कुछ विशेषताओं, जैसे कि इसमें कितने बफ़र हो सकते हैं, यह प्रोड्यूसर और कंज्यूमर, दोनों तय करते हैं. हालांकि, BufferQueue ज़रूरत के हिसाब से बफ़र को असाइन करता है. बफ़र तब तक बनाए रखा जाता है, जब तक उनकी विशेषताएं बदल नहीं जातीं. उदाहरण के लिए, अगर कोई प्रोड्यूसर अलग साइज़ के बफ़र का अनुरोध करता है, तो पुराने बफ़र खाली कर दिए जाते हैं और मांग के हिसाब से नए बफ़र असाइन किए जाते हैं.

BufferQueue, बफ़र किए गए कॉन्टेंट को कभी कॉपी नहीं करता, क्योंकि इतना डेटा एक जगह से दूसरी जगह ले जाना फ़ायदेमंद नहीं होता. इसके बजाय, बफ़र हमेशा हैंडल से पास किए जाते हैं.

Systrace की मदद से BufferQueue को ट्रैक करना

यह समझने के लिए कि ग्राफ़िक बफ़र कैसे काम करते हैं, Systrace का इस्तेमाल करें. यह एक ऐसा टूल है जो कुछ समय के लिए डिवाइस की गतिविधि को रिकॉर्ड करता है. सिस्टम-लेवल ग्राफ़िक कोड को अच्छी तरह से इंस्ट्रूमेंट किया गया है. साथ ही, ज़्यादातर काम का ऐप्लिकेशन फ़्रेमवर्क कोड भी इंस्ट्रूमेंट किया गया है.

Systrace का इस्तेमाल करने के लिए, gfx, view, और sched टैग चालू करें. BufferQueue ऑब्जेक्ट, ट्रेस में दिखाए जाते हैं. उदाहरण के लिए, अगर Grafika का Play वीडियो (SurfaceView) चलने के दौरान कोई ट्रेस लिया जाता है, तो SurfaceView लेबल वाली लाइन से पता चलता है कि किसी भी समय कितने बफ़र कतार में थे.

ऐप्लिकेशन चालू होने पर, इसकी वैल्यू बढ़ती है. इससे MediaCodec डिकोडर, फ़्रेम को रेंडर करना शुरू कर देता है. SurfaceFlinger के काम करने और बफ़र का इस्तेमाल करने के दौरान, वैल्यू कम हो जाती है. वीडियो को 30 fps पर दिखाने पर, सूची की वैल्यू 0 से 1 के बीच बदलती रहती है. इसकी वजह यह है कि ~60 fps डिसप्ले, सोर्स के साथ चल सकता है. SurfaceFlinger सिर्फ़ तब काम करता है, जब कोई काम करना हो. यह हर सेकंड 60 बार काम नहीं करता. अगर स्क्रीन पर कुछ अपडेट नहीं हो रहा है, तो सिस्टम काम करने से बचने की कोशिश करता है और VSync बंद कर देता है.

Grafika के Play वीडियो (TextureView) पर स्विच करने और नया ट्रेस लेने पर, आपको एक लाइन दिखेगी, जिस पर com.android.grafika / com.android.grafika.PlayMovieActivity लेबल होगा. यह मुख्य यूज़र इंटरफ़ेस (यूआई) लेयर है, जो BufferQueue का एक और इंस्टेंस है. TextureView, अलग लेयर के बजाय यूज़र इंटरफ़ेस (यूआई) लेयर में रेंडर होता है. इसलिए, वीडियो से जुड़े सभी अपडेट यहां दिखते हैं.

Gralloc

Gralloc एलोकेटर एचएएलhardware/libhardware/include/hardware/gralloc.h इस्तेमाल के फ़्लैग की मदद से, बफ़र के लिए जगह तय करता है. इस्तेमाल से जुड़े फ़्लैग में ये एट्रिब्यूट शामिल होते हैं:

  • सॉफ़्टवेयर (सीपीयू) से मेमोरी को कितनी बार ऐक्सेस किया जाएगा
  • हार्डवेयर (GPU) से मेमोरी को कितनी बार ऐक्सेस किया जाएगा
  • मेमोरी का इस्तेमाल OpenGL ES (GLES) टेक्स्चर के तौर पर किया जाएगा या नहीं
  • वीडियो एन्कोडर का इस्तेमाल मेमोरी के लिए किया जाएगा या नहीं

उदाहरण के लिए, अगर किसी प्रोड्यूसर के बफ़र फ़ॉर्मैट में RGBA_8888 पिक्सल की जानकारी दी गई है और प्रोड्यूसर यह बताता है कि बफ़र को सॉफ़्टवेयर से ऐक्सेस किया जाएगा (इसका मतलब है कि कोई ऐप्लिकेशन सीपीयू पर पिक्सल को ऐक्सेस करेगा), तो Gralloc R-G-B-A क्रम में हर पिक्सल के लिए चार बाइट वाला बफ़र बनाता है. अगर इसके बजाय, प्रोड्यूसर यह बताता है कि उसके बफ़र को सिर्फ़ हार्डवेयर से और GLES टेक्सचर के तौर पर ऐक्सेस किया जाएगा, तो Gralloc GLES ड्राइवर के मुताबिक कुछ भी कर सकता है. जैसे, BGRA ऑर्डरिंग, नॉन-लाइनर स्विज़्ड लेआउट, और वैकल्पिक कलर फ़ॉर्मैट. हार्डवेयर को अपने पसंदीदा फ़ॉर्मैट का इस्तेमाल करने की अनुमति देने से, परफ़ॉर्मेंस बेहतर हो सकती है.

कुछ वैल्यू को कुछ प्लैटफ़ॉर्म पर जोड़ा नहीं जा सकता. उदाहरण के लिए, वीडियो एन्कोडर फ़्लैग के लिए YUV पिक्सल की ज़रूरत पड़ सकती है. इसलिए, सॉफ़्टवेयर ऐक्सेस जोड़ने और RGBA_8888 की जानकारी देने पर, ऐक्सेस नहीं मिलता.

Gralloc से मिला हैंडल, Binder की मदद से प्रोसेस के बीच भेजा जा सकता है.

सुरक्षित बफ़र

Gralloc के इस्तेमाल से जुड़े फ़्लैग GRALLOC_USAGE_PROTECTED की मदद से, ग्राफ़िक बफ़र को सिर्फ़ हार्डवेयर से सुरक्षित पाथ के ज़रिए दिखाया जा सकता है. डीआरएम कॉन्टेंट दिखाने का सिर्फ़ यही तरीका है (डीआरएम से सुरक्षित बफ़र को SurfaceFlinger या OpenGL ES ड्राइवर ऐक्सेस नहीं कर सकता).

डीआरएम (डिजिटल राइट मैनेजमेंट) की मदद से सुरक्षित किया गया वीडियो, सिर्फ़ ओवरले प्लेन पर दिखाया जा सकता है. सुरक्षित कॉन्टेंट के साथ काम करने वाले वीडियो प्लेयर को SurfaceView के साथ लागू किया जाना चाहिए. बिना सुरक्षा वाले हार्डवेयर पर चलने वाला सॉफ़्टवेयर, बफ़र को पढ़ या लिख नहीं सकता. साथ ही, हार्डवेयर से सुरक्षित किए गए पाथ, हार्डवेयर कंपोजर ओवरले पर दिखने चाहिए. इसका मतलब है कि अगर हार्डवेयर कंपोजर, OpenGL ES कंपोजिशन पर स्विच करता है, तो सुरक्षित किए गए वीडियो डिसप्ले से हट जाते हैं.

सुरक्षित कॉन्टेंट के बारे में ज़्यादा जानने के लिए, डीएमआर देखें.