ফ্রেম পেসিং লাইব্রেরি অ্যান্ড্রয়েড গেম ডেভেলপমেন্ট কিটের অংশ।
অ্যান্ড্রয়েড ফ্রেম পেসিং লাইব্রেরি, যা সোয়াপি নামেও পরিচিত, এটি AGDK লাইব্রেরির অংশ। এটি ওপেনজিএল এবং ভলকান গেমগুলিকে অ্যান্ড্রয়েডে মসৃণ রেন্ডারিং এবং সঠিক ফ্রেম পেসিং অর্জনে সহায়তা করে। এই নথিটি ফ্রেম পেসিং সংজ্ঞায়িত করে, এমন পরিস্থিতিতে বর্ণনা করে যেখানে ফ্রেম পেসিং প্রয়োজন, এবং লাইব্রেরি কীভাবে এই পরিস্থিতিগুলিকে মোকাবেলা করে তা দেখায়। আপনি যদি আপনার গেমে ফ্রেম পেসিং বাস্তবায়নে সরাসরি ঝাঁপ দিতে চান, তাহলে পরবর্তী ধাপটি দেখুন।
পটভূমি
ফ্রেম পেসিং হল একটি OS এর ডিসপ্লে সাবসিস্টেম এবং অন্তর্নিহিত ডিসপ্লে হার্ডওয়্যারের সাথে একটি গেমের লজিক এবং রেন্ডারিং লুপের সিঙ্ক্রোনাইজেশন। অ্যান্ড্রয়েড ডিসপ্লে সাবসিস্টেমটি ভিজ্যুয়াল আর্টিফ্যাক্টগুলি এড়ানোর জন্য ডিজাইন করা হয়েছে (যা ছিঁড়ে যাওয়া নামে পরিচিত) যা ঘটতে পারে যখন ডিসপ্লে হার্ডওয়্যার একটি আপডেটের মাধ্যমে আংশিকভাবে একটি নতুন ফ্রেমে স্যুইচ করে। এই আর্টিফ্যাক্টগুলি এড়াতে, ডিসপ্লে সাবসিস্টেম নিম্নলিখিতগুলি করে:
- অভ্যন্তরীণভাবে অতীতের ফ্রেমগুলিকে বাফার করে৷
- দেরী ফ্রেম জমা সনাক্ত করে
- দেরী ফ্রেম সনাক্ত করা হলে অতীত ফ্রেমের প্রদর্শনের পুনরাবৃত্তি করে
একটি গেম ডিসপ্লে সাবসিস্টেমের মধ্যে কম্পোজিটর SurfaceFlinger কে জানায় যে এটি একটি ফ্রেমের জন্য প্রয়োজনীয় সমস্ত ড্র কল জমা দিয়েছে ( eglSwapBuffers
বা vkQueuePresentKHR
কল করে)। সারফেসফ্লিংগার একটি ল্যাচ ব্যবহার করে ডিসপ্লে হার্ডওয়্যারে একটি ফ্রেমের উপলব্ধতার সংকেত দেয়। ডিসপ্লে হার্ডওয়্যার তারপর প্রদত্ত ফ্রেম দেখায়। ডিসপ্লে হার্ডওয়্যার একটি ধ্রুবক হারে টিক করে, উদাহরণস্বরূপ 60 Hz, এবং যদি হার্ডওয়্যারের প্রয়োজনে কোন নতুন ফ্রেম না থাকে, হার্ডওয়্যারটি আবার আগের ফ্রেমটি প্রদর্শন করে।
একটি গেম রেন্ডার লুপ নেটিভ ডিসপ্লে হার্ডওয়্যারের চেয়ে ভিন্ন হারে রেন্ডার করার সময় অসঙ্গতিপূর্ণ ফ্রেমের সময়গুলি প্রায়ই ঘটে৷ 30 FPS-এ চলমান একটি গেম যদি এমন একটি ডিভাইসে রেন্ডার করার চেষ্টা করে যা স্থানীয়ভাবে 60 FPS সমর্থন করে, গেম রেন্ডার লুপ বুঝতে পারে না যে একটি পুনরাবৃত্তি ফ্রেম একটি অতিরিক্ত 16 মিলিসেকেন্ডের জন্য স্ক্রিনে থেকে যায়। এই সংযোগ বিচ্ছিন্ন সাধারণত ফ্রেমের সময়ে যথেষ্ট অসঙ্গতি তৈরি করে, যেমন: 49 মিলিসেকেন্ড, 16 মিলিসেকেন্ড, 33 মিলিসেকেন্ড। অত্যধিক জটিল দৃশ্যগুলি এই সমস্যাটিকে আরও জটিল করে তোলে, কারণ এর ফলে ফ্রেমগুলি মিস হয়ে যায়।
অ-অনুকূল সমাধান
ফ্রেম পেসিংয়ের জন্য নিম্নলিখিত সমাধানগুলি অতীতে গেমগুলির দ্বারা নিযুক্ত করা হয়েছে এবং সাধারণত অসঙ্গত ফ্রেমের সময় এবং ইনপুট লেটেন্সি বৃদ্ধির ফলে।
রেন্ডারিং API যত তাড়াতাড়ি অনুমতি দেয় তত তাড়াতাড়ি ফ্রেম জমা দিন
এই পদ্ধতিটি একটি গেমকে পরিবর্তনশীল SurfaceFlinger কার্যকলাপের সাথে সংযুক্ত করে এবং লেটেন্সির একটি অতিরিক্ত ফ্রেম প্রবর্তন করে। ডিসপ্লে পাইপলাইনে ফ্রেমের একটি সারি থাকে, সাধারণত 2 আকারের, যা পূর্ণ হয় যদি গেমটি খুব দ্রুত ফ্রেমগুলি উপস্থাপন করার চেষ্টা করে। সারিতে আর কোনো জায়গা না থাকায়, গেম লুপ (বা অন্তত রেন্ডারিং থ্রেড) একটি OpenGL বা Vulkan কল দ্বারা ব্লক করা হয়েছে। গেমটি তখন ডিসপ্লে হার্ডওয়্যারটি একটি ফ্রেম দেখানোর জন্য অপেক্ষা করতে বাধ্য হয় এবং এই ব্যাক-প্রেশার দুটি উপাদানকে সিঙ্ক্রোনাইজ করে। এই পরিস্থিতি বাফার-স্টাফিং বা সারি-স্টাফিং হিসাবে পরিচিত। রেন্ডারার প্রক্রিয়া কি ঘটছে তা বুঝতে পারে না, তাই ফ্রেমরেটের অসঙ্গতি আরও খারাপ হয়। যদি গেমটি ফ্রেমের আগে ইনপুটের নমুনা দেয়, ইনপুট লেটেন্সি আরও খারাপ হয়।
নিজে থেকেই অ্যান্ড্রয়েড কোরিওগ্রাফার ব্যবহার করুন
গেমগুলিও সিঙ্ক্রোনাইজেশনের জন্য অ্যান্ড্রয়েড কোরিওগ্রাফার ব্যবহার করে। এই উপাদানটি, API 16 থেকে Java এবং API 24 থেকে C++ এ উপলব্ধ, ডিসপ্লে সাবসিস্টেমের মতো একই ফ্রিকোয়েন্সিতে নিয়মিত টিক সরবরাহ করে। প্রকৃত হার্ডওয়্যার VSYNC এর তুলনায় এই টিকটি কখন বিতরণ করা হয় সে সম্পর্কে এখনও সূক্ষ্মতা রয়েছে এবং এই অফসেটগুলি ডিভাইস অনুসারে পরিবর্তিত হয়। দীর্ঘ ফ্রেমের জন্য বাফার-স্টাফিং এখনও ঘটতে পারে।
ফ্রেম পেসিং লাইব্রেরির সুবিধা
ফ্রেম পেসিং লাইব্রেরি সিঙ্ক্রোনাইজেশনের জন্য অ্যান্ড্রয়েড কোরিওগ্রাফার ব্যবহার করে এবং আপনার জন্য টিক ডেলিভারির পরিবর্তনশীলতা নিয়ে কাজ করে। ফ্রেমগুলি সঠিক সময়ে উপস্থাপিত হয়েছে তা নিশ্চিত করতে এটি উপস্থাপনা টাইমস্ট্যাম্প ব্যবহার করে এবং বাফার স্টাফিং এড়াতে বেড়া সিঙ্ক করে। লাইব্রেরি NDK কোরিওগ্রাফার ব্যবহার করে যদি এটি উপলব্ধ থাকে এবং এটি না থাকলে জাভা কোরিওগ্রাফারের কাছে ফিরে আসে।
লাইব্রেরি একাধিক রিফ্রেশ রেট পরিচালনা করে যদি সেগুলি ডিভাইস দ্বারা সমর্থিত হয়, যা একটি ফ্রেম উপস্থাপনে একটি গেমকে আরও নমনীয়তা দেয়৷ উদাহরণস্বরূপ, 60 Hz রিফ্রেশ রেট এবং 90 Hz সমর্থন করে এমন একটি ডিভাইসের জন্য, যে গেমটি প্রতি সেকেন্ডে 60 ফ্রেম তৈরি করতে পারে না তা মসৃণ থাকার জন্য 30 FPS এর পরিবর্তে 45 FPS-এ নেমে যেতে পারে। লাইব্রেরি প্রত্যাশিত গেম ফ্রেম রেট সনাক্ত করে এবং সেই অনুযায়ী ফ্রেম উপস্থাপনার সময় স্বয়ংক্রিয়ভাবে সামঞ্জস্য করে। ফ্রেম পেসিং লাইব্রেরি ব্যাটারির আয়ুও উন্নত করে কারণ এটি অপ্রয়োজনীয় ডিসপ্লে আপডেট এড়িয়ে যায়। উদাহরণস্বরূপ, যদি একটি গেম 60 FPS এ রেন্ডারিং হয় কিন্তু ডিসপ্লে 120 Hz এ আপডেট হয়, তাহলে প্রতিটি ফ্রেমের জন্য স্ক্রীনটি দুবার আপডেট করা হয়। ফ্রেম পেসিং লাইব্রেরি টার্গেট ফ্রেম হারের সবচেয়ে কাছাকাছি ডিভাইস দ্বারা সমর্থিত মানটিতে রিফ্রেশ রেট সেট করে এটি এড়ায়।
এটা কিভাবে কাজ করে
সঠিক ফ্রেম পেসিং অর্জনের জন্য ফ্রেম পেসিং লাইব্রেরি দীর্ঘ এবং ছোট গেম ফ্রেমের সাথে কীভাবে ডিল করে তা নিম্নলিখিত বিভাগগুলি দেখায়।
30 Hz এ সঠিক ফ্রেম পেসিং
60 Hz ডিভাইসে 30 Hz-এ রেন্ডার করার সময়, Android-এর আদর্শ পরিস্থিতি চিত্র 1-এ দেখানো হয়েছে। সারফেসফ্লিংগার যদি উপস্থিত থাকে তবে নতুন গ্রাফিক বাফার তৈরি করে (ডায়াগ্রামে NB নির্দেশ করে যে "কোন বাফার নেই" উপস্থিত এবং আগেরটির পুনরাবৃত্তি হয়)।
চিত্র 1. একটি 60 Hz ডিভাইসে 30 Hz এ আদর্শ ফ্রেম পেসিং
ছোট খেলার ফ্রেম তোতলাতে বাড়ে
বেশিরভাগ আধুনিক ডিভাইসে, গেম ইঞ্জিনগুলি প্ল্যাটফর্ম কোরিওগ্রাফারের উপর নির্ভর করে যা ফ্রেম জমা দেওয়ার জন্য টিক সরবরাহ করে। যাইহোক, ছোট ফ্রেমের কারণে দুর্বল ফ্রেমের গতির সম্ভাবনা এখনও রয়েছে, যেমনটি চিত্র 2-এ দেখা গেছে। ছোট ফ্রেমের পরে লম্বা ফ্রেমগুলিকে খেলোয়াড় তোতলান বলে মনে করে।
চিত্র 2. সংক্ষিপ্ত গেম ফ্রেম সি ফ্রেম B শুধুমাত্র একটি ফ্রেম উপস্থাপন করে, একাধিক C ফ্রেম অনুসরণ করে
ফ্রেম পেসিং লাইব্রেরি উপস্থাপনা টাইমস্ট্যাম্প ব্যবহার করে এটি সমাধান করে। লাইব্রেরি প্রেজেন্টেশন টাইমস্ট্যাম্প এক্সটেনশনগুলি EGL_ANDROID_presentation_time
এবং VK_GOOGLE_display_timing
ব্যবহার করে যাতে ফ্রেমগুলি তাড়াতাড়ি উপস্থাপিত না হয়, যেমনটি চিত্র 3-এ দেখা যায়।
চিত্র 3. একটি মসৃণ প্রদর্শনের জন্য গেম ফ্রেম বি দুইবার উপস্থাপন করা হয়েছে
লম্বা ফ্রেম তোতলামি এবং লেটেন্সি বাড়ে
যখন ডিসপ্লে ওয়ার্কলোড অ্যাপ্লিকেশন ওয়ার্কলোডের চেয়ে বেশি সময় নেয়, তখন একটি সারিতে অতিরিক্ত ফ্রেম যোগ করা হয়। এটি আবারও তোতলামির দিকে নিয়ে যায় এবং বাফার-স্টাফিংয়ের কারণে অতিরিক্ত লেটেন্সি ফ্রেমের দিকে নিয়ে যেতে পারে (চিত্র 4 দেখুন)। লাইব্রেরি তোতলামি এবং লেটেন্সির অতিরিক্ত ফ্রেম উভয়ই সরিয়ে দেয়।
চিত্র 4. লম্বা ফ্রেম B 2টি ফ্রেমের জন্য ভুল পেসিং দেয়—A এবং B
লাইব্রেরি এটির সমাধান করে সিঙ্ক ফেন্স ( EGL_KHR_fence_sync
এবং VkFence
) ব্যবহার করে অ্যাপ্লিকেশনে ওয়েট ইনজেকশন করার জন্য যা ডিসপ্লে পাইপলাইনকে ধরার অনুমতি দেয়, পিছনের চাপ তৈরি করতে না দিয়ে। ফ্রেম A এখনও একটি অতিরিক্ত ফ্রেম উপস্থাপন করে, কিন্তু ফ্রেম B এখন সঠিকভাবে উপস্থাপন করে, যেমন চিত্র 5 এ দেখা গেছে।
চিত্র 5. ফ্রেম C এবং D উপস্থাপনের জন্য অপেক্ষা করছে
সমর্থিত অপারেটিং মোড
আপনি নিম্নলিখিত তিনটি মোডের একটিতে কাজ করার জন্য ফ্রেম পেসিং লাইব্রেরি কনফিগার করতে পারেন:
- অটো মোড বন্ধ + পাইপলাইন
- অটো মোড অন + পাইপলাইন
- অটো মোড অন + অটো পাইপলাইন মোড (পাইপলাইন/নন-পাইপলাইন)
প্রস্তাবিত মোড
আপনি স্বয়ংক্রিয়-মোড এবং পাইপলাইন মোডগুলির সাথে পরীক্ষা করতে পারেন, তবে আপনি সেগুলি বন্ধ করে শুরু করুন এবং Swappy শুরু করার পরে নিম্নলিখিতগুলি অন্তর্ভুক্ত করুন:
swappyAutoSwapInterval(false);
swappyAutoPipelineMode(false);
swappyEnableStats(false);
swappySwapIntervalNS(1000000000L/yourPreferredFrameRateInHz);
পাইপলাইন মোড
ইঞ্জিন ওয়ার্কলোড সমন্বয় করতে, লাইব্রেরি সাধারণত একটি পাইপলাইনিং মডেল ব্যবহার করে যা VSYNC সীমানা জুড়ে CPU এবং GPU ওয়ার্কলোডগুলিকে আলাদা করে।
চিত্র 6. পাইপলাইন মোড
নন-পাইপলাইন মোড
সাধারণভাবে, এই পদ্ধতির ফলে কম, আরও অনুমানযোগ্য ইনপুট-স্ক্রিন লেটেন্সি হয়। যে ক্ষেত্রে একটি গেমের ফ্রেমের সময় খুব কম থাকে, সেক্ষেত্রে CPU এবং GPU উভয় কাজের লোডই একক অদলবদল ব্যবধানে ফিট হতে পারে। এই ক্ষেত্রে, একটি নন-পাইপলাইন পদ্ধতি আসলে কম ইনপুট-স্ক্রীন লেটেন্সি প্রদান করবে।
চিত্র 7. নন-পাইপলাইন মোড
অটো মোড
বেশিরভাগ গেমই জানে না কিভাবে অদলবদল ব্যবধান বেছে নিতে হয়, যে সময়কালের জন্য প্রতিটি ফ্রেম উপস্থাপন করা হয় (উদাহরণস্বরূপ, 30 Hz এর জন্য 33.3 ms)। কিছু ডিভাইসে, একটি গেম 60 FPS এ রেন্ডার করতে পারে যখন অন্যটিতে এটিকে কম মানতে নামতে হতে পারে। অটো মোড নিম্নলিখিত কাজ করার জন্য CPU এবং GPU সময় পরিমাপ করে:
- স্বয়ংক্রিয়ভাবে অদলবদল ব্যবধান নির্বাচন করুন : যে গেমগুলি কিছু দৃশ্যে 30 Hz এবং অন্যগুলিতে 60 Hz প্রদান করে সেগুলি লাইব্রেরীকে এই ব্যবধানটি গতিশীলভাবে সামঞ্জস্য করতে দেয়৷
- অতি-দ্রুত ফ্রেমের জন্য পাইপলাইন নিষ্ক্রিয় করুন : সব ক্ষেত্রেই সর্বোত্তম ইনপুট-স্ক্রিন লেটেন্সি প্রদান করে।
একাধিক রিফ্রেশ হার
একাধিক রিফ্রেশ রেট সমর্থন করে এমন ডিভাইসগুলি মসৃণ দেখায় এমন একটি অদলবদল ব্যবধান বেছে নেওয়ার ক্ষেত্রে উচ্চতর নমনীয়তা প্রদান করে:
- 60 Hz ডিভাইসে : 60 FPS / 30 FPS / 20FPS
- 60 Hz + 90 Hz ডিভাইসে : 90 FPS / 60 FPS / 45 FPS / 30 FPS
- 60 Hz + 90 Hz + 120 Hz ডিভাইসে : 120 FPS / 90 FPS / 60 FPS / 45 FPS / 40 FPS / 30 FPS
লাইব্রেরি রিফ্রেশ রেট বেছে নেয় যা একটি গেমের ফ্রেমের প্রকৃত রেন্ডারিং সময়কালের সাথে সবচেয়ে ভাল মেলে, একটি ভাল ভিজ্যুয়াল অভিজ্ঞতা দেয়।
একাধিক রিফ্রেশ রেট ফ্রেম পেসিং সম্পর্কে আরও তথ্যের জন্য, Android ব্লগ পোস্টে উচ্চ রিফ্রেশ রেট রেন্ডারিং দেখুন৷
ফ্রেম পরিসংখ্যান
ফ্রেম পেসিং লাইব্রেরি ডিবাগিং এবং প্রোফাইলিং উদ্দেশ্যে নিম্নলিখিত পরিসংখ্যান প্রদান করে:
- রেন্ডারিং সম্পূর্ণ হওয়ার পরে কম্পোজিটর সারিতে অপেক্ষা করা একটি ফ্রেমকে স্ক্রিনের সংখ্যার একটি হিস্টোগ্রাম রিফ্রেশ করে।
- অনুরোধ করা উপস্থাপনা সময় এবং প্রকৃত বর্তমান সময়ের মধ্যে পাস করা স্ক্রীন রিফ্রেশের সংখ্যার একটি হিস্টোগ্রাম।
- পরপর দুটি ফ্রেমের মধ্যে স্ক্রীন রিফ্রেশের সংখ্যার একটি হিস্টোগ্রাম।
- এই ফ্রেমের জন্য CPU কাজ শুরু এবং প্রকৃত বর্তমান সময়ের মধ্যে স্ক্রীন রিফ্রেশের সংখ্যার একটি হিস্টোগ্রাম।
পরবর্তী ধাপ
আপনার গেমে অ্যান্ড্রয়েড ফ্রেম পেসিং লাইব্রেরি সংহত করতে নিম্নলিখিত নির্দেশিকাগুলির মধ্যে একটি দেখুন:
- আপনার OpenGL রেন্ডারারে অ্যান্ড্রয়েড ফ্রেম পেসিং একীভূত করুন
- আপনার ভলকান রেন্ডারারে অ্যান্ড্রয়েড ফ্রেম পেসিং সংহত করুন