প্রশস্ত রঙের সামগ্রী সহ গ্রাফিক্স উন্নত করুন

অ্যান্ড্রয়েড 8.0 (API লেভেল 26) সামঞ্জস্যপূর্ণ ডিসপ্লে সহ ডিভাইসে গ্রাফিক্স রেন্ডার করার জন্য স্ট্যান্ডার্ড RGB (sRGB) ছাড়াও অতিরিক্ত রঙের স্থানগুলির জন্য রঙ পরিচালনা সমর্থন চালু করেছে। এই সমর্থনের মাধ্যমে, আপনার অ্যাপ জাভা বা নেটিভ কোডের মাধ্যমে PNG, JPEG, এবং WebP ফাইলগুলি থেকে লোড করা এমবেডেড প্রশস্ত রঙের প্রোফাইলের সাথে বিটম্যাপ রেন্ডার করতে পারে। OpenGL বা Vulkan ব্যবহার করা অ্যাপগুলি সরাসরি প্রশস্ত রঙের গামুট সামগ্রী ( Display P3 এবং scRGB ব্যবহার করে) আউটপুট করতে পারে। এই ক্ষমতাটি এমন অ্যাপ তৈরি করার জন্য উপযোগী যা উচ্চ বিশ্বস্ততার রঙের প্রজনন জড়িত, যেমন ছবি এবং ভিডিও সম্পাদনা অ্যাপ।

ওয়াইড কালার গামুট মোড বুঝুন

প্রশস্ত রঙের প্রোফাইল হল ICC প্রোফাইল , যেমন Adobe RGB , Pro Photo RGB , এবং DCI-P3 , যেগুলি sRGB-এর থেকে বিস্তৃত রঙের প্রতিনিধিত্ব করতে সক্ষম৷ প্রশস্ত রঙের প্রোফাইল সমর্থন করে এমন স্ক্রিনগুলি গভীর প্রাথমিক রঙের (লাল, সবুজ এবং নীল) পাশাপাশি সমৃদ্ধ গৌণ রঙ (যেমন ম্যাজেন্টাস, সায়ান এবং হলুদ) সহ চিত্রগুলি প্রদর্শন করতে পারে।

Android 8.0 (API লেভেল 26) বা উচ্চতর সংস্করণে চলমান Android ডিভাইসগুলিতে যেগুলি এটি সমর্থন করে, আপনার অ্যাপটি এমন একটি ক্রিয়াকলাপের জন্য প্রশস্ত রঙের গামুট কালার মোড সক্ষম করতে পারে যেখানে সিস্টেম এমবেডেড প্রশস্ত রঙের প্রোফাইলগুলির সাথে বিটম্যাপ চিত্রগুলিকে চিনতে এবং সঠিকভাবে প্রক্রিয়া করে৷ ColorSpace.Named ক্লাসটি সাধারণত ব্যবহৃত রঙের স্থানগুলির একটি আংশিক তালিকা গণনা করে যা Android সমর্থন করে৷

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

ওয়াইড কালার গামুট মোড সক্ষম করুন

সামঞ্জস্যপূর্ণ ডিভাইসে প্রশস্ত রঙের গামুট মোডে ক্রিয়াকলাপ প্রদর্শনের অনুরোধ করতে colorMode বৈশিষ্ট্যটি ব্যবহার করুন। প্রশস্ত রঙের স্বরগ্রাম মোডে, একটি উইন্ডো আরও প্রাণবন্ত রং প্রদর্শন করতে sRGB স্বরগ্রামের বাইরে রেন্ডার করতে পারে। যদি ডিভাইসটি ওয়াইড কালার গামুট রেন্ডারিং সমর্থন না করে, তাহলে এই অ্যাট্রিবিউটের কোনো প্রভাব নেই। প্রদত্ত ডিসপ্লে ওয়াইড কালার গামুট সক্ষম কিনা তা নির্ধারণ করতে আপনার অ্যাপের প্রয়োজন হলে, isWideColorGamut() পদ্ধতিতে কল করুন। এছাড়াও আপনি অ্যাপটি isScreenWideColorGamut() কল করতে পারেন, যা শুধুমাত্র ডিসপ্লেটি ওয়াইড কালার গ্যামাট সক্ষম হলে এবং ডিভাইসটি ওয়াইড কালার গামুট কালার রেন্ডারিং সমর্থন করলেই true হয়।

একটি ডিসপ্লে প্রশস্ত রঙের স্বরগ্রাম সক্ষম হতে পারে তবে রঙ-পরিচালিত নয়, সেক্ষেত্রে, সিস্টেম একটি অ্যাপকে প্রশস্ত রঙের গামুট মোড দেবে না। যখন একটি ডিসপ্লে রঙ-পরিচালিত হয় না — যেমনটি 8.0-এর আগে অ্যান্ড্রয়েডের সমস্ত সংস্করণের ক্ষেত্রে ছিল — সিস্টেমটি অ্যাপ দ্বারা আঁকা রঙগুলিকে ডিসপ্লের স্বরগ্রামে রিম্যাপ করে।

আপনার ক্রিয়াকলাপে প্রশস্ত রঙের গামুট সক্ষম করতে, আপনার AndroidManifest.xml ফাইলে wideColorGamutcolorMode বৈশিষ্ট্য সেট করুন। প্রতিটি কার্যকলাপের জন্য আপনাকে এটি করতে হবে যার জন্য আপনি প্রশস্ত রঙ মোড সক্ষম করতে চান৷

android:colorMode="wideColorGamut"

আপনি setColorMode(int) পদ্ধতিতে কল করে এবং COLOR_MODE_WIDE_COLOR_GAMUT এ পাস করে আপনার কার্যকলাপে প্রোগ্রাম্যাটিকভাবে রঙ মোড সেট করতে পারেন।

প্রশস্ত রঙ স্বরগ্রাম বিষয়বস্তু রেন্ডার

চিত্র 1. ডিসপ্লে P3 (কমলা) বনাম sRGB (সাদা) রঙের স্থান

প্রশস্ত রঙের গামুট বিষয়বস্তু রেন্ডার করতে, আপনার অ্যাপটিকে অবশ্যই একটি প্রশস্ত রঙের বিটম্যাপ লোড করতে হবে, এটি একটি রঙের প্রোফাইল সহ একটি বিটম্যাপ যাতে sRGB-এর চেয়ে বেশি রঙের স্থান থাকে। সাধারণ প্রশস্ত রঙের প্রোফাইলগুলির মধ্যে রয়েছে Adobe RGB, DCI-P3 এবং Display P3।

getColorSpace() কল করে আপনার অ্যাপটি একটি বিটম্যাপের রঙের স্থান অনুসন্ধান করতে পারে। সিস্টেমটি একটি নির্দিষ্ট রঙের স্থানকে প্রশস্ত স্বরগ্রাম হিসাবে স্বীকৃতি দেয় কিনা তা নির্ধারণ করতে, আপনি isWideGamut() পদ্ধতিতে কল করতে পারেন।

Color ক্লাস আপনাকে পূর্ণসংখ্যার মান ব্যবহার করে এমন সবচেয়ে সাধারণ উপস্থাপনার পরিবর্তে একটি 64-বিট লম্বা মানের মধ্যে প্যাক করা চারটি উপাদান সহ একটি রঙের প্রতিনিধিত্ব করতে দেয়। দীর্ঘ মান ব্যবহার করে, আপনি পূর্ণসংখ্যার মানের চেয়ে আরও নির্ভুলতার সাথে রঙগুলি সংজ্ঞায়িত করতে পারেন। আপনি যদি একটি দীর্ঘ মান হিসাবে একটি রঙ তৈরি বা এনকোড করতে চান তবে Color ক্লাসে pack() পদ্ধতিগুলির একটি ব্যবহার করুন।

getColorMode() পদ্ধতিটি COLOR_MODE_WIDE_COLOR_GAMUT প্রদান করে কিনা তা যাচাই করে আপনি আপনার অ্যাপটি সঠিকভাবে ওয়াইড কালার গামুট মোডের অনুরোধ করেছে কিনা তা যাচাই করতে পারেন (তবে, ওয়াইড কালার গামুট মোডটি আসলে মঞ্জুর করা হয়েছে কিনা এই পদ্ধতিটি নির্দেশ করে না)।

নেটিভ কোডে ওয়াইড কালার গামুট সাপোর্ট ব্যবহার করুন

আপনার অ্যাপটি নেটিভ কোড ব্যবহার করলে কিভাবে OpenGL এবং Vulkan API-এর সাহায্যে ওয়াইড কালার গামুট মোড সক্ষম করবেন তা এই বিভাগে বর্ণনা করে।

ওপেনজিএল

OpenGL-এ ওয়াইড কালার গামুট মোড ব্যবহার করার জন্য, আপনার অ্যাপে অবশ্যই নিম্নলিখিত এক্সটেনশনগুলির মধ্যে একটি সহ EGL 1.4 লাইব্রেরি অন্তর্ভুক্ত করতে হবে:

বৈশিষ্ট্যটি সক্ষম করার জন্য, আপনাকে প্রথমে eglChooseConfig মাধ্যমে একটি GL প্রসঙ্গ তৈরি করতে হবে, গুণাবলীতে প্রশস্ত রঙের জন্য তিনটি সমর্থিত রঙের বাফার বিন্যাসের মধ্যে একটি। প্রশস্ত রঙের জন্য রঙের বাফার বিন্যাস অবশ্যই RGBA মানগুলির এই সেটগুলির মধ্যে একটি হতে হবে:

  • 8, 8, 8, 8
  • 10, 10, 10, 2
  • FP16, FP16, FP16, FP16

তারপর, আপনার রেন্ডার লক্ষ্যগুলি তৈরি করার সময় P3 রঙের স্থান এক্সটেনশনের জন্য অনুরোধ করুন, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:

std::vector<EGLint> attributes;
attributes.push_back(EGL_GL_COLORSPACE_KHR);
attributes.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT);
attributes.push_back(EGL_NONE);
engine->surface_ = eglCreateWindowSurface(
    engine->display_, config, engine->app->window, attributes.data());

ভলকান

VK_EXT_swapchain_colorspace এক্সটেনশনের মাধ্যমে প্রশস্ত রঙের গামুটের জন্য Vulkan সমর্থন প্রদান করা হয়।

আপনার Vulkan কোডে বিস্তৃত রঙ সমর্থন সক্ষম করার আগে, প্রথমে এক্সটেনশনটি vkEnumerateInstanceExtensionProperties এর মাধ্যমে সমর্থিত কিনা তা পরীক্ষা করে দেখুন। এক্সটেনশনটি উপলব্ধ থাকলে, এক্সটেনশন দ্বারা সংজ্ঞায়িত অতিরিক্ত রঙের স্থানগুলি ব্যবহার করে এমন কোনও সোয়াপচেইন চিত্র তৈরি করার আগে আপনাকে অবশ্যই vkCreateInstance চলাকালীন এটি সক্রিয় করতে হবে।

সোয়াপচেন তৈরি করার আগে, আপনাকে আপনার পছন্দসই রঙের স্থান বেছে নিতে হবে, তারপরে উপলব্ধ শারীরিক ডিভাইসের সারফেসগুলি লুপ করুন এবং সেই রঙের জায়গার জন্য একটি বৈধ রঙের বিন্যাস চয়ন করুন।

অ্যান্ড্রয়েড ডিভাইসে, ভলকান নিম্নলিখিত রঙের স্পেস এবং VkSurfaceFormatKHR রঙের ফর্ম্যাটগুলির সাথে প্রশস্ত রঙের গামুট সমর্থন করে:

  • ভলকান ওয়াইড কালার গামুট কালার স্পেস :
    • VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
    • VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
  • প্রশস্ত রঙ স্বরগ্রাম সমর্থন সহ ভলকান রঙ বিন্যাস :
    • VK_FORMAT_R16G16B16A16_SFLOAT
    • VK_FORMAT_A2R10G10B10_UNORM_PACK32
    • VK_FORMAT_R8G8B8A8_UNORM

নিম্নলিখিত কোড স্নিপেটটি দেখায় যে আপনি কীভাবে চেক করতে পারেন যে ডিভাইসটি ডিসপ্লে P3 রঙের স্থান সমর্থন করে:

uint32_t formatCount = 0;
vkGetPhysicalDeviceSurfaceFormatsKHR(
       vkPhysicalDev,
       vkSurface,
       &formatCount,
       nullptr);
VkSurfaceFormatKHR *formats = new VkSurfaceFormatKHR[formatCount];
vkGetPhysicalDeviceSurfaceFormatsKHR(
       vkPhysicalDev,
       vkSurface,
       &formatCount,
       formats);

uint32_t displayP3Index = formatCount;
for (uint32_t idx = 0; idx < formatCount; idx++) {
 if (formats[idx].format == requiredSwapChainFmt &&
     formats[idx].colorSpace==VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT)
 {
   displayP3Index = idx;
   break;
 }
}
if (displayP3Index == formatCount) {
    // Display P3 is not supported on the platform
    // choose other format
}

নিম্নলিখিত কোড স্নিপেটটি দেখায় কিভাবে VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT এর সাথে একটি ভলকান সোয়াপচেইনের অনুরোধ করতে হয়:

uint32_t queueFamily = 0;
VkSwapchainCreateInfoKHR swapchainCreate {
   .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
   .pNext = nullptr,
   .surface = AndroidVkSurface_,
   .minImageCount = surfaceCapabilities.minImageCount,
   .imageFormat = requiredSwapChainFmt,
   .imageColorSpace = VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT,
   .imageExtent = surfaceCapabilities.currentExtent,
   .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
   .imageArrayLayers = 1,
   .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
   .queueFamilyIndexCount = 1,
   .pQueueFamilyIndices = &queueFamily,
   .presentMode = VK_PRESENT_MODE_FIFO_KHR,
   .oldSwapchain = VK_NULL_HANDLE,
   .clipped = VK_FALSE,
};
VkRresult status = vkCreateSwapchainKHR(
                       vkDevice,
                       &swapchainCreate,
                       nullptr,
                       &vkSwapchain);
if (status != VK_SUCCESS) {
    // Display P3 is not supported
    return false;
}