hwc: support blending
authorGreg Hackmann <ghackmann@google.com>
Fri, 3 Aug 2012 20:29:33 +0000 (13:29 -0700)
committerGreg Hackmann <ghackmann@google.com>
Wed, 15 Aug 2012 21:03:30 +0000 (14:03 -0700)
Also remove support for RGBA-4444 surfaces, since the blending hardware
must be configured with the same alpha width across all windows

Change-Id: I0b011d309e760c52355a2d3e20828cc74640c4c4
Signed-off-by: Greg Hackmann <ghackmann@google.com>
include/s3c-fb.h
libhwc/hwc.cpp
original-kernel-headers/linux/s3c-fb.h

index 159159ad1709a31db83a3a89169e923fb91a8752..b1b57b576c5769ea8e6cfbc84453e1d5ff26927c 100644 (file)
@@ -48,48 +48,55 @@ enum s3c_fb_pixel_format {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
  S3C_FB_PIXEL_FORMAT_RGBX_8888 = 1,
  S3C_FB_PIXEL_FORMAT_RGBA_5551 = 2,
- S3C_FB_PIXEL_FORMAT_RGBA_4444 = 3,
- S3C_FB_PIXEL_FORMAT_MAX = 4,
+ S3C_FB_PIXEL_FORMAT_MAX = 3,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum s3c_fb_blending {
+ S3C_FB_BLENDING_NONE = 0,
+ S3C_FB_BLENDING_PREMULT = 1,
+ S3C_FB_BLENDING_COVERAGE = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ S3C_FB_BLENDING_MAX = 3,
 };
 struct s3c_fb_win_config {
  enum {
- S3C_FB_WIN_STATE_DISABLED = 0,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ S3C_FB_WIN_STATE_DISABLED = 0,
  S3C_FB_WIN_STATE_COLOR,
  S3C_FB_WIN_STATE_BUFFER,
  } state;
- union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ union {
  __u32 color;
  struct {
  int fd;
- __u32 offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u32 offset;
  __u32 stride;
  enum s3c_fb_pixel_format format;
+ enum s3c_fb_blending blending;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
  };
  };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
  int x;
  int y;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
  __u32 w;
  __u32 h;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define S3C_FB_MAX_WIN (5)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct s3c_fb_win_config_data {
  int fence;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
  struct s3c_fb_win_config config[S3C_FB_MAX_WIN];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define S3CFB_WIN_POSITION _IOW('F', 203,   struct s3c_fb_user_window)
 #define S3CFB_WIN_SET_PLANE_ALPHA _IOW('F', 204,   struct s3c_fb_user_plane_alpha)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define S3CFB_WIN_SET_CHROMA _IOW('F', 205,   struct s3c_fb_user_chroma)
 #define S3CFB_SET_VSYNC_INT _IOW('F', 206, __u32)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define S3CFB_GET_ION_USER_HANDLE _IOWR('F', 208,   struct s3c_fb_user_ion_client)
 #define S3CFB_WIN_CONFIG _IOW('F', 209,   struct s3c_fb_win_config_data)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
 
index e856e6346a1a773732fe9d26e47fefb5956f3592..289d7a5048165324b4e34a54d2c94d79bf2c4917 100644 (file)
@@ -144,10 +144,10 @@ static void dump_config(s3c_fb_win_config &c)
     if (c.state == c.S3C_FB_WIN_STATE_BUFFER) {
         ALOGV("\t\tfd = %d, offset = %u, stride = %u, "
                 "x = %d, y = %d, w = %u, h = %u, "
-                "format = %u",
+                "format = %u, blending = %u",
                 c.fd, c.offset, c.stride,
                 c.x, c.y, c.w, c.h,
-                c.format);
+                c.format, c.blending);
     }
     else if (c.state == c.S3C_FB_WIN_STATE_COLOR) {
         ALOGV("\t\tcolor = %u", c.color);
@@ -193,8 +193,6 @@ static enum s3c_fb_pixel_format exynos5_format_to_s3c_format(int format)
         return S3C_FB_PIXEL_FORMAT_RGBX_8888;
     case HAL_PIXEL_FORMAT_RGBA_5551:
         return S3C_FB_PIXEL_FORMAT_RGBA_5551;
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-        return S3C_FB_PIXEL_FORMAT_RGBA_4444;
 
     default:
         return S3C_FB_PIXEL_FORMAT_MAX;
@@ -346,6 +344,26 @@ int hdmi_get_config(struct exynos5_hwc_composer_device_1_t *dev)
     return found ? 0 : -1;
 }
 
+static enum s3c_fb_blending exynos5_blending_to_s3c_blending(int32_t blending)
+{
+    switch (blending) {
+    case HWC_BLENDING_NONE:
+        return S3C_FB_BLENDING_NONE;
+    case HWC_BLENDING_PREMULT:
+        return S3C_FB_BLENDING_PREMULT;
+    case HWC_BLENDING_COVERAGE:
+        return S3C_FB_BLENDING_COVERAGE;
+
+    default:
+        return S3C_FB_BLENDING_MAX;
+    }
+}
+
+static bool exynos5_blending_is_supported(int32_t blending)
+{
+    return exynos5_blending_to_s3c_blending(blending) < S3C_FB_BLENDING_MAX;
+}
+
 static int hdmi_enable(struct exynos5_hwc_composer_device_1_t *dev)
 {
     if (dev->hdmi_mirroring)
@@ -441,9 +459,8 @@ bool exynos5_supports_overlay(hwc_layer_1_t &layer, size_t i)
             return false;
         }
     }
-    if (layer.blending != HWC_BLENDING_NONE) {
-        // TODO: support this
-        ALOGV("\tlayer %u: blending not supported", i);
+    if (!exynos5_blending_is_supported(layer.blending)) {
+        ALOGV("\tlayer %u: blending %d not supported", i, layer.blending);
         return false;
     }
 
@@ -815,7 +832,7 @@ err_alloc:
 
 static void exynos5_config_handle(private_handle_t *handle,
         hwc_rect_t &sourceCrop, hwc_rect_t &displayFrame,
-        s3c_fb_win_config &cfg)
+        int32_t blending, s3c_fb_win_config &cfg)
 {
     cfg.state = cfg.S3C_FB_WIN_STATE_BUFFER;
     cfg.fd = handle->fd;
@@ -827,6 +844,7 @@ static void exynos5_config_handle(private_handle_t *handle,
     uint8_t bpp = exynos5_format_to_bpp(handle->format);
     cfg.offset = (sourceCrop.top * handle->stride + sourceCrop.left) * bpp / 8;
     cfg.stride = handle->stride * bpp / 8;
+    cfg.blending = exynos5_blending_to_s3c_blending(blending);
 }
 
 static void exynos5_config_overlay(hwc_layer_1_t *layer, s3c_fb_win_config &cfg,
@@ -844,7 +862,8 @@ static void exynos5_config_overlay(hwc_layer_1_t *layer, s3c_fb_win_config &cfg,
     }
 
     private_handle_t *handle = private_handle_t::dynamicCast(layer->handle);
-    exynos5_config_handle(handle, layer->sourceCrop, layer->displayFrame, cfg);
+    exynos5_config_handle(handle, layer->sourceCrop, layer->displayFrame,
+            layer->blending, cfg);
 }
 
 static void exynos5_post_callback(void *data, private_handle_t *fb)
@@ -880,7 +899,9 @@ static void exynos5_post_callback(void *data, private_handle_t *fb)
     for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
         if (i == pdata->fb_window) {
             hwc_rect_t rect = { 0, 0, fb->width, fb->height };
-            exynos5_config_handle(fb, rect, rect, config[i]);
+            int32_t blending = (i == 0) ? HWC_BLENDING_NONE :
+                    HWC_BLENDING_PREMULT;
+            exynos5_config_handle(fb, rect, rect, blending, config[i]);
         } else if ( pdata->overlay_map[i] != -1) {
             hwc_layer_1_t &layer = pdata->overlays[i];
             private_handle_t *handle =
@@ -909,13 +930,18 @@ static void exynos5_post_callback(void *data, private_handle_t *fb)
                 private_handle_t *dst_handle =
                         private_handle_t::dynamicCast(dst_buf);
                 exynos5_config_handle(dst_handle, layer.sourceCrop,
-                        layer.displayFrame, config[i]);
+                        layer.displayFrame, layer.blending, config[i]);
             }
             else {
                 exynos5_config_overlay(&layer, config[i],
                         pdata->pdev->gralloc_module);
             }
         }
+        if (i == 0 && config[i].blending != S3C_FB_BLENDING_NONE) {
+            ALOGV("blending not supported on window 0; forcing BLENDING_NONE");
+            config[i].blending = S3C_FB_BLENDING_NONE;
+        }
+
         ALOGV("window %u configuration:", i);
         dump_config(config[i]);
     }
index 0a38c9b7981367f5daa1b0ed43e57eb4588965af..223d011b54ff1f592c14ec283bc2b8ebb574a41a 100644 (file)
@@ -43,8 +43,14 @@ enum s3c_fb_pixel_format {
        S3C_FB_PIXEL_FORMAT_RGBA_8888 = 0,
        S3C_FB_PIXEL_FORMAT_RGBX_8888 = 1,
        S3C_FB_PIXEL_FORMAT_RGBA_5551 = 2,
-       S3C_FB_PIXEL_FORMAT_RGBA_4444 = 3,
-       S3C_FB_PIXEL_FORMAT_MAX = 4,
+       S3C_FB_PIXEL_FORMAT_MAX = 3,
+};
+
+enum s3c_fb_blending {
+       S3C_FB_BLENDING_NONE = 0,
+       S3C_FB_BLENDING_PREMULT = 1,
+       S3C_FB_BLENDING_COVERAGE = 2,
+       S3C_FB_BLENDING_MAX = 3,
 };
 
 struct s3c_fb_win_config {
@@ -57,10 +63,11 @@ struct s3c_fb_win_config {
        union {
                __u32 color;
                struct {
-                       int     fd;
-                       __u32   offset;
-                       __u32   stride;
-                       enum s3c_fb_pixel_format format;
+                       int                             fd;
+                       __u32                           offset;
+                       __u32                           stride;
+                       enum s3c_fb_pixel_format        format;
+                       enum s3c_fb_blending            blending;
                };
        };