অ্যান্ড্রয়েডে নতুন পিক্সেল ফর্ম্যাট যোগ করুন

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

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

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

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

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

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

  1. বিদ্যমান কোড কনভেনশন অনুসরণ করে এবং আপনার এন্ট্রির হেক্স ভ্যালু পূর্ববর্তী এন্ট্রির চেয়ে এক বেশি সেট করে, নতুন পিক্সেল ফরম্যাটটিকে PixelFormat.aidl এর PixelFormat enum-এর শেষে একটি নতুন এন্ট্রি হিসেবে যুক্ত করুন। আপনার কোডের পরিবর্তনগুলো পূর্ববর্তী এন্ট্রিগুলোর সাথে মেলান। 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. এই ত্রুটিটি দূর করতে, ত্রুটির বার্তায় উল্লেখিত নির্দেশ অনুযায়ী aidl_api ডিরেক্টরিতে থাকা PixelFormat.aidl পরিবর্তন করার জন্য নিম্নলিখিত কমান্ডটি চালান:

    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_ দিয়ে শুরু হবে, এরপর চ্যানেলের সংক্ষিপ্ত রূপ ও বিট ডেপথ থাকবে এবং শেষে এনকোডিং থাকবে। এই enum এন্ট্রির হেক্স ভ্যালু অবশ্যই PixelFormat.aidl এর হেক্স ভ্যালুর সমান হতে হবে।

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

  2. যদি পিক্সেল ফরম্যাটটির সাথে কোনো OpenGL ES ফরম্যাট যুক্ত থাকে, তবে সেটিকে CTS-এর অধীনে ঐচ্ছিক টেস্টিং-এ যোগ করুন। এটি করার জন্য, AHardwareBufferGLTest.cpp ফাইলের AHBFormatAsString(int32_t format) মধ্যে নতুন GL ফরম্যাটটি যোগ করুন এবং নতুন ফরম্যাটটির জন্য 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 যুক্ত করুন, এক্ষেত্রে HAL_PIXEL_FORMAT কনস্ট্যান্টের পরিবর্তে PixelFormat:: enum ব্যবহার করুন। “Add a new pixel format to 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.java তে @IntDef শেষে একটি নতুন এন্ট্রি যুক্ত করে HardwareBuffer SDK-তে নতুন পিক্সেল ফরম্যাটটি যোগ করুন। উদাহরণস্বরূপ, RGBA_8888 ফরম্যাটের এন্ট্রিটি নিচে দেখানো হলো:

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

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

  7. HardwareBuffer.java তে @Format এর শেষে একটি নতুন পাবলিক মেম্বার ভেরিয়েবল যুক্ত করে নতুন পিক্সেল ফরম্যাটটিকে একটি 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. HardwareBufferTest.java ফাইলের paramsForTestCreateOptionalFormats() ফাংশনের শেষে নতুন পিক্সেল ফরম্যাটটি যুক্ত করে জাভা টেস্টগুলিতে নতুন পিক্সেল ফরম্যাটটি যোগ করুন, যা নিম্নরূপভাবে দেখানো হলো:

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

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

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

নতুন পিক্সেল ফরম্যাটের জন্য ভলকান 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. পিক্সেল ফরম্যাটটি কাজ করার জন্য যদি ভলকান এক্সটেনশনের প্রয়োজন হয়, তবে ভলকান এক্সটেনশনটি কোয়েরি করুন। ইনস্ট্যান্স-সাইড এক্সটেনশনের জন্য, 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 তে কোনো ইনস্ট্যান্স বা ডিভাইস এক্সটেনশন প্রকাশ করার জন্য প্রয়োজনীয় পরিকাঠামো গুগল পরিচালনা করে। ভলকান লোডার থেকে এক্সটেনশনগুলো সঠিকভাবে সেটআপ করার জন্য প্রাথমিক পরিবর্তন তালিকার প্রয়োজন হয় না।

  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. বিদ্যমান সোর্স থেকে প্রয়োজনীয় পরিবর্তনগুলো অনুমান করে অথবা তথ্যের জন্য আপনার অ্যান্ড্রয়েড সাপোর্টের সাথে যোগাযোগ করে vktApiExternalMemoryTests.cpp এবং vktExternalMemoryUtil.cpp এ থাকা ভলকান কনফরমেন্স টেস্টগুলো আপডেট করুন।

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

নিম্নলিখিতভাবে EGL আপডেট করুন:

  1. getNativePixelFormat() ফাংশনে, নতুন পিক্সেল ফরম্যাটের জন্য AIDL enum রিটার্ন করতে 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,
      ...
    };
    

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

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