BufferQueue وGralloc

تربط فئة BufferQueue بين المكوّنات التي تنشئ مخازن مؤقتة للبيانات الرسومية (المنتجون) والمكوّنات التي تقبل البيانات لعرضها أو معالجتها بشكلٍ إضافي (المستهلكون). يعتمد كل ما ينقل وحدات تخزين مؤقتة للبيانات الرسومية عبر النظام تقريبًا على BufferQueue.

يُجري أداة تخصيص الذاكرة Gralloc عمليات تخصيص المخزن المؤقت ويتم تنفيذها من خلال واجهتَي HIDL خاصتَين بالمورّد (راجِع hardware/interfaces/graphics/allocator/ و hardware/interfaces/graphics/mapper/). تأخذ الدالة allocate() الوسيطات المتوقّعة (العرض والارتفاع وتنسيق البكسل) بالإضافة إلى مجموعة من أعلام الاستخدام.

صنّاع BufferQueue ومستهلكيها

ينشئ المستهلكون بنية بيانات BufferQueue ويملكونها، ويمكن أن يكونوا في عمليات مختلفة عن تلك التي يستخدمها المنتجون. عندما يحتاج مُنشئ المحتوى إلى ذاكرة تخزين مؤقت، فإنه يطلب ذاكرة تخزين مؤقتة فارغة من BufferQueue من خلال استدعاء dequeueBuffer()، مع تحديد عرض ذاكرات التخزين المؤقت وارتفاعها وتنسيق البكسل وعلامات الاستخدام. بعد ذلك، يعبّئ المنتج المخزن المؤقت ويعيده إلى قائمة الانتظار من خلال استدعاء queueBuffer(). بعد ذلك، يحصل المستهلك على المخزن المؤقت باستخدام acquireBuffer() ويستفيد من محتويات المخزن المؤقت. عندما ينتهي المستهلك من استخدام البيانات، يُعيد المحتوى المؤقت إلى القائمة من خلال استدعاء releaseBuffer(). يتحكّم إطار عمل المزامنة في كيفية نقل ذاكرة التخزين المؤقت عبر مسار رسومات Android.

يحدّد كلّ من المنتج والمستهلك بشكلٍ مشترك بعض خصائص BufferQueue، مثل الحدّ الأقصى لعدد المخازن المؤقتة التي يمكن أن تحتوي عليها. ومع ذلك، تخصص BufferQueue وحدات التخزين المؤقت حسب الحاجة. يتم الاحتفاظ بالمخازن المؤقتة ما لم تتغيّر الخصائص. على سبيل المثال، إذا طلب المُنشئ مخازنًا مؤقتة بحجم مختلف، يتم تحرير المخازن المؤقتة القديمة وتخصيص مخازن مؤقتة جديدة عند الطلب.

لا تنسخ BufferQueue أبدًا محتويات المخزن المؤقت، لأنّ نقل هذا الكمّ الكبير من البيانات ليس مجديًا. بدلاً من ذلك، يتم دائمًا تمرير المخزن المؤقت من خلال معرّف.

تتبُّع BufferQueue باستخدام Systrace

لفهم كيفية نقل ذاكرة التخزين المؤقت للرسومات، استخدِم Systrace، وهي أداة تسجِّل نشاط الجهاز على مدار فترة زمنية قصيرة. تمّت مراقبة رمز الرسومات على مستوى النظام بشكل جيد، كما تمّت مراقبة الكثير من رمز إطار عمل التطبيق المعنيّ.

لاستخدام Systrace، فعِّل علامات gfx وview و sched. يتم عرض عناصر BufferQueue في التتبُّع. على سبيل المثال، إذا أجريت عملية تتبُّع أثناء تشغيل فيديو (SurfaceView) Play من Grafika، يُعلمك الصف الذي يحمل التصنيف SurfaceView بعدد وحدات التخزين المؤقت التي تم وضعها في قائمة الانتظار في أي وقت معيّن.

تزداد القيمة عندما يكون التطبيق نشطًا، ما يؤدي إلى بدء عرض اللقطات بواسطة وحدة ترميز/فك ترميز MediaCodec. تنخفض القيمة عندما يعمل SurfaceFlinger ويستهلك وحدات التخزين المؤقت. عند عرض الفيديو بمعدّل 30 لقطة في الثانية، تتراوح قيمة الانتظار بين 0 و1 لأنّ عرض المحتوى بمعدّل 60 لقطة في الثانية تقريبًا يمكن أن يتلاءم مع المصدر. لا يتم تشغيل SurfaceFlinger إلا عند توفُّر عمل يجب تنفيذه، وليس 60 مرة في الثانية. يحاول النظام تجنُّب العمل ويوقف ميزة VSYNC إذا لم يكن هناك أي محتوى يتم تعديله على الشاشة.

إذا بدّلت إلى فيديو Play في Grafika (TextureView) وحصلت على تتبع جديد، سيظهر لك صف يحمل التصنيف com.android.grafika / com.android.grafika.PlayMovieActivity. هذه هي طبقة واجهة المستخدم الرئيسية، وهي BufferQueue أخرى. بما أنّ TextureView يتم عرضها في طبقة واجهة المستخدم بدلاً من طبقة منفصلة، يتم عرض جميع تعديلات الفيديو هنا.

Gralloc

ينفِّذ أداة تخصيص الذاكرة Gralloc HAL hardware/libhardware/include/hardware/gralloc.h عمليات تخصيص المخزن المؤقت من خلال علامات الاستخدام. تتضمّن علامات الاستخدام سمات مثل:

  • عدد المرات التي سيتم فيها الوصول إلى الذاكرة من البرنامج (وحدة المعالجة المركزية)
  • عدد المرات التي سيتم فيها الوصول إلى الذاكرة من الأجهزة (وحدة معالجة الرسومات)
  • ما إذا كان سيتم استخدام الذاكرة كزخرفة OpenGL ES (GLES)
  • ما إذا كان سيتم استخدام الذاكرة من قِبل برنامج ترميز الفيديو

على سبيل المثال، إذا كان تنسيق المخزن المؤقت الخاص بالمنتج يحدّد RGBA_8888 بكسل، ويشير المنتج إلى أنّه سيتم الوصول إلى المخزن المؤقت من البرنامج (أي أنّ التطبيق سيستخدم وحدات البكسل في وحدة المعالجة المركزية)، ينشئ Gralloc مخزنًا مؤقتًا يحتوي على 4 بايت لكل بكسل بترتيب R-G-B-A. إذا حدّد المنتج بدلاً من ذلك أنّه لن يتم الوصول إلى ذاكرته المؤقتة إلا من الأجهزة وكملمس GLES، يمكن أن ينفّذ Gralloc أيّ إجراء يريده سائق GLES، مثل ترتيب BGRA وتنسيقات ألوان بديلة وتصاميم غير خطية تم تبديلها. يمكن أن يؤدي السماح للأجهزة باستخدام التنسيق المفضّل إلى تحسين الأداء.

لا يمكن دمج بعض القيم على منصات معيّنة. على سبيل المثال، قد تتطلّب علامة رمز ترميز الفيديو استخدام وحدات بكسل YUV، لذا لا يمكن إضافة إذن الوصول إلى البرنامج وتحديد RGBA_8888.

يمكن تمرير الاسم المعرِّف الذي يعرضه Gralloc بين العمليات من خلال Binder.

الفواصل المحمية

لا تسمح علامة استخدام Gralloc GRALLOC_USAGE_PROTECTED بعرض مخازن الرسومات إلا من خلال مسار محمي بالأجهزة. هذه المستويات المتراكبة هي الطريقة الوحيدة لعرض محتوى إدارة الحقوق الرقمية (لا يمكن لـ SurfaceFlinger أو برنامج تشغيل OpenGL ES الوصول إلى ملفّات التخزين المؤقت المحمية بإدارة الحقوق الرقمية).

لا يمكن عرض الفيديو المحمي بإدارة الحقوق الرقمية إلا على مستوى التراكب. يجب تنفيذ مشغّلات الفيديو التي تتيح تشغيل المحتوى المحمي باستخدام SurfaceView. لا يمكن للبرامج التي تعمل على أجهزة غير محمية قراءة أو كتابة المخزن المؤقت، ويجب أن تظهر المسارات المحمية بالأجهزة على التراكب الخاص بـ "أداة إنشاء المحتوى بالأجهزة" (أي أنّه يتم إخفاء الفيديوهات المحمية من الشاشة إذا غيّرت "أداة إنشاء المحتوى بالأجهزة" وضعها إلى وضع إنشاء OpenGL ES).

لمعرفة التفاصيل حول المحتوى المحمي، يُرجى الاطّلاع على مقالة إدارة الحقوق الرقمية.