Android-এ নতুন পিক্সেল ফর্ম্যাট যোগ করা

Android-এ যোগ করা সব নতুন পিক্সেল ফর্ম্যাটকে Android ইন্টারফেস ডেফিনিশন ল্যাঙ্গুয়েজ (AIDL) এবং Android হার্ডওয়্যার বাফার (AHB)-এ অন্তর্ভুক্ত করতে হবে। AIDL ও AHB-তে কঠোর স্থিতিশীলতা ও স্ট্যান্ডার্ডাইজেশন সংক্রান্ত প্রয়োজনীয়তা থাকে যা কার্যকারিতা বাড়ানোর সময় সতর্কতার সাথে প্রসেস মেনে চলতে বাধ্য করে। সব নতুন পিক্সেল ফর্ম্যাট AOSP-তে থাকতে হবে এবং সব আপডেটকে AIDL ও AHB বিশেষজ্ঞদের দ্বারা আলাদা আলাদাভাবে কনফার্ম করতে হবে। এইভাবে যত্ন সহকারে কনফার্ম করার প্রসেসটি প্ল্যাটফর্মে যেকোনও নতুন পিক্সেল ফর্ম্যাটকে স্ট্যান্ডার্ডাইজ করার ক্ষেত্রে একটি গুরুত্বপূর্ণ ফ্যাক্টর।

এই পৃষ্ঠায় প্রয়োজনীয় AOSP কোড পরিবর্তন এবং AOSP-তে নতুন পিক্সেল ফর্ম্যাট যোগ করার জন্য প্রয়োজনীয় প্রসেস সম্পর্কে বলা হয়েছে।

নতুন পিক্সেল ফর্ম্যাট যোগ করার আগে, সোর্স ডাউনলোড করুন এবং প্যাচ জমা দেওয়া লিঙ্কে উল্লেখ করা পদ্ধতি অনুযায়ী প্যাচ আপলোড করুন।

AIDL-এ নতুন পিক্সেল ফর্ম্যাট যোগ করুন

নতুন পিক্সেল ফর্ম্যাটের জন্য সহায়তা যোগ করতে AIDL-এর মধ্যে থাকা দুটি PixelFormat.aidl ফাইলেই পরিবর্তন করতে হবে। AIDL সোর্স কোডের জন্য hardware/interfaces/graphics/common/aidl/ দেখুন।

AIDL-এ নতুন পিক্সেল ফর্ম্যাট যোগ করতে, এইসব ধাপ ফলো করুন:

  1. আগে থেকে থাকা কোড কনভেনশন অনুসরণ করে এবং আপনার এন্ট্রির জন্য হেক্স ভ্যালু আগের এন্ট্রির থেকে এক বেশি সেট করে PixelFormat.aidl -এ PixelFormat এনামের শেষে নতুন এন্ট্রি হিসেবে নতুন পিক্সেল ফর্ম্যাট যোগ করুন। আপনার কোডে করা পরিবর্তন আগের এন্ট্রির সাথে মিলিয়ে দেখুন। RGBA_8888 পিক্সেল ফর্ম্যাট এন্ট্রির জন্য নিচের উদাহরণ দেখুন:
    /**
     * 32-bit format that has 8-bit R, G, B, and A components, in that order,
     * from the lowest memory address to the highest memory address.
     *
     * The component values are unsigned normalized to the range [0, 1], whose
     * interpretation is defined by the dataspace.
     */
    RGBA_8888 = 0x1,
    

    আপনি PixelFormat.aidl-এ পরিবর্তন করার পরে কোড তৈরি করলে, নিম্নলিখিত সমস্যার মেসেজ দেখতে পাবেন:

    android_developer:~/android/aosp-android-latest-release: m
    ...
    ###############################################################################
    # ERROR: AIDL API change detected                                             #
    ###############################################################################
    Above AIDL file(s) has changed. Run `m android.hardware.graphics.common-update-api` to reflect the changes
    to the current version so that it is reviewed by
    android-aidl-api-council@google.com
    And then you need to change dependency on android.hardware.graphics.common-V(n)-* to android.hardware.graphics.common-V(n+1)-* to use
    new APIs.
    
  2. এই সমস্যা সমাধান করতে, সমস্যা সংক্রান্ত মেসেজে যেভাবে বলা হয়েছে সেইভাবে নিম্নলিখিত কমান্ড রান করুন, যাতে PixelFormat.aidl aidl_api ডিরেক্টরিতে পরিবর্তন করা যায়:

    m android.hardware.graphics.common-update-api
    

    উপরের কমান্ডটি রান করলে, সঠিকভাবে বিল্ড করার জন্য সঠিক ফাইল আপডেট হয়ে যায়।

AHB-তে নতুন পিক্সেল ফর্ম্যাট যোগ করা

নতুন পিক্সেল ফর্ম্যাটের জন্য সহায়তা যোগ করতে হলে hardware_buffer.h ও AHardwareBuffer.cpp-এ পরিবর্তন করতে হবে। AHB সোর্স কোডের জন্য frameworks/native/libs/nativewindow দেখুন।

AHB-তে নতুন পিক্সেল ফর্ম্যাট যোগ করতে, এইসব ধাপ ফলো করুন:

  1. hardware_buffer.h-এ, AHardwareBuffer_Format enum-এর শেষে নতুন এন্ট্রি হিসেবে নতুন পিক্সেল ফর্ম্যাট যোগ করুন। আগে থেকে থাকা কোড কনভেনশন অনুসরণ করুন।

    RGBA_8888 পিক্সেল ফর্ম্যাটের উদাহরণ ব্যবহার করে, নতুন পিক্সেল ফর্ম্যাট এন্ট্রি এইভাবে যোগ করুন:

    /**
     * Corresponding formats:
     *   Vulkan: VK_FORMAT_R8G8B8A8_UNORM
     *   OpenGL ES: GL_RGBA8
     */
    AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
    

    মনে রাখবেন যে নতুন পিক্সেল ফর্ম্যাটকে AHB-তে একটি নাম দেওয়া হয়েছে, যা অবশ্যই AHARDWAREBUFFER_FORMAT_ দিয়ে শুরু হতে হবে, তারপরে চ্যানেলের সংক্ষিপ্ত রূপ এবং বিট ডেপথ এবং এনকোডিং দিয়ে শেষ হতে হবে। এই এনুম এন্ট্রির হেক্স ভ্যালু অবশ্যই PixelFormat.aidl-এর সমান হতে হবে।

    পিক্সেল ফর্ম্যাটে সংশ্লিষ্ট Vulkan বা OpenGL ES ফর্ম্যাটের একটি বা দুটিই থাকতে হবে। যেখানে উপযুক্ত সেখানে সংশ্লিষ্ট ফর্ম্যাট উল্লেখ করুন। সম্পর্কিত কোনও ফর্ম্যাট না থাকলে, N/A নির্দিষ্ট করুন।

  2. CTS-এর অধীনে ঐচ্ছিক টেস্টিংয়ে পিক্সেল ফর্ম্যাট যোগ করুন, যদি এটির সাথে কোনও OpenGL ES ফর্ম্যাট যুক্ত থাকে। এটি করতে, নতুন GL ফর্ম্যাটকে AHardwareBufferGLTest.cpp AHBFormatAsString(int32_t format)-এ FORMAT_CASE(...) এবং GL_FORMAT_CASE(...)-এর সাথে যোগ করুন, যা নতুন ফর্ম্যাটের জন্য নিচে দেখানো হয়েছে:

    const char* AHBFormatAsString(int32_t format) {
      switch (format) {
          ...
          FORMAT_CASE(R8G8B8A8_UNORM);
          ...
          GL_FORMAT_CASE(GL_RGB8);
      }
      return "";
    }
    
  3. এরপরে, AHardwareBufferGLTest.cpp-এ একটি নতুন পরীক্ষা যোগ করুন, যা নিচে দেখানো হয়েছে:

    class RGBA8Test : public AHardwareBufferGLTest {};
    
    // Verify that if we can allocate an RGBA8 AHB we can render to it.
    TEST_P(RGBA8Test, Write) {
        AHardwareBuffer_Desc desc = GetParam();
        desc.usage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
        if (!SetUpBuffer(desc)) {
            return;
        }
    
        ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(desc.width, desc.height, 0, kBufferAsRenderbuffer));
        ASSERT_NO_FATAL_FAILURE(
            SetUpProgram(kVertexShader, kColorFragmentShader, kPyramidPositions, 0.5f));
    
        glDrawArrays(GL_TRIANGLES, 0, kPyramidVertexCount);
        ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
    }
    
    INSTANTIATE_TEST_CASE_P(
        SingleLayer, RGBA8Test,
        ::testing::Values(
            AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_R16G16_UINT, 0, 0, 0, 0}),
        &GetTestName);
    

    AHardwareBuffer_Desc ভ্যালুর অন্তত একটি সেট উল্লেখ করুন। প্রয়োজন হলে আরও মান যোগ করুন।

  4. AHardwareBuffer.cpp-এ, এর মধ্যে থাকা স্ট্যাটিক অ্যাসার্টের শেষ খুঁজে দেখুন:

    // ----------------------------------------------------------------------------
    // Validate hardware_buffer.h and PixelFormat.aidl agree
    // ----------------------------------------------------------------------------
    

    নতুন পিক্সেল ফর্ম্যাটের জন্য নতুন static_assert যোগ করুন, এর জন্য PixelFormat:: enum ব্যবহার করুন এবং HAL_PIXEL_FORMAT কনস্ট্যান্ট ব্যবহার করবেন না। AIDL-এ নতুন পিক্সেল ফর্ম্যাট যোগ করুন লিঙ্ক থেকে RGBA_8888 পিক্সেল ফর্ম্যাটের জন্য একই উদাহরণ ব্যবহার করে, নিম্নলিখিতভাবে নতুন পিক্সেল ফর্ম্যাট এন্ট্রি যোগ করুন:

    static_assert(static_cast(aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888) ==
      AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
    "HAL and AHardwareBuffer pixel format don't match");
    
  5. AHardwareBufferTest.cpp-এর PrintAhbFormat()-এর শেষে নতুন পিক্সেল ফর্ম্যাট যোগ করে উপযুক্ত পরীক্ষায় নতুন পিক্সেল ফর্ম্যাট যোগ করুন। নিচে দেখানো আগে থেকে থাকা কোড কনভেনশন অনুসরণ করুন:

    void PrintAhbFormat(std::ostream& os, uint64_t format) {
        switch (format) {
            ...
            FORMAT_CASE(R8G8B8A8_UNORM);
            default: os << "unknown"; break;
        }
    }
    
  6. HardwareBuffer SDK-তে HardwareBuffer.java নতুন পিক্সেল ফর্ম্যাট যোগ করুন: @IntDef-এ নতুন এন্ট্রি যোগ করে। যেমন, RGBA_8888 ফর্ম্যাটের এন্ট্রি নিচে দেখানো হল:

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "RGB", "BLOB", "YCBCR_", "D_", "DS_", "S_" }, value = {
      ...
      RGBA_8888,
    })
    

    কম্পোনেন্ট ভ্যালু আনসাইনড নরমালাইজড না হলে, ভেরিয়েবলের নামে ভ্যালু স্পষ্টভাবে উল্লেখ করুন। যেমন, শুধুমাত্র আনসাইনড ইন্টিজার ১৬-বিট রেড চ্যানেল ফর্ম্যাটের ভেরিয়েবলের নাম অবশ্যই R_16UI হতে হবে এবং অতিরিক্ত আনসাইনড ইন্টিজার ১৬-বিট গ্রিন চ্যানেল ফর্ম্যাট সহ একই ফর্ম্যাট অবশ্যই RG_16UI16UI হতে হবে।

  7. @Format-এর শেষে নতুন সর্বজনীন মেম্বার ভেরিয়েবল যোগ করে, HardwareBuffer.java-এ static int হিসেবে নতুন পিক্সেল ফর্ম্যাট যোগ করুন:

    @Format
    ...
    /** Format: 8 bits each red, green, blue, alpha */
    public static final int RGBA_8888 = 0x1;
    

    এই enum এন্ট্রির হেক্স ভ্যালু PixelFormat.aidl এবং hardware_buffer.h-এর হেক্স ভ্যালুর সমান হতে হবে। আগে থেকে থাকা কনভেনশন অনুসরণ করুন।

  8. এইসব কোড পরিবর্তন করে বিল্ড করার চেষ্টা করলে বিল্ড সংক্রান্ত সমস্যা হয়:

    android_developer:~/android/aosp-android-latest-release: m
    ...
    ******************************
    You have tried to change the API from what has been previously approved.
    
    To make these errors go away, you have two choices:
       1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)
          to the new methods, etc. shown in the above diff.
    
       2. You can update current.txt and/or removed.txt by executing the following command:
             m api-stubs-docs-non-updatable-update-current-api
    
          To submit the revised current.txt to the main Android repository,
          you will need approval.
    ******************************
    ...
    

    এই সমস্যার সমাধান করতে, সমস্যার মেসেজে উল্লেখ করা, এই কমান্ডটি রান করুন current.txt:

    m api-stubs-docs-non-updatable-update-current-api
    

    উপরের কমান্ডটি রান করলে, সাধারণভাবে বিল্ড করার জন্য সঠিক ফাইল আপডেট হয়ে যায়।

  9. Java টেস্টে নতুন পিক্সেল ফর্ম্যাট যোগ করুন, এর জন্য HardwareBufferTest.java-এ paramsForTestCreateOptionalFormats()-এর শেষে নতুন পিক্সেল ফর্ম্যাট যোগ করুন, যা নিচে দেখানো হয়েছে:

    private static Object[] paramsForTestCreateOptionalFormats() {
      return new Integer[]{
          HardwareBuffer.RGBA_8888
      };
    

Window সিস্টেম ইন্টিগ্রেশনে নতুন পিক্সেল ফর্ম্যাট যোগ করা

গ্রাফিক্স API-তে ফ্রেমবাফারের ফর্ম্যাট হিসেবে নতুন পিক্সেল ফর্ম্যাট ব্যবহার করতে, প্রাসঙ্গিক গ্রাফিক্স API-এর জন্য উপযুক্ত উইন্ডো সিস্টেম ইন্টিগ্রেশনে (WSI) এটি যোগ করুন। Vulkan API ব্যবহার করে এমন কোনও অ্যাপ বা সিস্টেম প্রসেসের জন্য, Vulkan Swapchain আপডেট করুন। OpenGL ES API ব্যবহার করে এমন কোনও অ্যাপ বা সিস্টেম প্রসেসের জন্য, EGL API আপডেট করুন।

নতুন পিক্সেল ফর্ম্যাটের জন্য Vulkan WSI পরিবর্তন

নিম্নলিখিত উপায়ে Vulkan WSI আপডেট করুন:

  1. swapchain.cpp-এ GetNativePixelFormat(VkFormat format) ফাংশনে নতুন কেস যোগ করুন:

    android::PixelFormat GetNativePixelFormat(VkFormat format) {
      ...
      switch (format) {
          ...
          case VK_FORMAT_R8G8B8A8_UNORM:
              native_format = PixelFormat::RGBA_8888;
              break;
          ...
          default:
              ALOGV("unsupported swapchain format %d", format);
              break;
      }
      return native_format;
    }
    
  2. পিক্সেল ফর্ম্যাট কাজ করার জন্য Vulkan এক্সটেনশন প্রয়োজন হলে, Vulkan এক্সটেনশন সম্পর্কে কোয়েরি করুন। যেমন, সাইড এক্সটেনশনের জন্য instance_data ব্যবহার করুন, যা নিচে দেখানো হয়েছে:
    bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
    

    ডিভাইস সাইড এক্সটেনশনের জন্য, নিম্নলিখিতগুলি ব্যবহার করুন:

    bool rgba10x6_formats_ext = false;
    uint32_t exts_count;
    const auto& driver = GetData(pdev).driver;
    driver.EnumerateDeviceExtensionProperties(pdev, nullptr, &exts_count,
                                              nullptr);
    std::vector props(exts_count);
    driver.EnumerateDeviceExtensionProperties(pdev, nullptr, &exts_count,
                                              props.data());
    for (uint32_t i = 0; i < exts_count; i++) {
        VkExtensionProperties prop = props[i];
        if (strcmp(prop.extensionName,
                   VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME) == 0) {
            rgba10x6_formats_ext = true;
        }
    }
    

    swapchain.cpp-এর কাছে কোনও ইনস্ট্যান্স বা ডিভাইস এক্সটেনশন এক্সপোজ করার জন্য প্রয়োজনীয় পরিকাঠামো Google ম্যানেজ করে। Vulkan লোডার থেকে এক্সটেনশন সঠিকভাবে সেট-আপ করার জন্য প্রাথমিক পরিবর্তন তালিকা প্রয়োজন হয় না।

  3. এরপরে, ফর্ম্যাট ও কালারস্পেসের পেয়ারগুলি গণনা করুন:
    desc.format = AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM;
    if (AHardwareBuffer_isSupported(&desc) && rgba10x6_formats_ext) {
      all_formats.emplace_back(
          VkSurfaceFormatKHR{VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
                             VK_COLOR_SPACE_SRGB_NONLINEAR_KHR});
      if (colorspace_ext) {
        all_formats.emplace_back(
            VkSurfaceFormatKHR{VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
                               VK_COLOR_SPACE_PASS_THROUGH_EXT});
        all_formats.emplace_back(
            VkSurfaceFormatKHR{VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
                               VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT});
    }
    

    মানানসই ফর্ম্যাট ও কালারস্পেস পেয়ার সম্পর্কে আপনার জ্ঞান থাকতে হবে।

  4. external/deqp-এ অবস্থিত dEQP-VK-এ নতুন ফর্ম্যাট যোগ করুন
  5. বর্তমান সোর্স থেকে প্রয়োজনীয় পরিবর্তনগুলি অনুমান করে অথবা তথ্যের জন্য আপনার Android সহায়তার সাথে যোগাযোগ করে vktApiExternalMemoryTests.cpp এবং vktExternalMemoryUtil.cpp লিঙ্কে Vulkan কনফর্ম্যান্স টেস্ট আপডেট করুন।

নতুন পিক্সেল ফর্ম্যাটের জন্য EGL পরিবর্তন

নিচে উল্লেখ করা পদ্ধতি অনুসরণ করে EGL আপডেট করুন:

  1. getNativePixelFormat() ফাংশনে, নতুন পিক্সেল ফর্ম্যাটের জন্য AIDL এনুম রিটার্ন করতে if-else ট্রি পরিবর্তন করুন।

    RGBA_8888 পিক্সেল ফর্ম্যাটের উদাহরণ ব্যবহার করে:

    if (a == 0) {
      ...
    } else {
      if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
          if (colorDepth > 24) {
              ...
          } else {
              *format = PixelFormat::RGBA_8888;
          }
      } else {
        ...
      }
    }
    
  2. dEQP-তে নতুন ফর্ম্যাট যোগ করতে, androidFormats enum-এ নতুন এন্ট্রি যোগ করুন, যা নিচে দেখানো হয়েছে:
    static const GLenum androidFormats[] =
    {
      ...
      GL_RGBA8,
      ...
    };
    

আপনার আপডেট জমা দিন

আপনার পরিবর্তন তালিকা তৈরি করতে এবং উপযুক্ত টিমের সাথে তা শেয়ার করতে কন্ট্রিবিউটরদের জন্য এইসব ধাপ অনুসরণ করুন।