সিঙ্ক্রোনাইজেশন ফ্রেমওয়ার্ক

সিঙ্ক্রোনাইজেশন ফ্রেমওয়ার্কটি অ্যান্ড্রয়েড গ্রাফিক্স সিস্টেমের বিভিন্ন অ্যাসিঙ্ক্রোনাস অপারেশনের মধ্যে নির্ভরতা স্পষ্টভাবে বর্ণনা করে। ফ্রেমওয়ার্কটি এমন একটি API প্রদান করে যা উপাদানগুলিকে বাফারগুলি কখন মুক্তি পাবে তা নির্দেশ করতে সক্ষম করে। ফ্রেমওয়ার্কটি কার্নেল থেকে ইউজারস্পেসে ড্রাইভারদের মধ্যে এবং ইউজারস্পেস প্রক্রিয়াগুলির মধ্যে সিঙ্ক্রোনাইজেশন প্রিমিটিভগুলি প্রেরণ করার অনুমতি দেয়।

উদাহরণস্বরূপ, একটি অ্যাপ্লিকেশন GPU-তে কাজ করার জন্য সারিবদ্ধভাবে কাজ করতে পারে। GPU সেই ছবিটি আঁকতে শুরু করে। যদিও ছবিটি এখনও মেমোরিতে আঁকতে পারেনি, বাফার পয়েন্টারটি উইন্ডো কম্পোজিটরে পাঠানো হয় এবং একটি বেড়া দিয়ে নির্দেশ করে যে GPU কাজ কখন শেষ হবে। উইন্ডো কম্পোজিটর সময়ের আগে প্রক্রিয়াকরণ শুরু করে এবং কাজটি ডিসপ্লে কন্ট্রোলারের কাছে হস্তান্তর করে। একইভাবে, CPU কাজ সময়ের আগে সম্পন্ন হয়। GPU শেষ হয়ে গেলে, ডিসপ্লে কন্ট্রোলার অবিলম্বে ছবিটি প্রদর্শন করে।

সিঙ্ক্রোনাইজেশন ফ্রেমওয়ার্কটি বাস্তবায়নকারীদের তাদের নিজস্ব হার্ডওয়্যার উপাদানগুলিতে সিঙ্ক্রোনাইজেশন রিসোর্স ব্যবহার করতে দেয়। অবশেষে, ফ্রেমওয়ার্কটি ডিবাগিংয়ে সহায়তা করার জন্য গ্রাফিক্স পাইপলাইনে দৃশ্যমানতা প্রদান করে।

স্পষ্ট সিঙ্ক্রোনাইজেশন

এক্সপ্লিসিট সিঙ্ক্রোনাইজেশন গ্রাফিক্স বাফারের উৎপাদক এবং গ্রাহকদের বাফার ব্যবহার শেষ হওয়ার পরে সিগন্যাল পাঠাতে সক্ষম করে। এক্সপ্লিসিট সিঙ্ক্রোনাইজেশন কার্নেল-স্পেসে বাস্তবায়িত হয়।

স্পষ্ট সিঙ্ক্রোনাইজেশনের সুবিধাগুলির মধ্যে রয়েছে:

  • ডিভাইসগুলির মধ্যে আচরণের তারতম্য কম
  • উন্নত ডিবাগিং সমর্থন
  • উন্নত পরীক্ষার মেট্রিক্স

সিঙ্ক ফ্রেমওয়ার্কে তিনটি অবজেক্ট টাইপ আছে:

  • sync_timeline
  • sync_pt
  • sync_fence

সিঙ্ক_টাইমলাইন

sync_timeline হল একটি একঘেয়েভাবে বর্ধিত টাইমলাইন যা বিক্রেতাদের প্রতিটি ড্রাইভার ইনস্ট্যান্সের জন্য বাস্তবায়ন করা উচিত, যেমন একটি GL প্রসঙ্গ, ডিসপ্লে কন্ট্রোলার, অথবা 2D ব্লিটার। sync_timeline একটি নির্দিষ্ট হার্ডওয়্যারের জন্য কার্নেলে জমা দেওয়া কাজ গণনা করে। sync_timeline ক্রিয়াকলাপের ক্রম নিশ্চিত করে এবং হার্ডওয়্যার-নির্দিষ্ট বাস্তবায়ন সক্ষম করে।

sync_timeline বাস্তবায়নের সময় এই নির্দেশিকাগুলি অনুসরণ করুন:

  • ডিবাগিং সহজ করার জন্য সমস্ত ড্রাইভার, টাইমলাইন এবং বেড়ার জন্য দরকারী নাম প্রদান করুন।
  • ডিবাগিং আউটপুটকে আরও পঠনযোগ্য করে তুলতে টাইমলাইনে timeline_value_str এবং pt_value_str অপারেটরগুলি প্রয়োগ করুন।
  • প্রয়োজনে GL লাইব্রেরির মতো ইউজারস্পেস লাইব্রেরিগুলিকে ব্যক্তিগত টাইমলাইন ডেটাতে অ্যাক্সেস দেওয়ার জন্য fill driver_data প্রয়োগ করুন। data_driver বিক্রেতাদের অপরিবর্তনীয় sync_fence এবং sync_pts সম্পর্কে তথ্য প্রেরণ করতে দেয় যাতে তাদের উপর ভিত্তি করে কমান্ড লাইন তৈরি করা যায়।
  • ইউজারস্পেসকে স্পষ্টভাবে একটি বেড়া তৈরি বা সংকেত দেওয়ার অনুমতি দেবেন না। স্পষ্টভাবে সংকেত/বেড়া তৈরি করার ফলে পরিষেবা অস্বীকারের আক্রমণ হয় যা পাইপলাইনের কার্যকারিতা বন্ধ করে দেয়।
  • sync_timeline , sync_pt , অথবা sync_fence এলিমেন্টগুলি স্পষ্টভাবে অ্যাক্সেস করবেন না। API সমস্ত প্রয়োজনীয় ফাংশন প্রদান করে।

সিঙ্ক_পয়েন্ট

sync_pt হল sync_timeline এর একটি একক মান বা বিন্দু। একটি বিন্দুর তিনটি অবস্থা থাকে: সক্রিয়, সংকেতযুক্ত এবং ত্রুটি। বিন্দুগুলি সক্রিয় অবস্থায় শুরু হয় এবং সংকেতযুক্ত বা ত্রুটি অবস্থায় রূপান্তরিত হয়। উদাহরণস্বরূপ, যখন কোনও চিত্র গ্রাহকের আর বাফারের প্রয়োজন হয় না, তখন একটি sync_pt সংকেতযুক্ত হয় যাতে একজন চিত্র প্রযোজক জানেন যে বাফারে আবার লেখা ঠিক আছে।

সিঙ্ক_ফেন্স

sync_fence হল sync_pt মানের একটি সংগ্রহ যার প্রায়শই বিভিন্ন sync_timeline প্যারেন্ট থাকে (যেমন ডিসপ্লে কন্ট্রোলার এবং GPU এর জন্য)। sync_fence , sync_pt , এবং sync_timeline হল প্রধান আদিম উপাদান যা ড্রাইভার এবং ইউজারস্পেস তাদের নির্ভরতা যোগাযোগের জন্য ব্যবহার করে। যখন একটি বেড়া সিগন্যাল হয়ে যায়, তখন বেড়ার আগে জারি করা সমস্ত কমান্ড সম্পূর্ণ হয় কারণ কার্নেল ড্রাইভার বা হার্ডওয়্যার ব্লক ক্রমানুসারে কমান্ডগুলি কার্যকর করে।

সিঙ্ক ফ্রেমওয়ার্ক একাধিক গ্রাহক বা প্রযোজককে একটি বাফার ব্যবহার শেষ করার পরে সংকেত প্রেরণ করতে দেয়, একটি ফাংশন প্যারামিটারের সাথে নির্ভরতা তথ্য যোগাযোগ করে। বেড়াগুলি একটি ফাইল বর্ণনাকারী দ্বারা সমর্থিত এবং কার্নেল স্পেস থেকে ইউজারস্পেসে প্রেরণ করা হয়। উদাহরণস্বরূপ, একটি বেড়াতে দুটি sync_pt মান থাকতে পারে যা দুটি পৃথক চিত্র গ্রাহকের একটি বাফার পড়া শেষ হওয়ার সময় বোঝায়। যখন বেড়াটি সংকেত দেওয়া হয়, তখন চিত্র নির্মাতারা জানেন যে উভয় গ্রাহকই ব্যবহার শেষ করেছেন।

sync_pt মানের মতো বেড়াগুলি সক্রিয় শুরু হয় এবং তাদের পয়েন্টগুলির অবস্থার উপর ভিত্তি করে অবস্থা পরিবর্তন করে। যদি সমস্ত sync_pt মান সিগন্যাল হয়ে যায়, তাহলে sync_fence সিগন্যাল হয়ে যায়। যদি একটি sync_pt ত্রুটি অবস্থায় পড়ে, তাহলে পুরো sync_fence একটি ত্রুটি অবস্থা থাকে।

বেড়া তৈরি হওয়ার পর একটি sync_fence এর সদস্যপদ অপরিবর্তনীয়। একটি বেড়াতে একাধিক বিন্দু পেতে, একটি মার্জ করা হয় যেখানে দুটি স্বতন্ত্র বেড়া থেকে বিন্দু তৃতীয় বেড়াতে যোগ করা হয়। যদি এই বিন্দুগুলির মধ্যে একটি মূল বেড়াতে সংকেতযুক্ত থাকে এবং অন্যটি না থাকে, তাহলে তৃতীয় বেড়াটিও সংকেতযুক্ত অবস্থায় থাকবে না।

স্পষ্ট সিঙ্ক্রোনাইজেশন বাস্তবায়নের জন্য, নিম্নলিখিতগুলি প্রদান করুন:

  • একটি কার্নেল-স্পেস সাবসিস্টেম যা একটি নির্দিষ্ট হার্ডওয়্যার ড্রাইভারের জন্য সিঙ্ক ফ্রেমওয়ার্ক বাস্তবায়ন করে। যেসব ড্রাইভারকে ফেন্স-সচেতন থাকতে হয় তারা সাধারণত হার্ডওয়্যার কম্পোজার (HWC) অ্যাক্সেস করে বা এর সাথে যোগাযোগ করে। মূল ফাইলগুলির মধ্যে রয়েছে:
    • মূল বাস্তবায়ন:
      • kernel/common/include/linux/sync.h
      • kernel/common/drivers/base/sync.c
    • kernel/common/Documentation/sync.txt এ ডকুমেন্টেশন
    • platform/system/core/libsync কার্নেল স্পেসের সাথে যোগাযোগের জন্য লাইব্রেরি
  • হার্ডওয়্যার অ্যাবস্ট্রাকশন লেয়ার (HAL) এর validateDisplay() এবং presentDisplay() ফাংশনের প্যারামিটার হিসেবে বিক্রেতাকে উপযুক্ত সিঙ্ক্রোনাইজেশন বেড়া প্রদান করতে হবে।
  • গ্রাফিক্স ড্রাইভারে দুটি বেড়া-সম্পর্কিত GL এক্সটেনশন ( EGL_ANDROID_native_fence_sync এবং EGL_ANDROID_wait_sync ) এবং বেড়া সমর্থন।

কেস স্টাডি: একটি ডিসপ্লে ড্রাইভার বাস্তবায়ন করুন

সিঙ্ক্রোনাইজেশন ফাংশন সাপোর্ট করে এমন API ব্যবহার করতে, একটি ডিসপ্লে ড্রাইভার তৈরি করুন যার একটি ডিসপ্লে বাফার ফাংশন থাকবে। সিঙ্ক্রোনাইজেশন ফ্রেমওয়ার্ক বিদ্যমান থাকার আগে, এই ফাংশনটি dma-buf অবজেক্টগুলি গ্রহণ করত, সেই বাফারগুলিকে ডিসপ্লেতে রাখত এবং বাফারটি দৃশ্যমান থাকাকালীন ব্লক করত। উদাহরণস্বরূপ:

/*
 * assumes buffer is ready to be displayed.  returns when buffer is no longer on
 * screen.
 */
void display_buffer(struct dma_buf *buffer);

সিঙ্ক্রোনাইজেশন ফ্রেমওয়ার্কের ক্ষেত্রে, display_buffer ফাংশনটি আরও জটিল। ডিসপ্লেতে বাফার রাখার সময়, বাফারটি একটি বেড়ার সাথে যুক্ত থাকে যা নির্দেশ করে যে বাফারটি কখন প্রস্তুত হবে। বেড়া পরিষ্কার হওয়ার পরে আপনি লাইনে দাঁড়াতে পারেন এবং কাজ শুরু করতে পারেন।

বেড়া পরিষ্কার হওয়ার পরে সারিবদ্ধভাবে কাজ শুরু করলে কোনও বাধা থাকে না। আপনি তাৎক্ষণিকভাবে আপনার নিজস্ব বেড়াটি ফিরিয়ে দেন, যা বাফারটি কখন ডিসপ্লে থেকে বন্ধ থাকবে তা নির্দেশ করে। আপনি যখন বাফারগুলিকে সারিবদ্ধ করেন, তখন কার্নেল সিঙ্ক্রোনাইজেশন ফ্রেমওয়ার্কের সাথে নির্ভরতা তালিকাভুক্ত করে:

/*
 * displays buffer when fence is signaled.  returns immediately with a fence
 * that signals when buffer is no longer displayed.
 */
struct sync_fence* display_buffer(struct dma_buf *buffer, struct sync_fence
*fence);

সিঙ্ক ইন্টিগ্রেশন

এই বিভাগে ব্যাখ্যা করা হয়েছে কিভাবে কার্নেল-স্পেস সিঙ্ক ফ্রেমওয়ার্ককে অ্যান্ড্রয়েড ফ্রেমওয়ার্কের ইউজারস্পেস অংশ এবং ড্রাইভারগুলির সাথে একীভূত করা যায় যেগুলিকে একে অপরের সাথে যোগাযোগ করতে হবে। কার্নেল-স্পেস অবজেক্টগুলিকে ইউজারস্পেসে ফাইল বর্ণনাকারী হিসাবে উপস্থাপন করা হয়।

ইন্টিগ্রেশন কনভেনশন

অ্যান্ড্রয়েড এইচএএল ইন্টারফেস কনভেনশনগুলি অনুসরণ করুন:

  • যদি API একটি ফাইল বর্ণনাকারী প্রদান করে যা একটি sync_pt কে নির্দেশ করে, তাহলে বিক্রেতার ড্রাইভার অথবা API ব্যবহারকারী HAL কে অবশ্যই ফাইল বর্ণনাকারীটি বন্ধ করতে হবে।
  • যদি বিক্রেতা ড্রাইভার বা HAL একটি ফাইল বর্ণনাকারীকে একটি API ফাংশনে sync_pt ধারণ করে, তাহলে বিক্রেতা ড্রাইভার বা HAL ফাইল বর্ণনাকারীটি বন্ধ করবে না।
  • ফেন্স ফাইল বর্ণনাকারী ব্যবহার চালিয়ে যেতে, বিক্রেতা ড্রাইভার অথবা HAL-কে বর্ণনাকারীর নকল করতে হবে।

একটি ফেন্স অবজেক্ট যখনই BufferQueue এর মধ্য দিয়ে যায় তখনই তার নাম পরিবর্তন করা হয়। কার্নেল ফেন্স সাপোর্ট ফেন্সগুলিকে নামের জন্য স্ট্রিং রাখার অনুমতি দেয়, তাই সিঙ্ক ফ্রেমওয়ার্কটি উইন্ডোর নাম এবং বাফার সূচক ব্যবহার করে যা ফেন্সের নামকরণের জন্য সারিবদ্ধ করা হচ্ছে, যেমন SurfaceView:0/d/sync এবং বাগ রিপোর্টের আউটপুটে নামগুলি প্রদর্শিত হওয়ার সাথে সাথে একটি অচলাবস্থার উৎস সনাক্ত করতে ডিবাগিংয়ে এটি সহায়ক।

ANativeWindow ইন্টিগ্রেশন

ANativeWindow বেড়া সম্পর্কে সচেতন। dequeueBuffer , queueBuffer , এবং cancelBuffer বেড়ার প্যারামিটার রয়েছে।

OpenGL ES ইন্টিগ্রেশন

OpenGL ES সিঙ্ক ইন্টিগ্রেশন দুটি EGL এক্সটেনশনের উপর নির্ভর করে:

  • EGL_ANDROID_native_fence_sync EGLSyncKHR অবজেক্টে নেটিভ অ্যান্ড্রয়েড ফেন্স ফাইল বর্ণনাকারী মোড়ানো বা তৈরি করার একটি উপায় প্রদান করে।
  • EGL_ANDROID_wait_sync CPU-সাইডের পরিবর্তে GPU-সাইড স্টলগুলিকে অনুমতি দেয়, যার ফলে GPU EGLSyncKHR এর জন্য অপেক্ষা করে। EGL_ANDROID_wait_sync এক্সটেনশনটি EGL_KHR_wait_sync এক্সটেনশনের মতোই।

এই এক্সটেনশনগুলি স্বাধীনভাবে ব্যবহার করতে, সংশ্লিষ্ট কার্নেল সাপোর্টের সাথে EGL_ANDROID_native_fence_sync এক্সটেনশনটি প্রয়োগ করুন। এরপর, আপনার ড্রাইভারে EGL_ANDROID_wait_sync এক্সটেনশনটি সক্ষম করুন। EGL_ANDROID_native_fence_sync এক্সটেনশনটিতে একটি স্বতন্ত্র নেটিভ ফেন্স EGLSyncKHR অবজেক্ট টাইপ রয়েছে। ফলস্বরূপ, বিদ্যমান EGLSyncKHR অবজেক্ট টাইপের ক্ষেত্রে প্রযোজ্য এক্সটেনশনগুলি অগত্যা EGL_ANDROID_native_fence অবজেক্টের ক্ষেত্রে প্রযোজ্য হয় না, অবাঞ্ছিত ইন্টারঅ্যাকশন এড়ানো যায়।

EGL_ANDROID_native_fence_sync এক্সটেনশনটি একটি সংশ্লিষ্ট নেটিভ ফেন্স ফাইল বর্ণনাকারী বৈশিষ্ট্য ব্যবহার করে যা শুধুমাত্র তৈরির সময় সেট করা যেতে পারে এবং বিদ্যমান সিঙ্ক অবজেক্ট থেকে সরাসরি জিজ্ঞাসা করা যাবে না। এই বৈশিষ্ট্যটি দুটি মোডের একটিতে সেট করা যেতে পারে:

  • একটি বৈধ ফেন্স ফাইল বর্ণনাকারী একটি বিদ্যমান নেটিভ অ্যান্ড্রয়েড ফেন্স ফাইল বর্ণনাকারীকে একটি EGLSyncKHR অবজেক্টে মোড়ানো হয়।
  • -1 একটি EGLSyncKHR অবজেক্ট থেকে একটি নেটিভ অ্যান্ড্রয়েড ফেন্স ফাইল বর্ণনাকারী তৈরি করে।

নেটিভ অ্যান্ড্রয়েড ফেন্স ফাইল বর্ণনাকারী থেকে EGLSyncKHR অবজেক্টটি বের করতে DupNativeFenceFD() ফাংশন কল ব্যবহার করুন। এটি সেট অ্যাট্রিবিউট অনুসন্ধানের মতো একই ফলাফল দেয়, তবে প্রাপক ফেন্সটি বন্ধ করে দেয় (অতএব ডুপ্লিকেট অপারেশন) এই নিয়ম মেনে চলে। অবশেষে, EGLSyncKHR অবজেক্টটি ধ্বংস করলে অভ্যন্তরীণ ফেন্স অ্যাট্রিবিউটটি বন্ধ হয়ে যায়।

হার্ডওয়্যার কম্পোজার ইন্টিগ্রেশন

HWC তিন ধরণের সিঙ্ক বেড়া পরিচালনা করে:

  • অ্যাকোয়ায়ার ফেন্সগুলি ইনপুট বাফারের সাথে setLayerBuffer এবং setClientTarget কলগুলিতে প্রেরণ করা হয়। এগুলি বাফারে একটি মুলতুবি লেখার প্রতিনিধিত্ব করে এবং SurfaceFlinger বা HWC কম্পোজিশন সম্পাদনের জন্য সংশ্লিষ্ট বাফার থেকে পড়ার চেষ্টা করার আগে অবশ্যই সংকেত পাঠাতে হবে।
  • getReleaseFences কল ব্যবহার করে presentDisplay কল করার পরে রিলিজ ফেন্সগুলি পুনরুদ্ধার করা হয়। এগুলি একই স্তরে পূর্ববর্তী বাফার থেকে একটি মুলতুবি পড়া প্রতিনিধিত্ব করে। একটি রিলিজ ফেন্স সংকেত যখন HWC আর পূর্ববর্তী বাফার ব্যবহার করছে না কারণ বর্তমান বাফারটি ডিসপ্লেতে পূর্ববর্তী বাফারটি প্রতিস্থাপন করেছে। রিলিজ ফেন্সগুলি পূর্ববর্তী বাফারগুলির সাথে অ্যাপে ফেরত পাঠানো হয় যা বর্তমান রচনার সময় প্রতিস্থাপিত হবে। অ্যাপটিকে বাফারে নতুন বিষয়বস্তু লেখার আগে একটি রিলিজ ফেন্স সংকেত না আসা পর্যন্ত অপেক্ষা করতে হবে যা তাদের কাছে ফেরত পাঠানো হয়েছিল।
  • presentDisplay তে কল করার অংশ হিসেবে, প্রতি ফ্রেমে একটি করে বর্তমান বেড়া ফেরত পাঠানো হয়। বর্তমান বেড়াগুলি তখন বোঝায় যখন এই ফ্রেমের রচনা সম্পূর্ণ হয়ে যায়, অথবা পর্যায়ক্রমে, যখন পূর্ববর্তী ফ্রেমের রচনা ফলাফলের আর প্রয়োজন হয় না। ভৌত প্রদর্শনের জন্য, বর্তমান ফ্রেমটি স্ক্রিনে প্রদর্শিত হলে presentDisplay বর্তমান বেড়াগুলি ফেরত দেয়। বর্তমান বেড়াগুলি ফেরত দেওয়ার পরে, প্রযোজ্য হলে, আবার SurfaceFlinger টার্গেট বাফারে লেখা নিরাপদ। ভার্চুয়াল প্রদর্শনের জন্য, আউটপুট বাফার থেকে পড়া নিরাপদ হলে বর্তমান বেড়াগুলি ফেরত পাঠানো হয়।