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 কখনওই বাফার কন্টেন্ট কপি করে না, কারণ এত বেশি ডেটা এদিক-ওদিক সরানোটা খুব একটা কার্যকর নয়। এর পরিবর্তে, সবসময় হ্যান্ডেলের মাধ্যমে বাফার পাস করা হয়।

Systrace-এর সাহায্যে BufferQueue ট্র্যাক করা

গ্রাফিক্স বাফার কীভাবে কাজ করে তা বুঝতে, Systrace ব্যবহার করুন, এটি এমন একটি টুল যা অল্প সময়ের জন্য ডিভাইসের অ্যাক্টিভিটি রেকর্ড করে। সিস্টেম-লেভেল গ্রাফিক্স কোডটি ভালভাবে ইন্সট্রুমেন্ট করা হয়েছে, যেমনটি প্রাসঙ্গিক অ্যাপ ফ্রেমওয়ার্ক কোডের বেশিরভাগই।

Systrace ব্যবহার করতে, gfx, view এবং sched ট্যাগ চালু করুন। ট্রেসে BufferQueueটি অবজেক্ট দেখানো হয়েছে। উদাহরণস্বরূপ, আপনি যদি Grafika's Play ভিডিও (SurfaceView) চলাকালীন ট্রেস নেন, তাহলে SurfaceView লেবেল করা সারিটি আপনাকে বলে দেবে যে কোনও নির্দিষ্ট সময়ে কতগুলি বাফার সারিবদ্ধ করা হয়েছে।

অ্যাপ অ্যাক্টিভ থাকাকালীন ভ্যালু বাড়তে থাকে, যা MediaCodec ডিকোডার দ্বারা ফ্রেম রেন্ডার করার প্রক্রিয়াকে ট্রিগার করে। SurfaceFlinger কাজ করা ও বাফার ব্যবহার করার সময় ভ্যালু কমে যায়। ৩০ fps-এ ভিডিও দেখানোর সময়, কোয়ের ভ্যালু ০ থেকে ১ পর্যন্ত পরিবর্তিত হয় কারণ ~৬০ fps ডিসপ্লে সোর্সের সাথে তাল মিলিয়ে চলতে পারে। SurfaceFlinger শুধুমাত্র কাজ করার প্রয়োজন হলেই জেগে ওঠে, প্রতি সেকেন্ডে ৬০ বার নয়। স্ক্রিন আপডেট না হলে, সিস্টেম কাজ এড়িয়ে যেতে এবং VSync বন্ধ করে দিতে চেষ্টা করে।

আপনি Grafika-এর Play ভিডিওতে (TextureView) পাল্টে নতুন ট্রেস নিলে, আপনি একটি সারি দেখতে পাবেন যার লেবেলে লেখা আছে com.android.grafika / com.android.grafika.PlayMovieActivity। এটি হল মূল UI লেয়ার, যা আরেকটি BufferQueue ইনস্ট্যান্স। TextureView আলাদা লেয়ারের পরিবর্তে UI লেয়ারে রেন্ডার করে, তাই ভিডিও-চালিত সব আপডেট এখানে দেখানো হয়।

Gralloc

Gralloc অ্যালোকেটর HAL hardware/libhardware/include/hardware/gralloc.h ব্যবহারের ফ্ল্যাগের মাধ্যমে বাফার অ্যালোকেশন করে। ব্যবহার সংক্রান্ত ফ্ল্যাগে এইসব অ্যাট্রিবিউট থাকে:

  • সফ্টওয়্যার (CPU) থেকে কত ঘন ঘন মেমরি অ্যাক্সেস করা হবে
  • কত ঘন ঘন হার্ডওয়্যার (GPU) থেকে মেমরি অ্যাক্সেস করা হবে
  • মেমরি OpenGL ES (GLES) টেক্সচার হিসেবে ব্যবহার করা হবে কিনা
  • ভিডিও এনকোডার মেমরি ব্যবহার করবে কিনা

যেমন, কোনও প্রযোজকের বাফার ফর্ম্যাটে RGBA_8888 পিক্সেল নির্দিষ্ট করা থাকলে এবং প্রযোজক যদি ইঙ্গিত করেন যে বাফারটি সফ্টওয়্যার থেকে অ্যাক্সেস করা হবে (অর্থাৎ, কোনও অ্যাপ CPU-তে পিক্সেল স্পর্শ করবে), তাহলে Gralloc R-G-B-A ক্রমে প্রতি পিক্সেল ৪ বাইট সহ একটি বাফার তৈরি করে। এর পরিবর্তে, কোনও প্রযোজক যদি নির্দিষ্ট করে যে তার বাফার শুধুমাত্র হার্ডওয়্যার থেকে এবং GLES টেক্সচার হিসেবে অ্যাক্সেস করা হবে, তাহলে Gralloc GLES ড্রাইভার যা চায় তা করতে পারে, যেমন BGRA অর্ডারিং, নন-লিনিয়ার সোয়াজলড লেআউট এবং বিকল্প কালার ফরম্যাট। হার্ডওয়্যারকে তার পছন্দসই ফর্ম্যাট ব্যবহার করতে দিলে পারফর্ম্যান্স উন্নত হতে পারে।

কিছু ভ্যালু নির্দিষ্ট প্ল্যাটফর্মে একত্রিত করা যায় না। যেমন, ভিডিও এনকোডার ফ্ল্যাগের জন্য YUV পিক্সেল প্রয়োজন হতে পারে, তাই সফ্টওয়্যার অ্যাক্সেস যোগ করা এবং RGBA_8888 নির্দিষ্ট করা যায় না।

Gralloc-এর রিটার্ন করা হ্যান্ডেল Binder-এর মাধ্যমে প্রসেসের মধ্যে পাস করা যেতে পারে।

সুরক্ষিত বাফার

Gralloc ব্যবহার সংক্রান্ত ফ্ল্যাগ GRALLOC_USAGE_PROTECTED শুধুমাত্র হার্ডওয়্যার-সুরক্ষিত পাথ ব্যবহার করে গ্রাফিক্স বাফার দেখানোর অনুমতি দেয়। এইসব ওভারলে প্লেন হল DRM কন্টেন্ট দেখানোর একমাত্র উপায় (SurfaceFlinger বা OpenGL ES ড্রাইভার DRM-সুরক্ষিত বাফার অ্যাক্সেস করতে পারে না)।

DRM-সুরক্ষিত ভিডিও শুধুমাত্র ওভারলে প্লেনে দেখানো যাবে। ভিডিও প্লেয়ার যেগুলি সুরক্ষিত কন্টেন্ট সাপোর্ট করে সেগুলিকে SurfaceView-এর সাথে প্রয়োগ করতে হবে। সুরক্ষিত নয় এমন হার্ডওয়্যারে রান করা সফ্টওয়্যার বাফার পড়তে বা লিখতে পারে না; হার্ডওয়্যার-সুরক্ষিত পাথ অবশ্যই হার্ডওয়্যার কম্পোজার ওভারলেতে দেখাতে হবে (অর্থাৎ, হার্ডওয়্যার কম্পোজার OpenGL ES কম্পোজিশনে পরিবর্তন করলে সুরক্ষিত ভিডিও ডিসপ্লে থেকে অদৃশ্য হয়ে যায়)।

সুরক্ষিত কন্টেন্ট সম্পর্কে আরও জানতে, DRM দেখুন।