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

Android 3.0 (API লেভেল 11) থেকে শুরু করে, Android 2D রেন্ডারিং পাইপলাইন হার্ডওয়্যার অ্যাক্সিলারেশন সাপোর্ট করে, এর অর্থ হল, কোনও View's ক্যানভাসের উপর করা সমস্ত ড্রয়িং অপারেশন GPU ব্যবহার করে। হার্ডওয়্যার অ্যাক্সিলারেশন চালু করার জন্য বেশি রিসোর্স প্রয়োজন হয় বলে, আপনার অ্যাপ আরও বেশি RAM ব্যবহার করবে।

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

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

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

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

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

  • অ্যাপ্লিকেশন
  • অ্যাক্টিভিটি
  • উইন্ডো
  • দেখুন

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

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

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

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

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

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

উইন্ডো লেভেল

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

Kotlin

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

জাভা

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

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

লেভেল দেখুন

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

Kotlin

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)

জাভা

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

মনে রাখবেন: আপনি বর্তমানে ভিউ লেভেলে হার্ডওয়্যার অ্যাক্সিলারেশন চালু করতে পারবেন না। হার্ডওয়্যার অ্যাক্সিলারেশন বন্ধ করা ছাড়াও ভিউ লেয়ারের অন্যান্য ফাংশন আছে। তাদের ব্যবহার সম্পর্কে আরও তথ্য পেতে লেয়ার দেখুন বিকল্প দেখুন।

কোনও ভিউ হার্ডওয়্যার অ্যাক্সিলারেটেড কিনা তা নির্ধারণ করা

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

অ্যাপ্লিকেশন হার্ডওয়্যার অ্যাক্সিলারেটেড কিনা তা চেক করার দুটি আলাদা আলাদা উপায় আছে:

  • View.isHardwareAccelerated() রিটার্ন করে true যদি View একটি হার্ডওয়্যার অ্যাক্সিলারেটেড উইন্ডোর সাথে অ্যাটাচ করা থাকে।
  • Canvas.isHardwareAccelerated() Canvas হার্ডওয়্যার অ্যাক্সিলারেটেড হলে true রিটার্ন করে

আপনার ড্রয়িং কোডে এই চেকটি করতেই হলে, সম্ভব হলে View.isHardwareAccelerated()-এর পরিবর্তে Canvas.isHardwareAccelerated() ব্যবহার করুন। হার্ডওয়্যার অ্যাক্সিলারেটেড উইন্ডোর সাথে কোনও ভিউ অ্যাটাচ করা থাকলে, সেটি এখনও নন-হার্ডওয়্যার অ্যাক্সিলারেটেড ক্যানভাস ব্যবহার করে ড্র করা যেতে পারে। যেমন, ক্যাশিংয়ের উদ্দেশ্যে বিটম্যাপে ভিউ ড্র করার সময় এটি ঘটে।

Android ড্রয়িং মডেল

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

সফ্টওয়্যার-ভিত্তিক ড্রয়িং মডেল

সফ্টওয়্যার ড্রয়িং মডেলে, নিম্নলিখিত দুটি ধাপে ভিউ আঁকা হয়:

  1. হায়ারার্কি বাতিল করা
  2. হায়ারার্কি আঁকুন

কোনও অ্যাপ্লিকেশনকে যখনই তার UI-এর কোনও অংশ আপডেট করতে হয়, তখন সেটি সেইসব ভিউতে invalidate() (বা এর কোনও একটি ভেরিয়েন্ট) ইনভোক করে যেগুলির কন্টেন্ট পরিবর্তন করা হয়েছে। স্ক্রিনের যে অংশ আবার আঁকতে হবে (ডার্টি অঞ্চল), তা গণনা করার জন্য ভিউয়ের হায়ারার্কি ধরে ইনভ্যালিডেশন মেসেজ সব জায়গায় পাঠানো হয়। তারপরে, Android সিস্টেম হায়রার্কিতে থাকা এমন যেকোনও ভিউ আঁকে যা ডার্টি অঞ্চলের সাথে ইন্টারসেক্ট করে। এই ড্রয়িং মডেলের দুটি অসুবিধা আছে:

  • প্রথমত, এই মডেলের জন্য প্রতিটি ড্র পাসে প্রচুর কোড এক্সিকিউট করতে হয়। যেমন, আপনার অ্যাপ্লিকেশন যদি কোনও বোতামে invalidate()-কে কল করে এবং সেই বোতামটি অন্য ভিউয়ের উপরে থাকে, তাহলে Android সিস্টেম ভিউটি আবার আঁকে, যদিও এটি পরিবর্তন হয়নি।
  • দ্বিতীয় সমস্যা হল, ড্রয়িং মডেল আপনার অ্যাপ্লিকেশনে থাকা বাগ আড়াল করতে পারে। যেহেতু Android সিস্টেম নোংরা অঞ্চলের সাথে ইন্টারসেক্ট করলে ভিউ আবার আঁকে, তাই আপনি যে ভিউয়ের কন্টেন্ট পরিবর্তন করেছেন সেটি আবার আঁকা হতে পারে, এমনকি সেটির উপর invalidate() কল করা না হলেও। এটি ঘটলে, সঠিক আচরণ পাওয়ার জন্য আপনাকে অন্য ভিউ বাতিল করার উপর নির্ভর করতে হবে। আপনি অ্যাপ্লিকেশন পরিবর্তন করলে এই আচরণও প্রতিবার পরিবর্তিত হতে পারে। এই কারণে, ভিউয়ের ড্রয়িং কোডকে প্রভাবিত করে এমন ডেটা বা স্টেট পরিবর্তন করলে, আপনাকে সবসময় কাস্টম ভিউতে invalidate() কল করতে হবে।

মনে রাখবেন: Android ভিউয়ের প্রপার্টি পরিবর্তন হলে, যেমন ব্যাকগ্রাউন্ড কালার বা TextView-এর টেক্সট, সেগুলি অটোমেটিক invalidate()-কে কল করে।

হার্ডওয়্যার অ্যাক্সিলারেটেড ড্রয়িং মডেল

স্ক্রিন আপডেট করার অনুরোধ করতে এবং ভিউ রেন্ডার করতে Android সিস্টেম এখনও invalidate() এবং draw() ব্যবহার করে, কিন্তু আসল ড্রয়িং আলাদাভাবে ম্যানেজ করে। ড্রয়িং কমান্ড অবিলম্বে এক্সিকিউট করার পরিবর্তে, Android সিস্টেম ডিসপ্লে লিস্টের মধ্যে সেগুলি রেকর্ড করে, যার মধ্যে ভিউ হায়ারার্কির ড্রয়িং কোডের আউটপুট থাকে। অন্য একটি অপ্টিমাইজেশন হল, Android সিস্টেমকে শুধুমাত্র invalidate() কলের মাধ্যমে চিহ্নিত করা নোংরা ভিউয়ের জন্য ডিসপ্লে তালিকা রেকর্ড ও আপডেট করতে হবে। যেসব ভিউ বাতিল করা হয়নি, সেগুলি আগের রেকর্ড করা ডিসপ্লে তালিকা আবার ইস্যু করে সহজেই আবার আঁকা যায়। নতুন ড্রয়িং মডেলে তিনটি ধাপ আছে:

  1. হায়ারার্কি বাতিল করা
  2. ডিসপ্লে তালিকা রেকর্ড ও আপডেট করা
  3. ডিসপ্লে তালিকা আঁকুন

এই মডেলের সাহায্যে, draw() মেথড এক্সিকিউট করার জন্য আপনি নোংরা অঞ্চলের সাথে ইন্টারসেক্ট করা ভিউয়ের উপর নির্ভর করতে পারবেন না। Android সিস্টেম যাতে ভিউয়ের ডিসপ্লে তালিকা রেকর্ড করে তা নিশ্চিত করতে, আপনাকে অবশ্যই invalidate() কল করতে হবে। এটি করতে ভুলে গেলে, পরিবর্তন করার পরেও ভিউটি একই রকম দেখায়।

এছাড়াও, ডিসপ্লে তালিকা ব্যবহার করলে অ্যানিমেশন পারফর্ম্যান্স ভাল হয় কারণ আলফা বা রোটেশনের মতো নির্দিষ্ট প্রপার্টি সেট করার জন্য টার্গেট করা ভিউকে বাতিল করতে হয় না (এটি অটোমেটিক করা হয়)। এছাড়াও, ডিসপ্লে তালিকা সহ ভিউয়ের ক্ষেত্রে এই অপ্টিমাইজেশন প্রযোজ্য (আপনার অ্যাপ্লিকেশন হার্ডওয়্যার অ্যাক্সিলারেটেড হলে যেকোনও ভিউ)। যেমন, ধরে নিন যে LinearLayout-এর মধ্যে Button-এর উপরে ListView আছে। LinearLayout-এর ডিসপ্লে তালিকাটি এরকম দেখায়:

  • DrawDisplayList(ListView)
  • DrawDisplayList(Button)

এখন ধরে নিন যে আপনি ListView-এর অস্বচ্ছতা পরিবর্তন করতে চান। ListView-এ setAlpha(0.5f) ইনভোক করার পরে, ডিসপ্লে তালিকায় এখন এটি রয়েছে:

  • SaveLayerAlpha(0.5)
  • DrawDisplayList(ListView)
  • ফিরিয়ে আনুন
  • DrawDisplayList(Button)

ListView-এর জটিল ড্রয়িং কোড এক্সিকিউট করা হয়নি। এর পরিবর্তে, সিস্টেমটি অনেক সহজ LinearLayout-এর ডিসপ্লে তালিকা আপডেট করেছে। হার্ডওয়্যার অ্যাক্সিলারেশন চালু না থাকা কোনও অ্যাপ্লিকেশনে, তালিকা ও তার পেরেন্ট, দু'টিরই ড্রয়িং কোড আবার এক্সিকিউট করা হয়।

ড্রয়িং অপারেশন সংক্রান্ত সহায়তা

হার্ডওয়্যার অ্যাক্সিলারেশন করা হলে, 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 (ফ্রেমবাফার) ২৮
PorterDuff.Mode.OVERLAY (ফ্রেমবাফার) ২৮
শেডার
ComposeShader-এর মধ্যে ComposeShader ২৮
ComposeShader-এর মধ্যে একই ধরনের শেডার ২৮
ComposeShader-এ লোকাল ম্যাট্রিক্স 18

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

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

বড় স্কেলে সঠিকভাবে ম্যানেজ করার জন্য কখন ইমপ্লিমেন্টেশন পরিবর্তন করা হয়েছে তা নিম্নলিখিত সারণী থেকে জানতে পারবেন:
ড্রয়িং অপারেশনকে স্কেল করতে হবে প্রথম কাজ করে এমন API লেভেল
drawText() 18
drawPosText() ২৮
drawTextOnPath() ২৮
সাধারণ শেপ* 17
জটিল শেপ* ২৮
drawPath() ২৮
শ্যাডো লেয়ার ২৮

মনে রাখবেন: 'সহজ' শেপ হল drawRect(), drawCircle(), drawOval(), drawRoundRect() এবং drawArc() (useCenter=false সহ) কমান্ড যা এমন Paint-এর সাথে ইস্যু করা হয় যাতে PathEffect নেই এবং এতে ডিফল্ট নয় এমন জয়েন (setStrokeJoin() / setStrokeMiter()-এর মাধ্যমে) থাকে না। সেইসব ড্র কমান্ডের অন্যান্য উদাহরণ উপরের চার্টে 'জটিল' বিভাগের মধ্যে পড়ে।

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

লেয়ার দেখা

Android-এর সব ভার্সনে, ভিউ অফ-স্ক্রিন বাফারে রেন্ডার করার ক্ষমতা রাখে, হয় ভিউয়ের ড্রয়িং ক্যাশে ব্যবহার করে, অথবা Canvas.saveLayer() ব্যবহার করে। অফ-স্ক্রিন বাফার বা লেয়ারের বিভিন্ন ব্যবহার রয়েছে। কমপ্লেক্স ভিউ অ্যানিমেট করার সময় বা কম্পোজিশন এফেক্ট প্রয়োগ করার জন্য আপনি এগুলি ব্যবহার করে আরও ভালো পারফর্ম্যান্স পেতে পারেন। যেমন, আপনি Canvas.saveLayer() ব্যবহার করে কোনও ভিউ সাময়িকভাবে রেন্ডার করতে এবং তারপরে অপাসিটি ফ্যাক্টর সহ স্ক্রিনে কম্পোজিট করতে ফেড এফেক্ট প্রয়োগ করতে পারেন।

Android 3.0 (API লেভেল 11) থেকে শুরু করে, View.setLayerType() পদ্ধতির মাধ্যমে কীভাবে এবং কখন লেয়ার ব্যবহার করতে হবে তার উপর আপনার আরও বেশি নিয়ন্ত্রণ থাকে। এই API দুটি প্যারামিটার নেয়: আপনি যে লেয়ারের ধরন ব্যবহার করতে চান এবং একটি ঐচ্ছিক Paint অবজেক্ট যা লেয়ার কীভাবে কম্পোজিট করা উচিত তা বর্ণনা করে। আপনি কোনও লেয়ারে কালার ফিল্টার, বিশেষ ব্লেন্ডিং মোড বা অপাসিটি প্রয়োগ করতে Paint প্যারামিটার ব্যবহার করতে পারেন। কোনও ভিউ তিনটি লেয়ারের মধ্যে যেকোনও একটি ব্যবহার করতে পারে:

  • LAYER_TYPE_NONE: ভিউটি স্বাভাবিকভাবে রেন্ডার করা হয় এবং অফ-স্ক্রিন বাফার দ্বারা ব্যাক-আপ নেওয়া হয় না। এটি হল ডিফল্ট অ্যাকশন।
  • LAYER_TYPE_HARDWARE: অ্যাপ্লিকেশন হার্ডওয়্যার অ্যাক্সিলারেটেড হলে ভিউটি হার্ডওয়্যারে হার্ডওয়্যার টেক্সচারে রেন্ডার করা হয়। অ্যাপ্লিকেশন হার্ডওয়্যার অ্যাক্সিলারেটেড না হলে, এই লেয়ারের ধরন LAYER_TYPE_SOFTWARE-এর মতো আচরণ করে।
  • LAYER_TYPE_SOFTWARE: ভিউটি সফ্টওয়্যারে একটি বিটম্যাপে রেন্ডার করা হয়।

আপনি কোন ধরনের লেয়ার ব্যবহার করবেন তা আপনার লক্ষ্যের উপর নির্ভর করে:

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

লেয়ার ও অ্যানিমেশন দেখা

আপনার অ্যাপ্লিকেশন হার্ডওয়্যার অ্যাক্সিলারেটেড হলে, হার্ডওয়্যার লেয়ার আরও দ্রুত ও মসৃণ অ্যানিমেশন ডেলিভার করতে পারে। অনেক ড্রয়িং অপারেশন করা জটিল ভিউ অ্যানিমেট করার সময় ৬০ ফ্রেম প্রতি সেকেন্ডে অ্যানিমেশন চালানো সবসময় সম্ভব হয় না। হার্ডওয়্যার টেক্সচারে ভিউ রেন্ডার করার জন্য হার্ডওয়্যার লেয়ার ব্যবহার করে এটি কমানো যেতে পারে। ভিউ অ্যানিমেট করার জন্য হার্ডওয়্যার টেক্সচার ব্যবহার করা যেতে পারে। এর ফলে, অ্যানিমেশন চলাকালীন ভিউকে বারবার রিড্র করার প্রয়োজন হয় না। আপনি ভিউয়ের প্রপার্টি পরিবর্তন না করলে ভিউ আবার আঁকা হয় না, যা invalidate() কল করে অথবা আপনি invalidate() ম্যানুয়ালি কল করলে। আপনার অ্যাপ্লিকেশনে কোনও অ্যানিমেশন চালালে এবং আপনি যদি পছন্দমতো মসৃণ ফলাফল না পান, তাহলে আপনার অ্যানিমেটেড ভিউতে হার্ডওয়্যার লেয়ার চালু করার কথা বিবেচনা করুন।

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

  • alpha: লেয়ারের স্বচ্ছতা পরিবর্তন করে
  • x, y, translationX, translationY: লেয়ারের পজিশন পরিবর্তন করে
  • scaleX, scaleY: লেয়ারের সাইজ পরিবর্তন করে
  • rotation, rotationX, rotationY: 3D স্পেসে লেয়ারের দিকনির্দেশ পরিবর্তন করে
  • pivotX, pivotY: লেয়ারের ট্রান্সফর্মেশনের অরিজিন পরিবর্তন করে

ObjectAnimator-এর মাধ্যমে কোনও ভিউ অ্যানিমেট করার সময় এইসব প্রপার্টির নাম ব্যবহার করা হয়। আপনি এইসব প্রপার্টি অ্যাক্সেস করতে চাইলে, উপযুক্ত সেটার বা গেটারকে কল করুন। যেমন, আলফা প্রপার্টি পরিবর্তন করতে, setAlpha() কল করুন। নিচে দেওয়া কোড স্নিপেট থেকে Y-অক্ষ বরাবর 3D ভিউ ঘোরানোর সবচেয়ে কার্যকর উপায়টি দেখতে পাবেন:

Kotlin

view.setLayerType(View.LAYER_TYPE_HARDWARE, null)
ObjectAnimator.ofFloat(view, "rotationY", 180f).start()

জাভা

view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator.ofFloat(view, "rotationY", 180).start();

হার্ডওয়্যার লেয়ার ভিডিও মেমরি ব্যবহার করে বলে, এটি খুব সাজেস্ট করা হয় যে আপনি এগুলি শুধুমাত্র অ্যানিমেশনের সময়কালের জন্য চালু করুন এবং অ্যানিমেশন হয়ে গেলে বন্ধ করে দিন। অ্যানিমেশন লিসেনার ব্যবহার করে আপনি এটি করতে পারেন:

Kotlin

view.setLayerType(View.LAYER_TYPE_HARDWARE, null)
ObjectAnimator.ofFloat(view, "rotationY", 180f).apply {
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            view.setLayerType(View.LAYER_TYPE_NONE, null)
        }
    })
    start()
}

জাভা

view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);
animator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        view.setLayerType(View.LAYER_TYPE_NONE, null);
    }
});
animator.start();

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

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

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

আপনার আবেদনে ভিউয়ের সংখ্যা কমান
সিস্টেমকে যত বেশি ভিউ আঁকতে হবে, এটি তত ধীরে ধীরে কাজ করবে। এটি সফ্টওয়্যার রেন্ডারিং পাইপলাইনের ক্ষেত্রেও প্রযোজ্য। আপনার UI অপ্টিমাইজ করার সবচেয়ে সহজ উপায়গুলির মধ্যে একটি হল ভিউ কমানো।
ওভারড্র এড়িয়ে চলুন
একটি লেয়ারের উপরে আরেকটি লেয়ার আঁকবেন না। অন্যান্য অস্বচ্ছ ভিউ দিয়ে সম্পূর্ণভাবে আড়াল করা ভিউ সরিয়ে দিন। আপনাকে যদি একে অপরের উপরে মিশে যাওয়া একাধিক লেয়ার আঁকতে হয়, তাহলে সেগুলিকে একটি লেয়ারে মার্জ করার কথা বিবেচনা করুন। বর্তমান হার্ডওয়্যারের ক্ষেত্রে একটি ভাল নিয়ম হল, প্রতি ফ্রেমে স্ক্রিনে পিক্সেলের সংখ্যার ২.৫ গুণের বেশি পিক্সেল ড্র না করা (বিম্যাপে ট্রান্সপারেন্ট পিক্সেল গণনা করা হয়!)।
ড্র পদ্ধতিতে রেন্ডার অবজেক্ট তৈরি করবেন না
রেন্ডারিং পদ্ধতি কল করা হলেই নতুন Paint বা নতুন Path তৈরি করা একটি সাধারণ ভুল। এর ফলে গার্বেজ কালেক্টরকে আরও ঘন ঘন রান করতে হয় এবং হার্ডওয়্যার পাইপলাইনে ক্যাশে ও অপ্টিমাইজেশন বাইপাস করা হয়।
আকার খুব ঘন ঘন পরিবর্তন করবেন না
জটিল আকার, পাথ ও বৃত্তের মতো বিষয় টেক্সচার মাস্ক ব্যবহার করে রেন্ডার করা হয়। আপনি যতবার কোনও পাথ তৈরি বা পরিবর্তন করেন, হার্ডওয়্যার পাইপলাইন একটি নতুন মাস্ক তৈরি করে, যা খরচসাপেক্ষ হতে পারে।
বিটম্যাপ খুব ঘন ঘন পরিবর্তন করবেন না
আপনি বিটম্যাপের কন্টেন্ট পরিবর্তন করলে, পরবর্তীকালে সেটি আঁকার সময় সেটি আবার GPU টেক্সচার হিসেবে আপলোড করা হয়।
সাবধানে আলফা ভার্সন ব্যবহার করুন
আপনি setAlpha(), AlphaAnimation বা ObjectAnimator ব্যবহার করে কোনও ভিউ ট্রান্সলুসেন্ট করলে, এটি অফ-স্ক্রিন বাফারে রেন্ডার করা হয়, যার ফলে প্রয়োজনীয় ফিল-রেট দ্বিগুণ হয়ে যায়। খুব বড় ভিউতে আলফা প্রয়োগ করার সময়, ভিউয়ের লেয়ার টাইপকে LAYER_TYPE_HARDWARE হিসেবে সেট করার কথা বিবেচনা করুন।