Bug 1256475 - Use libyuv for non scaling YUV color conversion r=jrmuizel
☠☠ backed out by d8c954e520e4 ☠ ☠
authorSotaro Ikeda <sotaro.ikeda.g@gmail.com>
Mon, 06 Jun 2016 20:10:59 -0700
changeset 340815 c88f2cb8e4fae6764f559c0e43a93edd518102d2
parent 340814 851259fb3bc45b0ef5c54c390fb953ec0789096d
child 340816 b093026fc747724b11856fcf72e6dccfdaac829c
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1256475
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1256475 - Use libyuv for non scaling YUV color conversion r=jrmuizel
gfx/thebes/gfxPrefs.h
gfx/thebes/gfxUtils.cpp
gfx/ycbcr/chromium_types.h
gfx/ycbcr/moz.build
gfx/ycbcr/yuv_convert.cpp
gfx/ycbcr/yuv_convert.h
layout/reftests/webm-video/reftest.list
modules/libpref/init/all.js
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -268,16 +268,17 @@ private:
   DECL_GFX_PREF(Once, "gfx.logging.peak-texture-usage.enabled",GfxLoggingPeakTextureUsageEnabled, bool, false);
   DECL_GFX_PREF(Once, "gfx.max-alloc-size",                    MaxAllocSize, int32_t, (int32_t)500000000);
   DECL_GFX_PREF(Once, "gfx.max-texture-size",                  MaxTextureSize, int32_t, (int32_t)32767);
   DECL_GFX_PREF(Live, "gfx.partialpresent.force",              PartialPresent, int32_t, 0);
   DECL_GFX_PREF(Live, "gfx.perf-warnings.enabled",             PerfWarnings, bool, false);
   DECL_GFX_PREF(Live, "gfx.SurfaceTexture.detach.enabled",     SurfaceTextureDetachEnabled, bool, true);
   DECL_GFX_PREF(Live, "gfx.testing.device-reset",              DeviceResetForTesting, int32_t, 0);
   DECL_GFX_PREF(Live, "gfx.testing.device-fail",               DeviceFailForTesting, bool, false);
+  DECL_GFX_PREF(Live, "gfx.ycbcr.accurate-conversion",         YCbCrAccurateConversion, bool, false);
 
   DECL_GFX_PREF(Live, "gfx.content.use-native-pushlayer",      UseNativePushLayer, bool, false);
 
   // Disable surface sharing due to issues with compatible FBConfigs on
   // NVIDIA drivers as described in bug 1193015.
   DECL_GFX_PREF(Live, "gfx.use-glx-texture-from-pixmap",       UseGLXTextureFromPixmap, bool, false);
 
   // These times should be in milliseconds
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -26,18 +26,16 @@
 #include "nsComponentManagerUtils.h"
 #include "nsIClipboardHelper.h"
 #include "nsIFile.h"
 #include "nsIGfxInfo.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsRegion.h"
 #include "nsServiceManagerUtils.h"
-#include "yuv_convert.h"
-#include "ycbcr_to_rgb565.h"
 #include "GeckoProfiler.h"
 #include "ImageContainer.h"
 #include "ImageRegion.h"
 #include "gfx2DGlue.h"
 #include "gfxPrefs.h"
 
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"
--- a/gfx/ycbcr/chromium_types.h
+++ b/gfx/ycbcr/chromium_types.h
@@ -2,24 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef GFX_CHROMIUMTYPES_H
 #define GFX_CHROMIUMTYPES_H
 
 #include <stdint.h>
 
-// On Windows, protypes.h is #included, which defines these types.  This sucks!
-#ifndef PROTYPES_H
-typedef uint8_t uint8;
-typedef int8_t int8;
-typedef int16_t int16;
-typedef uint16_t uint16;
-typedef uint32_t uint32;
-#endif
+#include "libyuv/basic_types.h"
 
 // From Chromium build_config.h:
 // Processor architecture detection.  For more info on what's defined, see:
 //   http://msdn.microsoft.com/en-us/library/b0084kay.aspx
 //   http://www.agner.org/optimize/calling_conventions.pdf
 //   or with gcc, run: "echo | gcc -E -dM -"
 #if defined(_M_X64) || defined(__x86_64__)
 #define ARCH_CPU_X86_FAMILY 1
--- a/gfx/ycbcr/moz.build
+++ b/gfx/ycbcr/moz.build
@@ -1,20 +1,16 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS += [
-    'chromium_types.h',
-    'ycbcr_to_rgb565.h',
     'YCbCrUtils.h',
-    'yuv_convert.h',
-    'yuv_row.h',
 ]
 
 UNIFIED_SOURCES += [
     'ycbcr_to_rgb565.cpp',
     'YCbCrUtils.cpp',
     'yuv_convert.cpp',
     'yuv_row_c.cpp',
     'yuv_row_table.cpp',
@@ -58,9 +54,11 @@ else:
 if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['HAVE_ARM_NEON']:
     SOURCES += [
         'yuv_row_arm.s',
     ]
     SOURCES += [
         'yuv_convert_arm.cpp',
     ]
 
+LOCAL_INCLUDES += ['/media/libyuv/include']
+
 FINAL_LIBRARY = 'xul'
--- a/gfx/ycbcr/yuv_convert.cpp
+++ b/gfx/ycbcr/yuv_convert.cpp
@@ -13,16 +13,18 @@
 // YV16 is a full plane of Y and a full height, half width chroma planes
 // YV24 is a full plane of Y and a full height, full width chroma planes
 //
 // ARGB pixel format is output, which on little endian is stored as BGRA.
 // The alpha is set to 255, allowing the application to use RGBA or RGB32.
 
 #include "yuv_convert.h"
 
+#include "gfxPrefs.h"
+#include "libyuv.h"
 // Header for low level row functions.
 #include "yuv_row.h"
 #include "mozilla/SSE.h"
 
 namespace mozilla {
 
 namespace gfx {
 
@@ -55,16 +57,82 @@ void ConvertYCbCrToRGB32(const uint8* y_
                          int pic_x,
                          int pic_y,
                          int pic_width,
                          int pic_height,
                          int y_pitch,
                          int uv_pitch,
                          int rgb_pitch,
                          YUVType yuv_type) {
+
+
+  // Deprecated function's conversion is accurate.
+  // libyuv converion is a bit inaccurate to get performance. It dynamically
+  // calculates RGB from YUV to use simd. In it, signed byte is used for conversion's
+  // coefficient, but it requests 129. libyuv cut 129 to 127. And only 6 bits are
+  // used for a decimal part during the dynamic calculation.
+  //
+  // The function is still fast on some old intel chips.
+  // See Bug 1256475.
+  bool use_deprecated = gfxPrefs::YCbCrAccurateConversion() ||
+                        (supports_mmx() && supports_sse() && !supports_sse3());
+  if (use_deprecated) {
+    ConvertYCbCrToRGB32_deprecated(y_buf, u_buf, v_buf, rgb_buf,
+                                   pic_x, pic_y, pic_width, pic_height,
+                                   y_pitch, uv_pitch, rgb_pitch, yuv_type);
+    return;
+  }
+                                    
+  if (yuv_type == YV24) {
+    const uint8* src_y = y_buf + y_pitch * pic_y + pic_x;
+    const uint8* src_u = u_buf + uv_pitch * pic_y + pic_x;
+    const uint8* src_v = v_buf + uv_pitch * pic_y + pic_x;
+    DebugOnly<int> err = libyuv::I444ToARGB(src_y, y_pitch,
+                                            src_u, uv_pitch,
+                                            src_v, uv_pitch,
+                                            rgb_buf, rgb_pitch,
+                                            pic_width, pic_height);
+    MOZ_ASSERT(!err);
+  } else if (yuv_type == YV16) {
+    const uint8* src_y = y_buf + y_pitch * pic_y + pic_x;
+    const uint8* src_u = u_buf + uv_pitch * pic_y + pic_x / 2;
+    const uint8* src_v = v_buf + uv_pitch * pic_y + pic_x / 2;
+    DebugOnly<int> err = libyuv::I422ToARGB(src_y, y_pitch,
+                                            src_u, uv_pitch,
+                                            src_v, uv_pitch,
+                                            rgb_buf, rgb_pitch,
+                                            pic_width, pic_height);
+    MOZ_ASSERT(!err);
+  } else {
+    MOZ_ASSERT(yuv_type == YV12);
+    const uint8* src_y = y_buf + y_pitch * pic_y + pic_x;
+    const uint8* src_u = u_buf + (uv_pitch * pic_y + pic_x) / 2;
+    const uint8* src_v = v_buf + (uv_pitch * pic_y + pic_x) / 2;
+    DebugOnly<int> err = libyuv::I420ToARGB(src_y, y_pitch,
+                                            src_u, uv_pitch,
+                                            src_v, uv_pitch,
+                                            rgb_buf, rgb_pitch,
+                                            pic_width, pic_height);
+    MOZ_ASSERT(!err);
+  }
+}
+
+// Convert a frame of YUV to 32 bit ARGB.
+void ConvertYCbCrToRGB32_deprecated(const uint8* y_buf,
+                                    const uint8* u_buf,
+                                    const uint8* v_buf,
+                                    uint8* rgb_buf,
+                                    int pic_x,
+                                    int pic_y,
+                                    int pic_width,
+                                    int pic_height,
+                                    int y_pitch,
+                                    int uv_pitch,
+                                    int rgb_pitch,
+                                    YUVType yuv_type) {
   unsigned int y_shift = yuv_type == YV12 ? 1 : 0;
   unsigned int x_shift = yuv_type == YV24 ? 0 : 1;
   // Test for SSE because the optimized code uses movntq, which is not part of MMX.
   bool has_sse = supports_mmx() && supports_sse();
   // There is no optimized YV24 SSE routine so we check for this and
   // fall back to the C code.
   has_sse &= yuv_type != YV24;
   bool odd_pic_x = yuv_type != YV24 && pic_x % 2 != 0;
--- a/gfx/ycbcr/yuv_convert.h
+++ b/gfx/ycbcr/yuv_convert.h
@@ -52,16 +52,29 @@ void ConvertYCbCrToRGB32(const uint8* yp
                          int pic_y,
                          int pic_width,
                          int pic_height,
                          int ystride,
                          int uvstride,
                          int rgbstride,
                          YUVType yuv_type);
 
+void ConvertYCbCrToRGB32_deprecated(const uint8* yplane,
+                                    const uint8* uplane,
+                                    const uint8* vplane,
+                                    uint8* rgbframe,
+                                    int pic_x,
+                                    int pic_y,
+                                    int pic_width,
+                                    int pic_height,
+                                    int ystride,
+                                    int uvstride,
+                                    int rgbstride,
+                                    YUVType yuv_type);
+
 // Scale a frame of YUV to 32 bit ARGB.
 // Supports rotation and mirroring.
 void ScaleYCbCrToRGB32(const uint8* yplane,
                        const uint8* uplane,
                        const uint8* vplane,
                        uint8* rgbframe,
                        int source_width,
                        int source_height,
--- a/layout/reftests/webm-video/reftest.list
+++ b/layout/reftests/webm-video/reftest.list
@@ -34,17 +34,17 @@ skip-if(Android||B2G||Mulet) == poster-1
 skip-if(Android||B2G||Mulet) == poster-15.html poster-ref-green70x30.html # Initial mulet triage: parity with B2G/B2G Desktop
 random-if(winWidget) random-if(cocoaWidget) skip-if(Android||B2G||Mulet) == bug686957.html bug686957-ref.html # bug 922951 for OS X # Initial mulet triage: parity with B2G/B2G Desktop
 
 # Tests for <video src> with 'object-fit' & 'object-position':
 # These tests should be very similar to tests in our w3c-css/submitted/images3
 # reftest directory. They live here because they use WebM video (VP9), and it
 # wouldn't be fair of us to make a W3C testsuite implicitly depend on any
 # particular (non-spec-mandated) video codec.
-default-preferences test-pref(layout.css.object-fit-and-position.enabled,true)
+default-preferences test-pref(layout.css.object-fit-and-position.enabled,true) test-pref(gfx.ycbcr.accurate-conversion,true)
 fails-if(layersGPUAccelerated) skip-if(Android||B2G||Mulet) == object-fit-contain-webm-001.html object-fit-contain-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android/B2G failures # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(layersGPUAccelerated) skip-if(Android||B2G||Mulet) == object-fit-contain-webm-002.html object-fit-contain-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android/B2G failures # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(layersGPUAccelerated) skip-if(Android||B2G||Mulet) == object-fit-cover-webm-001.html object-fit-cover-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android/B2G failures # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(layersGPUAccelerated) skip-if(Android||B2G||Mulet) == object-fit-cover-webm-002.html object-fit-cover-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android/B2G failures # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(layersGPUAccelerated) skip-if(Android||B2G||Mulet) == object-fit-fill-webm-001.html object-fit-fill-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android/B2G failures # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(layersGPUAccelerated) skip-if(Android||B2G||Mulet) == object-fit-fill-webm-002.html object-fit-fill-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android/B2G failures # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(layersGPUAccelerated) skip-if(Android||B2G||Mulet) == object-fit-none-webm-001.html object-fit-none-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android/B2G failures # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(layersGPUAccelerated) skip-if(Android||B2G||Mulet) == object-fit-none-webm-002.html object-fit-none-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android/B2G failures # Initial mulet triage: parity with B2G/B2G Desktop
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -759,16 +759,18 @@ pref("gfx.work-around-driver-bugs", true
 pref("gfx.prefer-mesa-llvmpipe", false);
 
 pref("gfx.draw-color-bars", false);
 
 pref("gfx.logging.painted-pixel-count.enabled", false);
 pref("gfx.logging.texture-usage.enabled", false);
 pref("gfx.logging.peak-texture-usage.enabled", false);
 
+pref("gfx.ycbcr.accurate-conversion", false);
+
 pref("accessibility.browsewithcaret", false);
 pref("accessibility.warn_on_browsewithcaret", true);
 
 pref("accessibility.browsewithcaret_shortcut.enabled", true);
 
 #ifndef XP_MACOSX
 // Tab focus model bit field:
 // 1 focuses text controls, 2 focuses other form elements, 4 adds links.