Bug 1256475 - Use libyuv for non scaling YUV color conversion r=jrmuizel

This commit is contained in:
Sotaro Ikeda 2016-06-06 20:10:59 -07:00
parent 5399e1e48d
commit d7880ceea1
8 changed files with 88 additions and 15 deletions

View File

@ -273,6 +273,7 @@ private:
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);

View File

@ -31,8 +31,6 @@
#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"

View File

@ -7,14 +7,7 @@
#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:

View File

@ -5,11 +5,7 @@
# 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 += [
@ -63,4 +59,6 @@ if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['HAVE_ARM_NEON']:
'yuv_convert_arm.cpp',
]
LOCAL_INCLUDES += ['/media/libyuv/include']
FINAL_LIBRARY = 'xul'

View File

@ -18,6 +18,8 @@
#include "yuv_convert.h"
#include "gfxPrefs.h"
#include "libyuv.h"
// Header for low level row functions.
#include "yuv_row.h"
#include "mozilla/SSE.h"
@ -60,6 +62,72 @@ void ConvertYCbCrToRGB32(const uint8* y_buf,
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.

View File

@ -57,6 +57,19 @@ void ConvertYCbCrToRGB32(const uint8* yplane,
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,

View File

@ -39,7 +39,7 @@ random-if(winWidget) random-if(cocoaWidget) skip-if(Android||B2G||Mulet) == bug6
# 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

View File

@ -764,6 +764,8 @@ 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);