[automerger skipped] Merge sc-v2-dev-plus-aosp-without-vendor@8084891 am: 6d3993bab0 -s ours am: fa896ec4d9 -s ours

am skip reason: Merged-In I3aa37a2a54caa0974cce0e3ec678845c19e33788 with SHA-1 e93c95aa15 is already in history

Original change: https://googleplex-android-review.googlesource.com/c/platform/bootable/recovery/+/16845164

Change-Id: I6036ae8a4365c49e79d4f150fab1725106392f23
diff --git a/minui/graphics.cpp b/minui/graphics.cpp
index 597f2ce..b24c2b1 100644
--- a/minui/graphics.cpp
+++ b/minui/graphics.cpp
@@ -36,7 +36,6 @@
 static int overscan_offset_y = 0;
 
 static uint32_t gr_current = ~0;
-static constexpr uint32_t alpha_mask = 0xff000000;
 
 // gr_draw is owned by backends.
 static GRSurface* gr_draw = nullptr;
@@ -79,7 +78,7 @@
 }
 
 // Blends gr_current onto pix value, assumes alpha as most significant byte.
-static inline uint32_t pixel_blend(uint8_t alpha, uint32_t pix) {
+static inline uint32_t pixel_blend_argb(uint8_t alpha, uint32_t pix) {
   if (alpha == 255) return gr_current;
   if (alpha == 0) return pix;
   uint32_t pix_r = pix & 0xff;
@@ -96,6 +95,48 @@
   return (out_r & 0xff) | (out_g & 0xff00) | (out_b & 0xff0000) | (gr_current & 0xff000000);
 }
 
+static inline uint32_t pixel_blend_rgba(uint8_t alpha, uint32_t pix) {
+  if (alpha == 255) return gr_current;
+  if (alpha == 0) return pix;
+  uint32_t pix_r = pix & 0xff00;
+  uint32_t pix_g = pix & 0xff0000;
+  uint32_t pix_b = pix & 0xff000000;
+  uint32_t cur_r = gr_current & 0xff00;
+  uint32_t cur_g = gr_current & 0xff0000;
+  uint32_t cur_b = gr_current & 0xff000000;
+
+  uint32_t out_r = (pix_r * (255 - alpha) + cur_r * alpha) / 255;
+  uint32_t out_g = (pix_g * (255 - alpha) + cur_g * alpha) / 255;
+  uint32_t out_b = (pix_b * (255 - alpha) + cur_b * alpha) / 255;
+
+  return (gr_current & 0xff) | (out_r & 0xff00) | (out_g & 0xff0000) | (out_b & 0xff000000);
+}
+
+static inline uint32_t pixel_blend(uint8_t alpha, uint32_t pix) {
+  if (pixel_format == PixelFormat::RGBA) {
+    return pixel_blend_rgba(alpha, pix);
+  }
+  return pixel_blend_argb(alpha, pix);
+}
+
+static inline uint32_t get_alphamask() {
+  if (pixel_format == PixelFormat::RGBA) {
+    return 0x000000ff;
+  }
+  return 0xff000000;
+}
+
+static inline uint8_t get_alpha_shift() {
+  if (pixel_format == PixelFormat::RGBA) {
+    return 0;
+  }
+  return 24;
+}
+
+static inline uint8_t get_alpha(uint32_t pix) {
+  return static_cast<uint8_t>((pix & (gr_current & get_alphamask())) >> get_alpha_shift());
+}
+
 // Increments pixel pointer right, with current rotation.
 static void incr_x(uint32_t** p, int row_pixels) {
   if (rotation == GRRotation::LEFT) {
@@ -143,7 +184,7 @@
 
 static void TextBlend(const uint8_t* src_p, int src_row_bytes, uint32_t* dst_p, int dst_row_pixels,
                       int width, int height) {
-  uint8_t alpha_current = static_cast<uint8_t>((alpha_mask & gr_current) >> 24);
+  uint8_t alpha_current = get_alpha(gr_current);
   for (int j = 0; j < height; ++j) {
     const uint8_t* sx = src_p;
     uint32_t* px = dst_p;
@@ -158,7 +199,7 @@
 }
 
 void gr_text(const GRFont* font, int x, int y, const char* s, bool bold) {
-  if (!font || !font->texture || (gr_current & alpha_mask) == 0) return;
+  if (!font || !font->texture || (gr_current & get_alphamask()) == 0) return;
 
   if (font->texture->pixel_bytes != 1) {
     printf("gr_text: font has wrong format\n");
@@ -213,6 +254,8 @@
   uint32_t r32 = r, g32 = g, b32 = b, a32 = a;
   if (pixel_format == PixelFormat::ARGB || pixel_format == PixelFormat::BGRA) {
     gr_current = (a32 << 24) | (r32 << 16) | (g32 << 8) | b32;
+  } else if (pixel_format == PixelFormat::RGBA) {
+    gr_current = (b32 << 24) | (g32 << 16) | (r32 << 8) | a32;
   } else {
     gr_current = (a32 << 24) | (b32 << 16) | (g32 << 8) | r32;
   }
@@ -247,7 +290,7 @@
 
   int row_pixels = gr_draw->row_bytes / gr_draw->pixel_bytes;
   uint32_t* p = PixelAt(gr_draw, x1, y1, row_pixels);
-  uint8_t alpha = static_cast<uint8_t>(((gr_current & alpha_mask) >> 24));
+  uint8_t alpha = get_alpha(gr_current);
   if (alpha > 0) {
     for (int y = y1; y < y2; ++y) {
       uint32_t* px = p;
@@ -369,6 +412,8 @@
     pixel_format = PixelFormat::ARGB;
   } else if (format == "BGRA_8888") {
     pixel_format = PixelFormat::BGRA;
+  } else if (format == "RGBA_8888") {
+    pixel_format = PixelFormat::RGBA;
   } else {
     pixel_format = PixelFormat::UNKNOWN;
   }
diff --git a/minui/include/minui/minui.h b/minui/include/minui/minui.h
index a2f62f0..f9be82f 100644
--- a/minui/include/minui/minui.h
+++ b/minui/include/minui/minui.h
@@ -102,6 +102,7 @@
   RGBX = 2,
   BGRA = 3,
   ARGB = 4,
+  RGBA = 5, // LSB Alpha
 };
 
 enum class GraphicsBackend : int {
diff --git a/minui/resources.cpp b/minui/resources.cpp
index d7b9277..1521c8f 100644
--- a/minui/resources.cpp
+++ b/minui/resources.cpp
@@ -153,32 +153,57 @@
                                int width) {
   const uint8_t* ip = input_row;
   uint8_t* op = output_row;
+  PixelFormat pixel_format = gr_pixel_format();
 
   switch (channels) {
     case 1:
       // expand gray level to RGBX
       for (int x = 0; x < width; ++x) {
-        *op++ = *ip;
-        *op++ = *ip;
-        *op++ = *ip;
-        *op++ = 0xff;
+        if (pixel_format == PixelFormat::RGBA) {
+          *op++ = 0xff;
+          *op++ = *ip;
+          *op++ = *ip;
+          *op++ = *ip;
+        } else {
+          *op++ = *ip;
+          *op++ = *ip;
+          *op++ = *ip;
+          *op++ = 0xff;
+        }
         ip++;
       }
       break;
 
     case 3:
-      // expand RGBA to RGBX
       for (int x = 0; x < width; ++x) {
-        *op++ = *ip++;
-        *op++ = *ip++;
-        *op++ = *ip++;
-        *op++ = 0xff;
+        // expand RGBA to RGBX
+        if (pixel_format == PixelFormat::RGBA) {
+            *op++ = 0xff;
+            *op++ = *ip++;
+            *op++ = *ip++;
+            *op++ = *ip++;
+        } else {
+            *op++ = *ip++;
+            *op++ = *ip++;
+            *op++ = *ip++;
+            *op++ = 0xff;
+        }
       }
       break;
 
     case 4:
-      // copy RGBA to RGBX
-      memcpy(output_row, input_row, width * 4);
+      if (pixel_format == PixelFormat::RGBA) {
+        for (int x = 0; x < width; ++x) {
+            *op++ = *(ip + 3);
+            *op++ = *ip++;
+            *op++ = *ip++;
+            *op++ = *ip++;
+            ip++;
+        }
+      } else {
+        // copy RGBA to RGBX
+        memcpy(output_row, input_row, width * 4);
+      }
       break;
   }
 }
@@ -201,6 +226,8 @@
   PixelFormat pixel_format = gr_pixel_format();
   if (pixel_format == PixelFormat::ARGB || pixel_format == PixelFormat::BGRA) {
     png_set_bgr(png_ptr);
+  } else if (pixel_format == PixelFormat::RGBA) {
+    png_set_swap_alpha(png_ptr);
   }
 
   for (png_uint_32 y = 0; y < height; ++y) {
@@ -273,6 +300,8 @@
 
   if (gr_pixel_format() == PixelFormat::ARGB || gr_pixel_format() == PixelFormat::BGRA) {
     png_set_bgr(png_ptr);
+  } else if (gr_pixel_format() == PixelFormat::RGBA) {
+    png_set_swap_alpha(png_ptr);
   }
 
   for (png_uint_32 y = 0; y < height; ++y) {
@@ -316,11 +345,6 @@
     return -8;
   }
 
-  PixelFormat pixel_format = gr_pixel_format();
-  if (pixel_format == PixelFormat::ARGB || pixel_format == PixelFormat::BGRA) {
-    png_set_bgr(png_ptr);
-  }
-
   for (png_uint_32 y = 0; y < height; ++y) {
     uint8_t* p_row = surface->data() + y * surface->row_bytes;
     png_read_row(png_ptr, p_row, nullptr);
diff --git a/tools/recovery_l10n/res/values-as/strings.xml b/tools/recovery_l10n/res/values-as/strings.xml
index 33a204d..d956b9a 100644
--- a/tools/recovery_l10n/res/values-as/strings.xml
+++ b/tools/recovery_l10n/res/values-as/strings.xml
@@ -6,9 +6,9 @@
     <string name="recovery_no_command" msgid="4465476568623024327">"কোনো আদেশ নাই"</string>
     <string name="recovery_error" msgid="5748178989622716736">"ত্ৰুটি!"</string>
     <string name="recovery_installing_security" msgid="9184031299717114342">"সুৰক্ষা আপডেইট ইনষ্টল কৰি থকা হৈছে"</string>
-    <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Android ছিষ্টেম ল\'ড কৰিব নোৱাৰি। আপোনাৰ ডেটাত কিবা আসোঁৱাহ থকা যেন লাগিছে। আপুনি যদি এই বাৰ্তাটো পায়েই থাকে, আপুনি নিজৰ ডিভাইচটো ফেক্টৰী ডেটা ৰিছেট কৰি সেইটোত থকা ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিব লগা হ\'ব পাৰে।"</string>
+    <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Android ছিষ্টেম ল\'ড কৰিব নোৱাৰি। আপোনাৰ ডেটাত কিবা আসোঁৱাহ থকা যেন লাগিছে। আপুনি যদি এই বাৰ্তাটো পায়েই থাকে, আপুনি নিজৰ ডিভাইচটো ফেক্টৰী ডেটা ৰিছেট কৰি সেইটোত থকা ব্যৱহাৰকাৰীৰ আটাইবোৰ ডেটা মচিব লগা হ\'ব পাৰে।"</string>
     <string name="recovery_try_again" msgid="7168248750158873496">"আকৌ চেষ্টা কৰক"</string>
     <string name="recovery_factory_data_reset" msgid="7321351565602894783">"ফেক্টৰী ডেটা ৰিছেট"</string>
-    <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিবনে?\n\n এইটো কৰাৰ পিছত আনডু কৰিব নোৱাৰি!"</string>
+    <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"ব্যৱহাৰকাৰীৰ আটাইবোৰ ডেটা মচিবনে?\n\n এইটো কৰাৰ পাছত আনডু কৰিব নোৱাৰি!"</string>
     <string name="recovery_cancel_wipe_data" msgid="66987687653647384">"বাতিল কৰক"</string>
 </resources>
diff --git a/tools/recovery_l10n/res/values-kn/strings.xml b/tools/recovery_l10n/res/values-kn/strings.xml
index a98f469..eafd831 100644
--- a/tools/recovery_l10n/res/values-kn/strings.xml
+++ b/tools/recovery_l10n/res/values-kn/strings.xml
@@ -8,7 +8,7 @@
     <string name="recovery_installing_security" msgid="9184031299717114342">"ಭದ್ರತೆಯ ಅಪ್‌ಡೇಟ್‌ ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Android ಸಿಸ್ಟಂ ಅನ್ನು ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ನಿಮ್ಮ ಡೇಟಾ ದೋಷಪೂರಿತವಾಗಿರಬಹುದು. ನೀವು ಈ ಸಂದೇಶ ಪಡೆಯುವುದು ಮುಂದುವರಿದರೆ, ನೀವು ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರಿಸೆಟ್ ಮಾಡುವ ಅಗತ್ಯವಿದೆ ಮತ್ತು ಈ ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸಬೇಕಾಗುತ್ತದೆ."</string>
     <string name="recovery_try_again" msgid="7168248750158873496">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
-    <string name="recovery_factory_data_reset" msgid="7321351565602894783">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರಿಸೆಟ್‌"</string>
+    <string name="recovery_factory_data_reset" msgid="7321351565602894783">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರೀಸೆಟ್"</string>
     <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸುವುದೇ?\n\n ಇದನ್ನು ರದ್ದುಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ!"</string>
     <string name="recovery_cancel_wipe_data" msgid="66987687653647384">"ರದ್ದುಮಾಡಿ"</string>
 </resources>
diff --git a/tools/recovery_l10n/res/values-sv/strings.xml b/tools/recovery_l10n/res/values-sv/strings.xml
index cf43b25..baf8e18 100644
--- a/tools/recovery_l10n/res/values-sv/strings.xml
+++ b/tools/recovery_l10n/res/values-sv/strings.xml
@@ -2,7 +2,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recovery_installing" msgid="2013591905463558223">"Systemuppdatering installeras"</string>
-    <string name="recovery_erasing" msgid="7334826894904037088">"Rensar"</string>
+    <string name="recovery_erasing" msgid="7334826894904037088">"Raderar"</string>
     <string name="recovery_no_command" msgid="4465476568623024327">"Inget kommando"</string>
     <string name="recovery_error" msgid="5748178989622716736">"Fel!"</string>
     <string name="recovery_installing_security" msgid="9184031299717114342">"Säkerhetsuppdatering installeras"</string>
diff --git a/tools/recovery_l10n/res/values-te/strings.xml b/tools/recovery_l10n/res/values-te/strings.xml
index 4d52114..ecea432 100644
--- a/tools/recovery_l10n/res/values-te/strings.xml
+++ b/tools/recovery_l10n/res/values-te/strings.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="2013591905463558223">"సిస్టమ్ నవీకరణను ఇన్‍స్టాల్ చేస్తోంది"</string>
+    <string name="recovery_installing" msgid="2013591905463558223">"సిస్టమ్ అప్‌డేట్‌ను ఇన్‍స్టాల్ చేస్తోంది"</string>
     <string name="recovery_erasing" msgid="7334826894904037088">"డేటాను తొలగిస్తోంది"</string>
     <string name="recovery_no_command" msgid="4465476568623024327">"ఆదేశం లేదు"</string>
     <string name="recovery_error" msgid="5748178989622716736">"ఎర్రర్ సంభవించింది!"</string>
-    <string name="recovery_installing_security" msgid="9184031299717114342">"భద్రతా నవీకరణను ఇన్‌స్టాల్ చేస్తోంది"</string>
-    <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Android సిస్టమ్‌ని లోడ్ చేయడం సాధ్యం కాదు. మీ డేటా పాడై ఉండవచ్చు. మీకు ఈ సందేశం వస్తూనే ఉంటే, మీరు ఫ్యాక్టరీ డేటా రీసెట్ చేసి, పరికరంలో నిల్వ అయిన వినియోగదారు డేటా మొత్తాన్ని తొలగించాల్సి రావచ్చు."</string>
+    <string name="recovery_installing_security" msgid="9184031299717114342">"సెక్యూరిటీ అప్‌డేట్‌ను ఇన్‌స్టాల్ చేస్తోంది"</string>
+    <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Android సిస్టమ్‌ని లోడ్ చేయడం సాధ్యం కాదు. మీ డేటా పాడై ఉండవచ్చు. మీకు ఈ మెసేజ్‌ వస్తూనే ఉంటే, మీరు ఫ్యాక్టరీ డేటా రీసెట్ చేసి, పరికరంలో నిల్వ అయిన వినియోగదారు డేటా మొత్తాన్ని తొలగించాల్సి రావచ్చు."</string>
     <string name="recovery_try_again" msgid="7168248750158873496">"మళ్లీ ప్రయత్నించు"</string>
     <string name="recovery_factory_data_reset" msgid="7321351565602894783">"ఫ్యాక్టరీ డేటా రీసెట్"</string>
     <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"వినియోగదారు డేటా మొత్తాన్ని తొలగించాలా?\n\n ఈ చర్యను రద్దు చేయలేరు!"</string>