হার্ডওয়্যার ত্বরণ (ভিউ)

ধারণা এবং জেটপ্যাক কম্পোজ বাস্তবায়ন

অ্যান্ড্রয়েড ৩.০ (এপিআই লেভেল ১১) থেকে শুরু করে, অ্যান্ড্রয়েড ২ডি রেন্ডারিং পাইপলাইন হার্ডওয়্যার অ্যাক্সিলারেশন সমর্থন করে, যার অর্থ হলো একটি View -এর ক্যানভাসে সম্পাদিত সমস্ত ড্রয়িং অপারেশন জিপিইউ ব্যবহার করে। হার্ডওয়্যার অ্যাক্সিলারেশন সক্রিয় করার জন্য প্রয়োজনীয় বর্ধিত রিসোর্সের কারণে, আপনার অ্যাপ আরও বেশি র‍্যাম ব্যবহার করবে।

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

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

এছাড়াও ফ্রেমওয়ার্ক এপিআই এবং রেন্ডারস্ক্রিপ্ট সহ ওপেনজিএল দেখুন।

হার্ডওয়্যার ত্বরণ নিয়ন্ত্রণ করুন

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

  • আবেদন
  • কার্যকলাপ
  • জানালা
  • দেখুন

অ্যাপ্লিকেশন স্তর

আপনার সম্পূর্ণ অ্যাপ্লিকেশনের জন্য হার্ডওয়্যার অ্যাক্সিলারেশন সক্রিয় করতে, আপনার অ্যান্ড্রয়েড ম্যানিফেস্ট ফাইলে <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
)

জাভা

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

স্তর দেখুন

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

কোটলিন

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)

জাভা

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

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

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

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

  • View.isHardwareAccelerated তখনই true রিটার্ন করে, যখন View কোনো হার্ডওয়্যার অ্যাক্সিলারেটেড উইন্ডোর সাথে সংযুক্ত থাকে।

  • Canvas.isHardwareAccelerated তখনই true রিটার্ন করে, যখন Canvas হার্ডওয়্যার অ্যাক্সিলারেটেড হয়।

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

অ্যান্ড্রয়েড অঙ্কন মডেল

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

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

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

  1. ক্রমবিন্যাস বাতিল করুন
  2. ক্রমবিন্যাসটি আঁকুন।

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

  • প্রথমত, এই মডেলে প্রতিটি ড্র পাসে প্রচুর কোড এক্সিকিউট করার প্রয়োজন হয়। উদাহরণস্বরূপ, যদি আপনার অ্যাপ্লিকেশন কোনো বাটনে invalidate কল করে এবং সেই বাটনটি অন্য একটি ভিউ-এর উপরে থাকে, তাহলে অ্যান্ড্রয়েড সিস্টেম ভিউটিকে পুনরায় ড্র করে, যদিও সেটির কোনো পরিবর্তন হয়নি।

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

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

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

  1. ক্রমবিন্যাস বাতিল করুন

  2. প্রদর্শন তালিকা রেকর্ড এবং আপডেট করুন

  3. ডিসপ্লে তালিকাগুলো আঁকুন

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

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

  • DrawDisplayList(ListView)
  • DrawDisplayList(Button)

এখন ধরে নিন যে আপনি ListView এর অপাসিটি পরিবর্তন করতে চান। ListView তে setAlpha(0.5f) কল করার পর, প্রদর্শিত তালিকায় এখন এটি থাকবে:

  • SaveLayerAlpha(0.5)

  • DrawDisplayList(ListView)

  • Restore

  • DrawDisplayList(Button)

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

অঙ্কন কার্যক্রমের জন্য সহায়তা

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

নিম্নলিখিত সারণিতে এপিআই স্তর অনুযায়ী বিভিন্ন অপারেশনের সমর্থনের স্তর বর্ণনা করা হয়েছে:

প্রথম সমর্থিত এপিআই স্তর
ক্যানভাস
drawBitmapMesh() (রঙের অ্যারে) ১৮
drawPicture() ২৩
drawPosText() ১৬
drawTextOnPath() ১৬
drawVertices() ২৯
setDrawFilter() ১৬
clipPath() ১৮
clipRegion() ১৮
clipRect(Region.Op.XOR) ১৮
clipRect(Region.Op.Difference) ১৮
clipRect(Region.Op.ReverseDifference) ১৮
ঘূর্ণন/প্রেক্ষিত সহ clipRect() ১৮
রঙ
setAntiAlias() (টেক্সটের জন্য) ১৮
setAntiAlias() (লাইনগুলির জন্য) ১৬
setFilterBitmap() ১৭
setLinearText()
setMaskFilter()
setPathEffect() (লাইনগুলোর জন্য) ২৮
setShadowLayer() (টেক্সট ছাড়া) ২৮
setStrokeCap() (লাইনের জন্য) ১৮
setStrokeCap() (পয়েন্টের জন্য) ১৯
setSubpixelText() ২৮
Xfermode
PorterDuff.Mode.DARKEN (ফ্রেমবাফার) ২৮
PorterDuff.Mode.LIGHTEN (ফ্রেমবাফার) ২৮
PorterDuff.Mode.OVERLAY (ফ্রেমবাফার) ২৮
শেডার
ComposeShader এর ভিতরে ComposeShader ২৮
ComposeShader এর ভিতরে একই ধরণের শেডার ২৮
ComposeShader-এ স্থানীয় ম্যাট্রিক্স ১৮

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

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

নিম্নোক্ত সারণিতে দেখানো হয়েছে কখন বৃহৎ পরিসর সঠিকভাবে সামাল দেওয়ার জন্য বাস্তবায়নে পরিবর্তন আনা হয়েছিল:

অঙ্কন কার্যক্রমকে স্কেল করতে হবে প্রথম সমর্থিত এপিআই স্তর
drawText() ১৮
drawPosText() ২৮
drawTextOnPath() ২৮
সরল আকার ১৭
জটিল আকার ২৮
drawPath() ২৮
ছায়া স্তর ২৮

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

স্তরগুলি দেখুন

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

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

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

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

  • LAYER_TYPE_SOFTWARE : ভিউটি সফটওয়্যারের মাধ্যমে একটি বিটম্যাপে রেন্ডার করা হয়।

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

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

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

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

স্তর এবং অ্যানিমেশনগুলি দেখুন

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

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

  • alpha : লেয়ারের অস্বচ্ছতা পরিবর্তন করে।

  • x , y , translationX , translationY : লেয়ারের অবস্থান পরিবর্তন করে

  • scaleX , scaleY : লেয়ারের আকার পরিবর্তন করে।

  • rotation , rotationX , rotationY : ত্রিমাত্রিক স্থানে লেয়ারটির অভিমুখ পরিবর্তন করে।

  • pivotX , pivotY : লেয়ারের রূপান্তরের মূলবিন্দু পরিবর্তন করে

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

কোটলিন

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();

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

কোটলিন

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();

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

টিপস এবং কৌশল

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

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