video: tegra: dc: global alpha on 1 layer blend
Donghan Ryu [Wed, 15 May 2013 14:16:01 +0000 (23:16 +0900)]
global alpha on 1 layer blending showed incorrect
blending because FIX_WEIGHT on B_BLEND_CONTROL_1WIN
is not per-pixel. This change programs premult and
coverage blending mode to produce following output.

premult case
    color.rgba = color.rgba * global_alpha;
    blended_color = previous_color * (1 - color.a) +
                    color;

coverage case
    color.a = color.a * global_alpha;
    blended_color = previous_color * (1 - color.a) +
                    vec4(color.rgb, 1) * color.a;

Bug 1276814

Change-Id: Ibb65fed58603e86ac8af4e4fd32f6c621eb57e7a
Signed-off-by: Donghan Ryu <dryu@nvidia.com>
Reviewed-on: http://git-master/r/228908
(cherry picked from commit 8f877cd48594945d0cca4e970755285f9b74ef2e)
Signed-off-by: Jon Mayo <jmayo@nvidia.com>
Reviewed-on: http://git-master/r/233375
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit

drivers/video/tegra/dc/window.c

index e6aec07..0f9a5fc 100644 (file)
@@ -132,8 +132,6 @@ static void tegra_dc_blend_parallel(struct tegra_dc *dc,
                                DC_CMD_DISPLAY_WINDOW_HEADER);
                tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff),
                                DC_WIN_BLEND_NOKEY);
-               tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff),
-                               DC_WIN_BLEND_1WIN);
                tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 0,
                                win_num), DC_WIN_BLEND_2WIN_X);
                tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 1,
@@ -490,6 +488,20 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
                        win_options |= CP_ENABLE;
                }
 #endif
+               if (!tegra_dc_feature_is_gen2_blender(dc, win->idx)) {
+                       if (win->flags &
+                                       TEGRA_WIN_FLAG_BLEND_COVERAGE) {
+                               tegra_dc_writel(dc,
+                                       BLEND(NOKEY, ALPHA, 0xff, 0xff),
+                                       DC_WIN_BLEND_1WIN);
+                       } else {
+                               /* global_alpha is 255 if not in use */
+                               tegra_dc_writel(dc,
+                                       BLEND(NOKEY, FIX, win->global_alpha,
+                                               win->global_alpha),
+                                       DC_WIN_BLEND_1WIN);
+                       }
+               }
 
                if (win->ppflags & TEGRA_WIN_PPFLAG_CP_ENABLE)
                        win_options |= CP_ENABLE;