হার্ডওয়্যার অ্যাক্সিলারেশন

Android 2D রেন্ডারিং পাইপলাইন হার্ডওয়্যার অ্যাক্সিলারেশনকে সাপোর্ট করে, যার অর্থ হল ক্যানভাসে করা সমস্ত ড্রয়িং অপারেশন GPU ব্যবহার করে। হার্ডওয়্যার অ্যাক্সিলারেশন চালু করার জন্য প্রয়োজনীয় রিসোর্স বেড়ে যাওয়ার কারণে, আপনার অ্যাপ আরও বেশি RAM ব্যবহার করবে।

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

আপনার অ্যাপ্লিকেশন কাস্টম ড্রয়িং পারফর্ম করলে, কোনও সমস্যা খুঁজে পেতে হার্ডওয়্যার অ্যাক্সিলারেশন চালু করে আসল হার্ডওয়্যার ডিভাইসে আপনার অ্যাপ্লিকেশন টেস্ট করুন। ড্রয়িং অপারেশনের জন্য সহায়তা বিভাগে হার্ডওয়্যার অ্যাক্সিলারেশন সংক্রান্ত পরিচিত সমস্যা এবং সেগুলি কীভাবে সমাধান করা যায় তা বর্ণনা করা হয়েছে।

এছাড়াও, ফ্রেমওয়ার্ক API-এর সাথে OpenGL দেখুন।

হার্ডওয়্যার অ্যাক্সিলারেশন কন্ট্রোল করুন

আপনি নিম্নলিখিত লেভেলে হার্ডওয়্যার অ্যাক্সিলারেশন নিয়ন্ত্রণ করতে পারবেন:

  • অ্যাপ্লিকেশন
  • অ্যাক্টিভিটি
  • উইন্ডো
  • কম্পোজেবল

অ্যাপ্লিকেশন লেভেল

আপনার Android ম্যানিফেস্ট ফাইলে, সম্পূর্ণ অ্যাপ্লিকেশনের জন্য হার্ডওয়্যার অ্যাক্সিলারেশন চালু করতে <application> ট্যাগে নিম্নলিখিত অ্যাট্রিবিউট যোগ করুন:

<application android:hardwareAccelerated="true" ...>

অ্যাক্টিভিটি লেভেল

হার্ডওয়্যার অ্যাক্সিলারেশন গ্লোবালি চালু করার পরে আপনার অ্যাপ্লিকেশন সঠিকভাবে কাজ না করলে, আপনি স্বতন্ত্র অ্যাক্টিভিটির জন্যও এটি নিয়ন্ত্রণ করতে পারেন। অ্যাক্টিভিটি লেভেলে হার্ডওয়্যার অ্যাক্সিলারেশন চালু বা বন্ধ করতে, আপনি <activity> এলিমেন্টের জন্য android:hardwareAccelerated অ্যাট্রিবিউট ব্যবহার করতে পারেন। নিম্নলিখিত উদাহরণটি সম্পূর্ণ অ্যাপ্লিকেশনের জন্য হার্ডওয়্যার অ্যাক্সিলারেশন চালু করে কিন্তু একটি অ্যাক্টিভিটির জন্য এটি বন্ধ করে:

<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>

উইন্ডো লেভেল

আপনার যদি আরও সূক্ষ্ম কন্ট্রোলের প্রয়োজন হয়, তাহলে নিম্নলিখিত কোড ব্যবহার করে নির্দিষ্ট উইন্ডোর জন্য হার্ডওয়্যার অ্যাক্সিলারেশন চালু করতে পারেন:

window.setFlags(
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
)

কম্পোজেবল লেভেল

Compose-এ, হার্ডওয়্যার অ্যাক্সিলারেশন বন্ধ করার জন্য কোনও কম্পোজেবল-প্রতি সুইচ নেই।

কম্পোজেবলকে নিজস্ব লেয়ারে রেন্ডার করতে, Modifier.graphicsLayer ব্যবহার করুন। এটি কম্পোজেবলের ড্রয়িং কোড আবার না চালিয়েই ট্রান্সফর্ম প্রপার্টি (যেমন alpha, scaleX, scaleY, translationX, translationY, rotationX, rotationY, rotationZ এবং transformOrigin) পরিবর্তন করতে দেয়। সেরা পারফর্ম্যান্সের জন্য, এইসব প্রপার্টি সেট করতে সবসময় মডিফায়ারের ল্যাম্বডা ফর্ম ব্যবহার করুন।

লেয়ারের মধ্যে কাস্টম ব্লেন্ডিংয়ের মতো উন্নত ড্রয়িং অপারেশনের জন্য অফ-স্ক্রিন বাফারকে স্পষ্টভাবে বাধ্য করতে, CompositingStrategy.Offscreen ব্যবহার করুন। আরও তথ্যের জন্য, গ্রাফিক্স মডিফায়ার দেখুন।

আপনার যদি কাস্টম ড্রয়িং অপারেশন থাকে যার জন্য সফ্টওয়্যার রেন্ডারিং প্রয়োজন, তাহলে আপনি AndroidView ব্যবহার করে লিগ্যাসি ভিউ হোস্ট করতে পারেন এবং সেই ভিউতে setLayerType(View.LAYER_TYPE_SOFTWARE, null) কল করতে পারেন।

আঁকার অপারেশন সংক্রান্ত সহায়তা

হার্ডওয়্যার অ্যাক্সিলারেট করা হলে, 2D রেন্ডারিং পাইপলাইন সবচেয়ে বেশি ব্যবহৃত Canvas ড্রয়িং অপারেশন এবং কম ব্যবহৃত অনেক অপারেশনকে সাপোর্ট করে। Android-এর সাথে শিপ করা অ্যাপ্লিকেশন, স্ট্যান্ডার্ড কম্পোজেবল এবং রিফ্লেকশন ও টাইল্ড টেক্সচারের মতো সাধারণ উন্নত ভিজ্যুয়াল এফেক্ট রেন্ডার করার জন্য ব্যবহৃত সমস্ত ড্রয়িং অপারেশন কাজ করে।

নিম্নলিখিত সারণীতে API লেভেল জুড়ে বিভিন্ন অপারেশনের সাপোর্ট লেভেল বর্ণনা করা হয়েছে:

প্রথম কাজ করা API লেভেল
Canvas
drawBitmapMesh() (রঙের অ্যারে) 18
drawPicture() 23
drawPosText() 16
drawTextOnPath() 16
drawVertices() ২৯
setDrawFilter() 16
clipPath() 18
clipRegion() 18
clipRect(Region.Op.XOR) 18
clipRect(Region.Op.Difference) 18
clipRect(Region.Op.ReverseDifference) 18
রোটেশন/পার্সপেক্টিভ সহ clipRect() 18
রঙ
setAntiAlias() (টেক্সটের জন্য) 18
setAntiAlias() (লাইনের জন্য) 16
setFilterBitmap() 17
setLinearText() ✗
setMaskFilter() ✗
setPathEffect() (লাইনের জন্য) ২৮
setShadowLayer() (টেক্সট ছাড়া অন্য কিছু) ২৮
setStrokeCap() (লাইনের জন্য) 18
setStrokeCap() (পয়েন্টের জন্য) 19
setSubpixelText() ২৮
Xfermode
PorterDuff.Mode.DARKEN (ফ্রেমবাফার) ২৮
PorterDuff.Mode.LIGHTEN (framebuffer) ২৮
PorterDuff.Mode.OVERLAY (framebuffer) ২৮
শেডার
ComposeShader-এর মধ্যে ComposeShader ২৮
ComposeShader-এর মধ্যে একই ধরনের শেডার ২৮
ComposeShader-এ লোকাল ম্যাট্রিক্স 18

ক্যানভাস স্কেলিং

হার্ডওয়্যার অ্যাক্সিলারেটেড 2D রেন্ডারিং পাইপলাইন প্রথমে আনস্কেলড ড্রয়িংকে সাপোর্ট করার জন্য তৈরি করা হয়েছিল, কিছু ড্রয়িং অপারেশন উচ্চ স্কেল ভ্যালুতে কোয়ালিটি উল্লেখযোগ্যভাবে হ্রাস করে। এইসব অপারেশন GPU-এর মাধ্যমে ট্রান্সফর্ম করা ১.০ স্কেলে আঁকা টেক্সচার হিসেবে প্রয়োগ করা হয়। API লেভেল ২৮ থেকে শুরু করে, সব ড্রয়িং অপারেশন কোনও সমস্যা ছাড়াই স্কেল করতে পারে।

নিচের সারণীতে দেখানো হয়েছে যে বড় স্কেল সঠিকভাবে ম্যানেজ করার জন্য কখন প্রয়োগ করার পদ্ধতি পরিবর্তন করা হয়েছে:

ড্রয়িং অপারেশন স্কেল করা হবে প্রথম কাজ করা API লেভেল
drawText() 18
drawPosText() ২৮
drawTextOnPath() ২৮
সাধারণ শেপ 17
জটিল আকার ২৮
drawPath() ২৮
শ্যাডো লেয়ার ২৮

আপনি নির্ভর করেন এমন কোনও ড্রয়িং অপারেশন হার্ডওয়্যার অ্যাক্সিলারেটেড না হলে, প্রভাবিত ড্রয়িং অফ-স্ক্রিন সফ্টওয়্যার Bitmap (বা ImageBitmap)-এ রেন্ডার করুন এবং ফলাফল ড্র করুন। আপনার UI-এর বাকি অংশ হার্ডওয়্যার অ্যাক্সিলারেশন পাথ বজায় রাখে।

পরামর্শ এবং উপায়

হার্ডওয়্যার অ্যাক্সিলারেটেড 2D গ্রাফিক্সে পরিবর্তন করলে তা তৎক্ষণাৎ পারফর্ম্যান্স বাড়িয়ে দিতে পারে, তবে আপনাকে এখনও GPU কার্যকরভাবে ব্যবহার করার জন্য এইসব সাজেশন অনুসরণ করে আপনার অ্যাপ্লিকেশন ডিজাইন করতে হবে:

লেআউটের জটিলতা ও রিকম্পোজিশন কমানো
লেআউট ট্রি শ্যালো রাখুন এবং কতবার রিকম্পোজ করা হবে তা সীমিত করুন। স্টেট রিডকে সবচেয়ে সংকীর্ণ স্কোপে ডিফার করুন, যাতে কোনও পরিবর্তন সবচেয়ে ছোট সম্ভাব্য অঞ্চলকে রিড্র করে। যেমন, কম্পোজেবলের বডির পরিবর্তে Modifier.graphicsLayer { }-এর মধ্যে অ্যানিমেটেড স্টেট পড়ুন। আরও তথ্যের জন্য, Jetpack Compose পারফর্ম্যান্স দেখুন।
ওভারড্র করা এড়িয়ে চলুন
একটির উপর আরেকটি, এইভাবে অনেক লেয়ার আঁকবেন না। এমন যেকোনও UI এলিমেন্ট সরিয়ে দিন যা সম্পূর্ণভাবে অন্যান্য অস্বচ্ছ এলিমেন্টের মাধ্যমে ঢাকা পড়ে গেছে। আপনাকে যদি একটির উপর আরেকটি ব্লেন্ড করা একাধিক লেয়ার আঁকতে হয়, তাহলে সেগুলিকে একটি লেয়ারে মার্জ করার কথা বিবেচনা করুন। বর্তমান হার্ডওয়্যারের ক্ষেত্রে একটি ভালো নিয়ম হল, প্রতি ফ্রেমে স্ক্রিনে পিক্সেলের সংখ্যার ২.৫ গুণের বেশি আঁকবেন না (বিটম্যাপে ট্রান্সপারেন্ট পিক্সেল গণনা করা হয়!)।
ড্র মেথডে রেন্ডার অবজেক্ট তৈরি করবেন না
একটি সাধারণ ভুল হল, প্রতিবার রেন্ডারিং পদ্ধতি চালু করার সময় একটি নতুন Paint বা একটি নতুন Path তৈরি করা। এটি গার্বেজ কালেক্টরকে আরও ঘন ঘন রান করতে বাধ্য করে এবং হার্ডওয়্যার পাইপলাইনে ক্যাশে ও অপ্টিমাইজেশন বাইপাস করে। এটি এড়াতে, আপনার অবজেক্ট আবার ব্যবহার ও মিউটেট করুন:
  • স্ট্যান্ডার্ড পদ্ধতি ব্যবহার করুন: স্ট্যান্ডার্ড DrawScope পদ্ধতি (যেমন drawRect এবং drawCircle) ডেভেলপার অ্যালোকেশন ছাড়াই ইন্টার্নালি Paint অবজেক্ট আবার ব্যবহার করে।
  • পুনরায় বরাদ্দ করার পরিবর্তে মিউটেট করা: কাস্টম লজিক লেখার সময়, নতুন Path ইনস্ট্যান্টিয়েট করার পরিবর্তে আগে থেকে থাকা Path মুছে দিতে path.rewind ব্যবহার করুন।
  • স্টেট দক্ষতার সাথে হোল্ড করা: কম্পোজেবলের মধ্যে, remember { Path() } ব্যবহার করে একবার অবজেক্ট বরাদ্দ করুন। আপনি যদি আবার ব্যবহার করা যায় এমন কাস্টম মডিফায়ার এক্সটেনশন তৈরি করেন, তাহলে নতুন হিপ অ্যালোকেশন না করেই অবজেক্ট অ্যালোকেট ও আবার ব্যবহার করতে DrawModifierNode ব্যবহার করে কাস্টম Modifier.Node প্রয়োগ করুন।
ঘন ঘন আকার পরিবর্তন করবেন না
উদাহরণস্বরূপ, জটিল আকার, পাথ এবং বৃত্ত টেক্সচার মাস্ক ব্যবহার করে রেন্ডার করা হয়। আপনি যতবার কোনও পাথ তৈরি বা পরিবর্তন করেন, হার্ডওয়্যার পাইপলাইন একটি নতুন মাস্ক তৈরি করে, যা ব্যয়বহুল হতে পারে।
বিটম্যাপ খুব ঘন ঘন পরিবর্তন করবেন না
বিটম্যাপের কন্টেন্ট পরিবর্তন করার সময়, আপনি পরের বার এটি আঁকলে, এটি আবার GPU টেক্সচার হিসেবে আপলোড করা হয়।
সাবধানতার সাথে আলফা ব্যবহার করুন
আপনি যখন Modifier.alpha বা Compose অ্যানিমেশন API ব্যবহার করে কম্পোজেবল ট্রান্সলুসেন্ট করেন, তখন এটি সাধারণত অফ-স্ক্রিন বাফারে রেন্ডার করা হয় যা প্রয়োজনীয় ফিল-রেট দ্বিগুণ করে। ওভারল্যাপ না করা কন্টেন্টের জন্য অফ-স্ক্রিন বাফার ওভারহেড এড়াতে, CompositingStrategy.ModulateAlpha সেট করুন। আলাদা আলাদা ড্র কলের জন্য, লেয়ার তৈরি না করেই সরাসরি ড্রয়িং কমান্ডে (যেমন color = Color.Red.copy(alpha = 0.5f)-এর সাথে) আলফা প্রয়োগ করুন।

অতিরিক্ত রিসোর্স

কন্টেন্ট দেখে