Android'e yeni piksel formatları ekleme

Android'e eklenen tüm yeni piksel biçimlerinin , Android Arayüz Tanımlama Dili'ne (AIDL) ve Android Donanım Arabelleğine (AHB) dahil edilmesi gerekir. AIDL ve AHB, işlevselliği genişletirken dikkatli bir süreç gerektiren katı stabilite ve standardizasyon gereksinimlerine sahiptir. Tüm yeni piksel formatları AOSP'ye gelmeli ve tüm güncellemeler AIDL ve AHB uzmanları tarafından ayrı ayrı onaylanmalıdır. Bu dikkatli doğrulama süreci, platformdaki yeni piksel formatlarının standartlaştırılmasında önemli bir faktördür.

Bu sayfada gerekli AOSP kodu değişiklikleri ve AOSP'ye yeni piksel formatları eklemek için gereken süreç özetlenmektedir.

Yeni bir piksel formatı eklemeden önce, kaynağı indirin ve Yamaları Gönderme bölümünde belirtildiği gibi yamaları yükleyin.

AIDL'ye yeni bir piksel formatı ekleme

Yeni bir piksel biçimi için destek eklemek, AIDL'de bulunan PixelFormat.aidl dosyalarının her ikisinde de değişiklik yapılmasını gerektirir. AIDL kaynak kodu için hardware/interfaces/graphics/common/aidl/ bakın.

AIDL'ye yeni bir piksel resmi eklemek için şu adımları izleyin:

  1. Mevcut kod kuralını takip ederek ve girişinizin onaltılık değerini önceki girişten bir fazla olacak şekilde ayarlayarak, yeni piksel biçimini PixelFormat.aidl PixelFormat numaralandırmasının sonuna yeni bir giriş olarak ekleyin. Kod değişikliklerinizi önceki girişlerle eşleştirin. RGBA_8888 piksel biçimi girişi için aşağıdaki örneğe bakın:
    /**
     * 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 değişiklik yaptıktan sonra kodu oluşturduğunuzda aşağıdaki hata mesajı görülüyor:

    android_developer:~/android/aosp-main: 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. Bu hatayı temizlemek için, aidl_api dizinindeki PixelFormat.aidl değiştirmek üzere hata mesajında ​​belirtildiği gibi aşağıdaki komutu çalıştırın:

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

    Yukarıdaki komutu çalıştırmak, normal şekilde oluşturulabilmesi için doğru dosyayı günceller.

AHB'ye yeni bir piksel formatı ekleme

Yeni bir piksel formatı için destek eklemek, hardware_buffer.h ve AHardwareBuffer.cpp değişiklik yapılmasını gerektirir. AHB kaynak kodu için frameworks/native/libs/nativewindow bakın.

AHB'ye yeni bir piksel resmi eklemek için şu adımları izleyin:

  1. hardware_buffer.h dosyasında, yeni piksel biçimini AHardwareBuffer_Format numaralandırmasının sonuna yeni bir giriş olarak ekleyin. Mevcut kod kurallarına uyun.

    RGBA_8888 piksel formatı örneğini kullanarak yeni piksel formatı girişini aşağıdaki gibi ekleyin:

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

    Yeni piksel formatına AHB'de AHARDWAREBUFFER_FORMAT_ ile başlaması, ardından kanal kısaltmaları ve bit derinlikleri ve kodlamayla bitmesi gereken bir ad verildiğini unutmayın. Bu numaralandırma girişinin PixelFormat.aidl aynı onaltılık değere sahip olması gerekir.

    Piksel formatının ilişkili Vulkan veya OpenGL ES formatlarından birine veya her ikisine sahip olması bekleniyor. Uygun olduğu yerde ilişkili formatı belirtin. İlişkili bir format yoksa N/A belirtin.

  2. İlgili bir OpenGL ES formatı varsa, piksel formatını CTS altındaki isteğe bağlı teste ekleyin. Bunu yapmak için, yeni GL formatını, aşağıda gösterildiği gibi yeni format için FORMAT_CASE(...) ve GL_FORMAT_CASE(...) ile AHBFormatAsString(int32_t format) içindeki AHardwareBufferGLTest.cpp dosyasına ekleyin:

    const char* AHBFormatAsString(int32_t format) {
      switch (format) {
          ...
          FORMAT_CASE(R8G8B8A8_UNORM);
          ...
          GL_FORMAT_CASE(GL_RGB8);
      }
      return "";
    }
    
  3. Daha sonra, AHardwareBufferGLTest.cpp dosyasına aşağıda gösterildiği gibi yeni bir test ekleyin:

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

    En az bir AHardwareBuffer_Desc değeri kümesi belirtin. Gerekirse daha fazla değer ekleyin.

  4. AHardwareBuffer.cpp , içinde bulunan statik iddiaların sonunu bulun:

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

    Yeni piksel biçimi için HAL_PIXEL_FORMAT sabitini değil, PixelFormat:: numaralandırmasını kullanarak yeni bir static_assert ekleyin. AIDL'ye yeni bir piksel formatı ekleme bölümündeki RGBA_8888 piksel formatı için aynı örneği kullanarak, yeni piksel formatı girişini aşağıdaki gibi ekleyin:

    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. Yeni piksel biçimini AHardwareBufferTest.cpp dosyasındaki PrintAhbFormat() öğesinin sonuna ekleyerek yeni piksel biçimini uygun testlere ekleyin. Aşağıda gösterildiği gibi mevcut kod kuralını izleyin:

    void PrintAhbFormat(std::ostream& os, uint64_t format) {
        switch (format) {
            ...
            FORMAT_CASE(R8G8B8A8_UNORM);
            default: os << "unknown"; break;
        }
    }
    
  6. Yeni piksel biçimini HardwareBuffer.java HardwareBuffer SDK'sına ekleyin: @IntDef yeni bir giriş ekleyerek. Örneğin RGBA_8888 formatına ilişkin giriş şu şekilde gösterilmektedir:

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

    Bileşen değerleri işaretsiz normalleştirilmiş değilse, değişken adında değeri açıkça belirtin. Örneğin, yalnızca işaretsiz tam sayı 16 bit kırmızı kanal biçimi için değişken adı R_16UI olmalıdır ve ek işaretsiz tam sayı 16 bit yeşil kanal biçimiyle aynı biçim RG_16UI16UI olmalıdır.

  7. @Format sonuna yeni bir genel üye değişkeni ekleyerek yeni piksel biçimini HardwareBuffer.java dosyasına static int olarak ekleyin:

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

    Bu numaralandırma girişinin PixelFormat.aidl ve hardware_buffer.h ile aynı onaltılık değere sahip olması gerekir. Mevcut kuralları takip edin.

  8. Bu kod değişiklikleriyle derlemeye çalışmak bir derleme hatası oluşturur:

    android_developer:~/android/aosp-main: 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.
    ******************************
    ...
    

    Bu hatayı temizlemek için, hata iletisinde belirtildiği gibi aşağıdaki komutu çalıştırarak current.txt değiştirin:

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

    Yukarıdaki komutu çalıştırmak, normal şekilde oluşturulabilmesi için doğru dosyayı günceller.

  9. Yeni piksel biçimini, HardwareBufferTest.java dosyasındaki paramsForTestCreateOptionalFormats() öğesinin sonuna ekleyerek, aşağıda gösterildiği şekilde Java testlerine ekleyin:

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

Pencere Sistemi entegrasyonuna yeni bir piksel formatı ekleme

Yeni piksel biçimini bir grafik API'sindeki çerçeve arabelleğinin biçimi olarak kullanmak için, bunu ilgili grafik API'sine yönelik uygun Pencere Sistemi Entegrasyonuna (WSI) ekleyin. Vulkan API'sini kullanan bir uygulama veya sistem işlemi için Vulkan Swapchain'i güncelleyin. OpenGL ES API'sini kullanan bir uygulama veya sistem işlemi için EGL API'sini güncelleyin.

Yeni piksel formatları için Vulkan WSI değişiklikleri

Vulkan WSI'yi aşağıdaki şekilde güncelleyin:
  1. swapchain.cpp GetNativePixelFormat(VkFormat format) işlevine yeni bir vaka ekleyin:

    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. Piksel formatının çalışması için bir Vulkan uzantısı gerekiyorsa Vulkan uzantısını sorgulayın. Örneğin yan uzantılar, aşağıdaki şekilde gösterilen instance_data kullanın:
    bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
    

    Cihaz tarafı uzantıları için aşağıdakileri kullanın:

    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;
        }
    }
    

    Bir örneğin veya cihaz uzantısının swapchain.cpp sunulması için gereken altyapıyı Google üstlenir. Uzantıların Vulkan yükleyiciden doğru şekilde kurulması için ilk değişiklik listesine gerek yoktur.

  3. Daha sonra format ve renk alanı çiftlerini numaralandırın:
    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});
    }
    

    Uyumlu format ve renk alanı çiftleri hakkında bilgi sahibi olmanız gerekir.

  4. Yeni formatı external/deqp konumunda bulunan dEQP-VK ekleyin.
  5. Gerekli değişiklikleri mevcut kaynaktan çıkararak veya bilgi için Android desteğinize ulaşarak vktApiExternalMemoryTests.cpp ve vktExternalMemoryUtil.cpp Vulkan Uyumluluk Testlerini güncelleyin.

Yeni piksel formatları için EGL değişiklikleri

EGL'yi aşağıdaki şekilde güncelleyin:

  1. getNativePixelFormat() işlevinde, yeni piksel biçiminin AIDL numaralandırmasını döndürmek için if-else ağacını değiştirin. RGBA_8888 piksel formatı örneğini kullanma:
    if (a == 0) {
      ...
    } else {
      if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
          if (colorDepth > 24) {
              ...
          } else {
              *format = PixelFormat::RGBA_8888;
          }
      } else {
        ...
      }
    }
    
  2. Yeni formatı dEQP'ye eklemek için androidFormats numaralandırmasına aşağıda gösterildiği gibi yeni bir giriş ekleyin:
    static const GLenum androidFormats[] =
    {
      ...
      GL_RGBA8,
      ...
    };
    

Güncellemenizi gönderin

Takip Edin Katkıda bulunanların değişiklik listelerinizi hızlandırması ve bunları uygun ekiple paylaşması için .