হার্ডওয়্যার কম্পোজার (HWC) HAL, সারফেসফ্লিঙ্গার থেকে প্রাপ্ত লেয়ারগুলোকে একত্রিত করে, যার ফলে OpenGL ES (GLES) এবং GPU-এর কম্পোজিশনের পরিমাণ কমে যায়।
HWC ওভারলে এবং 2D ব্লিটারের মতো অবজেক্টগুলোকে অ্যাবস্ট্রাক্ট করে সারফেস কম্পোজিট করে এবং উইন্ডো কম্পোজিট করার জন্য বিশেষায়িত উইন্ডো কম্পোজিশন হার্ডওয়্যারের সাথে যোগাযোগ করে। SurfaceFlinger-কে GPU-এর সাথে কম্পোজিট করতে দেওয়ার পরিবর্তে, উইন্ডো কম্পোজিট করার জন্য HWC ব্যবহার করুন। বেশিরভাগ GPU কম্পোজিশনের জন্য অপ্টিমাইজ করা থাকে না, এবং যখন GPU, SurfaceFlinger থেকে লেয়ার কম্পোজ করে, তখন অ্যাপগুলো তাদের নিজস্ব রেন্ডারিংয়ের জন্য GPU ব্যবহার করতে পারে না।
HWC বাস্তবায়নে অবশ্যই নিম্নলিখিত বিষয়গুলো সমর্থন করতে হবে:
- কমপক্ষে চারটি ওভারলে:
- স্ট্যাটাস বার
- সিস্টেম বার
- অ্যাপ
- ওয়ালপেপার/পটভূমি
- ডিসপ্লের চেয়ে বড় লেয়ার (উদাহরণস্বরূপ, একটি ওয়ালপেপার)
- একযোগে প্রিমাল্টিপ্লাইড প্রতি-পিক্সেল আলফা ব্লেন্ডিং এবং প্রতি-প্লেন আলফা ব্লেন্ডিং
- সুরক্ষিত ভিডিও প্লেব্যাকের জন্য হার্ডওয়্যার পাথ
- RGBA প্যাকিং অর্ডার, YUV ফরম্যাট এবং টাইলিং, সুইজলিং ও স্ট্রাইড প্রোপার্টি
HWC বাস্তবায়ন করতে:
- একটি নন-অপারেশনাল HWC বাস্তবায়ন করুন এবং কম্পোজিশনের সমস্ত কাজ GLES-এ পাঠিয়ে দিন।
- পর্যায়ক্রমে HWC-কে কম্পোজিশনের দায়িত্ব অর্পণ করার জন্য একটি অ্যালগরিদম প্রয়োগ করুন। উদাহরণস্বরূপ, HWC-এর ওভারলে হার্ডওয়্যারে কেবল প্রথম তিন বা চারটি সারফেসের দায়িত্ব অর্পণ করুন।
- HWC অপ্টিমাইজ করুন। এর মধ্যে অন্তর্ভুক্ত থাকতে পারে:
- জিপিইউ-এর উপর থেকে সর্বাধিক চাপ কমানো যায় এমন সারফেসগুলো নির্বাচন করে সেগুলোকে এইচডব্লিউসি-তে পাঠানো হচ্ছে।
- স্ক্রিন আপডেট হচ্ছে কিনা তা শনাক্ত করা হচ্ছে। যদি তা না হয়, তাহলে শক্তি সাশ্রয়ের জন্য HWC-এর পরিবর্তে GLES-কে কম্পোজিশনের দায়িত্ব অর্পণ করুন। স্ক্রিনটি আবার আপডেট হলে, HWC-তে কম্পোজিশনের দায়িত্ব পুনরায় অর্পণ করুন।
- সাধারণ ব্যবহারের ক্ষেত্রগুলির জন্য প্রস্তুতি, যেমন:
- হোম স্ক্রিন, যার মধ্যে স্ট্যাটাস বার, সিস্টেম বার, অ্যাপ উইন্ডো এবং লাইভ ওয়ালপেপার অন্তর্ভুক্ত।
- পোর্ট্রেট এবং ল্যান্ডস্কেপ মোডে পূর্ণ-স্ক্রিন গেম
- ক্লোজড ক্যাপশনিং এবং প্লেব্যাক নিয়ন্ত্রণ সহ পূর্ণ-স্ক্রিন ভিডিও
- সুরক্ষিত ভিডিও প্লেব্যাক
- স্প্লিট-স্ক্রিন মাল্টিউইন্ডো
HWC আদিম
HWC কম্পোজিশনের কাজ এবং ডিসপ্লে হার্ডওয়্যারের সাথে এর মিথস্ক্রিয়াকে উপস্থাপন করার জন্য লেয়ার এবং ডিসপ্লে নামক দুটি প্রিমিটিভ প্রদান করে। HWC এছাড়াও VSync-এর উপর নিয়ন্ত্রণ প্রদান করে এবং কোনো VSync ইভেন্ট ঘটলে SurfaceFlinger-কে অবহিত করার জন্য একটি কলব্যাকের ব্যবস্থা করে।
HIDL ইন্টারফেস
অ্যান্ড্রয়েড ৮.০ এবং এর পরবর্তী সংস্করণগুলো HWC এবং SurfaceFlinger-এর মধ্যে বাইন্ডারাইজড IPC-এর জন্য Composer HAL নামক একটি HIDL ইন্টারফেস ব্যবহার করে। Composer HAL পুরোনো hwcomposer2.h ইন্টারফেসটিকে প্রতিস্থাপন করে। যদি ভেন্ডররা HWC-এর একটি Composer HAL ইমপ্লিমেন্টেশন প্রদান করে, তবে Composer HAL সরাসরি SurfaceFlinger থেকে HIDL কল গ্রহণ করে। যদি ভেন্ডররা HWC-এর একটি পুরোনো ইমপ্লিমেন্টেশন প্রদান করে, তবে Composer HAL, hwcomposer2.h থেকে ফাংশন পয়েন্টার লোড করে এবং HIDL কলগুলোকে ফাংশন পয়েন্টার কলে ফরোয়ার্ড করে দেয়।
HWC একটি নির্দিষ্ট ডিসপ্লের বৈশিষ্ট্য নির্ধারণ করার; বিভিন্ন ডিসপ্লে কনফিগারেশন (যেমন 4k বা 1080p রেজোলিউশন) এবং কালার মোডের (যেমন নেটিভ কালার বা ট্রু sRGB) মধ্যে পরিবর্তন করার; এবং সমর্থিত হলে ডিসপ্লেটি চালু, বন্ধ বা লো-পাওয়ার মোডে নিয়ে যাওয়ার ফাংশন সরবরাহ করে।
ফাংশন পয়েন্টার
যদি ভেন্ডররা সরাসরি Composer HAL প্রয়োগ করে, তাহলে SurfaceFlinger HIDL IPC-এর মাধ্যমে এর ফাংশনগুলোকে কল করে। উদাহরণস্বরূপ, একটি লেয়ার তৈরি করতে, SurfaceFlinger Composer HAL-এ createLayer() কল করে।
যদি ভেন্ডররা hwcomposer2.h ইন্টারফেসটি ইমপ্লিমেন্ট করে, তাহলে Composer HAL, hwcomposer2.h ফাংশন পয়েন্টারগুলোকে কল করে। hwcomposer2.h কমেন্টগুলোতে, HWC ইন্টারফেসের ফাংশনগুলোকে এমন সব ছোট হাতের (lowerCamelCase) নামে উল্লেখ করা হয়, যেগুলো ইন্টারফেসে নেমড ফিল্ড হিসেবে বিদ্যমান নেই। প্রায় প্রতিটি ফাংশনই hwc2_device_t দ্বারা প্রদত্ত getFunction ব্যবহার করে একটি ফাংশন পয়েন্টারের অনুরোধ করার মাধ্যমে লোড করা হয়। উদাহরণস্বরূপ, createLayer ফাংশনটি হলো HWC2_PFN_CREATE_LAYER টাইপের একটি ফাংশন পয়েন্টার, যা getFunction এ HWC2_FUNCTION_CREATE_LAYER নামক এনুমারেটেড ভ্যালুটি পাস করা হলে রিটার্ন করা হয়।
কম্পোজার HAL ফাংশন এবং HWC ফাংশন পাসথ্রু ফাংশন সম্পর্কে বিস্তারিত তথ্যের জন্য, composer দেখুন। HWC ফাংশন পয়েন্টার সম্পর্কে বিস্তারিত তথ্যের জন্য, ` hwcomposer2.h দেখুন।
স্তর এবং প্রদর্শন হ্যান্ডেল
HWC দ্বারা তৈরি হ্যান্ডেলগুলির মাধ্যমে লেয়ার এবং ডিসপ্লেগুলি নিয়ন্ত্রণ করা হয়। এই হ্যান্ডেলগুলি SurfaceFlinger-এর কাছে অস্বচ্ছ।
যখন SurfaceFlinger একটি নতুন লেয়ার তৈরি করে, তখন এটি createLayer কল করে, যা ডিরেক্ট ইমপ্লিমেন্টেশনের জন্য Layer অথবা পাসথ্রু ইমপ্লিমেন্টেশনের জন্য hwc2_layer_t টাইপের ভ্যালু রিটার্ন করে। যখন SurfaceFlinger সেই লেয়ারের কোনো প্রপার্টি পরিবর্তন করে, তখন এটি hwc2_layer_t ভ্যালুটি এবং পরিবর্তনটি করার জন্য প্রয়োজনীয় অন্যান্য তথ্য উপযুক্ত মডিফিকেশন ফাংশনে পাস করে দেয়। hwc2_layer_t টাইপটি একটি পয়েন্টার বা একটি ইনডেক্স ধারণ করার জন্য যথেষ্ট বড়।
হটপ্লাগ করার মাধ্যমে ফিজিক্যাল ডিসপ্লে তৈরি করা হয়। যখন একটি ফিজিক্যাল ডিসপ্লে হটপ্লাগ করা হয়, তখন HWC একটি হ্যান্ডেল তৈরি করে এবং হটপ্লাগ কলব্যাকের মাধ্যমে হ্যান্ডেলটি SurfaceFlinger-এর কাছে পাঠায়। একটি ডিসপ্লের অনুরোধ করার জন্য SurfaceFlinger যখন createVirtualDisplay() কল করে, তখন ভার্চুয়াল ডিসপ্লে তৈরি হয়। যদি HWC ভার্চুয়াল ডিসপ্লে কম্পোজিশন সমর্থন করে, তবে এটি একটি হ্যান্ডেল ফেরত দেয়। এরপর, SurfaceFlinger ডিসপ্লেটির কম্পোজিশনের দায়িত্ব HWC-এর উপর অর্পণ করে। যদি HWC ভার্চুয়াল ডিসপ্লে কম্পোজিশন সমর্থন না করে, তবে SurfaceFlinger হ্যান্ডেলটি তৈরি করে এবং ডিসপ্লেটি কম্পোজিট করে।
গঠন ক্রিয়াকলাপ প্রদর্শন করুন
VSync চলাকালীন প্রতিবার একবার, কম্পোজিট করার জন্য নতুন কন্টেন্ট থাকলে SurfaceFlinger জেগে ওঠে। এই নতুন কন্টেন্ট হতে পারে অ্যাপ থেকে আসা নতুন ইমেজ বাফার অথবা এক বা একাধিক লেয়ারের প্রোপার্টিতে কোনো পরিবর্তন। যখন SurfaceFlinger জেগে ওঠে:
- লেনদেন থাকলে তা পরিচালনা করে।
- নতুন গ্রাফিক বাফার থাকলে, তা ল্যাচ করে।
- যদি ধাপ ১ বা ২-এর ফলে প্রদর্শিত বিষয়বস্তুতে কোনো পরিবর্তন আসে, তাহলে একটি নতুন বিন্যাস সম্পাদন করে।
একটি নতুন কম্পোজিশন সম্পাদন করার জন্য, সারফেসফ্লিঙ্গার প্রযোজ্য ক্ষেত্রে লেয়ার তৈরি ও ধ্বংস করে অথবা লেয়ারের অবস্থা পরিবর্তন করে। এটি setLayerBuffer বা setLayerColor মতো কল ব্যবহার করে লেয়ারগুলোকে তাদের বর্তমান বিষয়বস্তু দিয়ে আপডেটও করে। সমস্ত লেয়ার আপডেট হয়ে গেলে, সারফেসফ্লিঙ্গার validateDisplay কল করে, যা HWC-কে লেয়ারগুলোর অবস্থা পরীক্ষা করতে এবং কম্পোজিশন কীভাবে এগোবে তা নির্ধারণ করতে নির্দেশ দেয়। ডিফল্টরূপে, সারফেসফ্লিঙ্গার প্রতিটি লেয়ারকে এমনভাবে কনফিগার করার চেষ্টা করে যাতে লেয়ারটি HWC দ্বারা কম্পোজিট হয়; যদিও কিছু পরিস্থিতিতে, সারফেসফ্লিঙ্গার GPU ফলব্যাকের মাধ্যমে লেয়ারগুলো কম্পোজিট করে।
validateDisplay কল করার পর, SurfaceFlinger কম্পোজিশন সম্পাদনের আগে HWC কোনো লেয়ার কম্পোজিশন টাইপ পরিবর্তন করতে চায় কিনা তা দেখতে getChangedCompositionTypes কল করে। পরিবর্তনগুলো গ্রহণ করতে, SurfaceFlinger acceptDisplayChanges কল করে।
যদি কোনো লেয়ারকে সারফেসফ্লিঙ্গার কম্পোজিশনের জন্য চিহ্নিত করা থাকে, তাহলে সারফেসফ্লিঙ্গার সেগুলোকে টার্গেট বাফারে কম্পোজিট করে। এরপর সারফেসফ্লিঙ্গার বাফারটিকে ডিসপ্লেতে দেওয়ার জন্য setClientTarget কল করে, যাতে বাফারটি স্ক্রিনে প্রদর্শিত হতে পারে অথবা যেসব লেয়ারকে সারফেসফ্লিঙ্গার কম্পোজিশনের জন্য চিহ্নিত করা হয়নি, সেগুলোর সাথে আরও কম্পোজিট করা যায়। যদি কোনো লেয়ারকে সারফেসফ্লিঙ্গার কম্পোজিশনের জন্য চিহ্নিত করা না থাকে, তাহলে সারফেসফ্লিঙ্গার কম্পোজিশনের ধাপটি এড়িয়ে যায়।
অবশেষে, SurfaceFlinger, HWC-কে গঠন প্রক্রিয়াটি সম্পন্ন করতে এবং চূড়ান্ত ফলাফল প্রদর্শন করতে জানানোর জন্য presentDisplay কল করে।
একাধিক প্রদর্শন
অ্যান্ড্রয়েড ১০ একাধিক ফিজিক্যাল ডিসপ্লে সমর্থন করে। অ্যান্ড্রয়েড ৭.০ এবং তার পরবর্তী সংস্করণগুলিতে ব্যবহারের জন্য যখন কোনো HWC ইমপ্লিমেন্টেশন ডিজাইন করা হয়, তখন কিছু সীমাবদ্ধতা থাকে যা HWC সংজ্ঞায় উপস্থিত নেই:
- এটা ধরে নেওয়া হয় যে ঠিক একটিই অভ্যন্তরীণ ডিসপ্লে আছে। অভ্যন্তরীণ ডিসপ্লে হলো সেই ডিসপ্লে যা বুট করার সময় প্রাথমিক হটপ্লাগ রিপোর্ট করে। অভ্যন্তরীণ ডিসপ্লে একবার হটপ্লাগ করা হলে, তা আর সংযোগ বিচ্ছিন্ন করা যায় না।
- অভ্যন্তরীণ ডিসপ্লে ছাড়াও, ডিভাইসটির স্বাভাবিক কার্যক্রম চলাকালীন যেকোনো সংখ্যক বাহ্যিক ডিসপ্লে হটপ্লাগ করা যেতে পারে। ফ্রেমওয়ার্কটি ধরে নেয় যে প্রথম অভ্যন্তরীণ ডিসপ্লের পরের সমস্ত হটপ্লাগই বাহ্যিক ডিসপ্লে, তাই যদি আরও কোনো অভ্যন্তরীণ ডিসপ্লে যোগ করা হয়, তবে সেগুলোকে
Display.TYPE_BUILT_INএর পরিবর্তে ভুলভাবেDisplay.TYPE_HDMIহিসেবে শ্রেণীবদ্ধ করা হয়।
উপরে বর্ণিত সারফেসফ্লিঙ্গার অপারেশনগুলো যদিও প্রতিটি ডিসপ্লের জন্য আলাদাভাবে সম্পাদিত হয়, কিন্তু সমস্ত সক্রিয় ডিসপ্লের জন্য সেগুলো ক্রমানুসারে সম্পাদিত হয়, এমনকি যদি শুধুমাত্র একটি ডিসপ্লের বিষয়বস্তু আপডেট করা হয়।
উদাহরণস্বরূপ, যদি বাহ্যিক ডিসপ্লে আপডেট করা হয়, তাহলে ক্রমটি হলো:
// In Android 9 and lower: // Update state for internal display // Update state for external display validateDisplay(<internal display>) validateDisplay(<external display>) presentDisplay(<internal display>) presentDisplay(<external display>) // In Android 10 and higher: // Update state for internal display // Update state for external display validateInternal(<internal display>) presentInternal(<internal display>) validateExternal(<external display>) presentExternal(<external display>)
ভার্চুয়াল ডিসপ্লে কম্পোজিশন
ভার্চুয়াল ডিসপ্লে কম্পোজিশন এক্সটার্নাল ডিসপ্লে কম্পোজিশনের অনুরূপ। ভার্চুয়াল ডিসপ্লে কম্পোজিশন এবং ফিজিক্যাল ডিসপ্লে কম্পোজিশনের মধ্যে পার্থক্য হলো, ভার্চুয়াল ডিসপ্লে স্ক্রিনের পরিবর্তে একটি গ্র্যালক বাফারে আউটপুট পাঠায়। হার্ডওয়্যার কম্পোজার (HWC) আউটপুটটি একটি বাফারে লেখে, কমপ্লিশন ফেন্স প্রদান করে এবং বাফারটিকে কোনো কনজিউমারের (যেমন ভিডিও এনকোডার, জিপিইউ, সিপিইউ ইত্যাদি) কাছে পাঠিয়ে দেয়। ডিসপ্লে পাইপলাইন যদি মেমরিতে লেখে, তবে ভার্চুয়াল ডিসপ্লে 2D/ব্লিটার বা ওভারলে ব্যবহার করতে পারে।
মোড
SurfaceFlinger যখন validateDisplay() HWC মেথডটি কল করে, তখন প্রতিটি ফ্রেম তিনটি মোডের মধ্যে একটিতে থাকে:
- GLES — GPU সমস্ত লেয়ারকে কম্পোজিট করে এবং সরাসরি আউটপুট বাফারে লেখে। কম্পোজিশন প্রক্রিয়ায় HWC জড়িত থাকে না।
- মিক্সড — GPU কিছু লেয়ারকে ফ্রেমবাফারে কম্পোজিট করে এবং HWC ফ্রেমবাফার ও অবশিষ্ট লেয়ারগুলোকে কম্পোজিট করে সরাসরি আউটপুট বাফারে লেখে।
- HWC — HWC সমস্ত লেয়ারকে একত্রিত করে এবং সরাসরি আউটপুট বাফারে লেখে।
আউটপুট ফরম্যাট
ভার্চুয়াল ডিসপ্লে বাফার আউটপুট ফরম্যাটগুলো তাদের মোডের উপর নির্ভর করে:
- GLES মোড — EGL ড্রাইভার
dequeueBuffer()ফাংশনে আউটপুট বাফার ফরম্যাট নির্ধারণ করে, যা সাধারণতRGBA_8888হয়ে থাকে। কনজিউমারকে অবশ্যই ড্রাইভারের নির্ধারণ করা আউটপুট ফরম্যাটটি গ্রহণ করতে সক্ষম হতে হবে, নতুবা বাফারটি পড়া যাবে না। - MIXED এবং HWC মোড — যদি কনজিউমারের সিপিইউ অ্যাক্সেসের প্রয়োজন হয়, তবে কনজিউমার নিজেই ফরম্যাটটি সেট করে। অন্যথায়, ফরম্যাটটি
IMPLEMENTATION_DEFINEDহয় এবং Gralloc ব্যবহারের ফ্ল্যাগগুলোর উপর ভিত্তি করে সেরা ফরম্যাটটি সেট করে। উদাহরণস্বরূপ, যদি কনজিউমারটি একটি ভিডিও এনকোডার হয় এবং HWC দক্ষতার সাথে ফরম্যাটটি লিখতে পারে, তাহলে Gralloc একটি YCbCr ফরম্যাট সেট করে।
সিঙ্ক্রোনাইজেশন বেড়া
সিনক্রোনাইজেশন (সিঙ্ক) ফেন্স অ্যান্ড্রয়েড গ্রাফিক্স সিস্টেমের একটি অত্যন্ত গুরুত্বপূর্ণ দিক। ফেন্স সিপিইউ-এর কাজকে একই সাথে চলমান জিপিইউ-এর কাজ থেকে স্বাধীনভাবে চলতে দেয় এবং শুধুমাত্র প্রকৃত নির্ভরশীলতার ক্ষেত্রেই কাজকে বাধা দেয়।
উদাহরণস্বরূপ, যখন কোনো অ্যাপ GPU-তে তৈরি হওয়া একটি বাফার সাবমিট করে, তখন এটি একটি সিঙ্ক ফেন্স অবজেক্টও সাবমিট করে। এই ফেন্সটি সংকেত দেয় যে GPU কখন বাফারটিতে লেখা শেষ করেছে।
HWC-এর নিয়ম অনুযায়ী, বাফার প্রদর্শিত হওয়ার আগে GPU-কে অবশ্যই বাফার লেখা শেষ করতে হয়। সিঙ্ক ফেন্সগুলো বাফারের সাথে গ্রাফিক্স পাইপলাইনের মধ্য দিয়ে যায় এবং বাফার লেখা হয়ে গেলে সংকেত দেয়। একটি বাফার প্রদর্শিত হওয়ার আগে, HWC পরীক্ষা করে দেখে যে সিঙ্ক ফেন্সটি সংকেত দিয়েছে কিনা, এবং যদি দিয়ে থাকে, তবে এটি বাফারটি প্রদর্শন করে।
সিঙ্ক ফেন্স সম্পর্কে আরও তথ্যের জন্য হার্ডওয়্যার কম্পোজার ইন্টিগ্রেশন দেখুন।