diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-08 19:32:27 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-08 19:32:27 +0000 |
commit | 67637b8ab2e6bef2ba134048461d14c9ecfff0c6 (patch) | |
tree | 4f8385e55be8edbcf6d3445957c516de50f3a398 /media/base | |
parent | 018a96fdb1e10160e0f12f066d9389739b37a97e (diff) | |
download | chromium_src-67637b8ab2e6bef2ba134048461d14c9ecfff0c6.zip chromium_src-67637b8ab2e6bef2ba134048461d14c9ecfff0c6.tar.gz chromium_src-67637b8ab2e6bef2ba134048461d14c9ecfff0c6.tar.bz2 |
Runtime check to enable SSE2 color space conversion code
This will make text in chromoting view to looks much nicer.
BUG=72218
TEST=Text looks much better in chromoting
Review URL: http://codereview.chromium.org/6410127
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@74154 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base')
-rw-r--r-- | media/base/cpu_features.h | 18 | ||||
-rw-r--r-- | media/base/cpu_features_arm.cc | 13 | ||||
-rw-r--r-- | media/base/cpu_features_x86.cc | 54 | ||||
-rw-r--r-- | media/base/yuv_convert.cc | 34 | ||||
-rw-r--r-- | media/base/yuv_convert_c.cc | 24 | ||||
-rw-r--r-- | media/base/yuv_convert_internal.h | 39 | ||||
-rw-r--r-- | media/base/yuv_convert_sse2.cc | 25 |
7 files changed, 176 insertions, 31 deletions
diff --git a/media/base/cpu_features.h b/media/base/cpu_features.h new file mode 100644 index 0000000..c5bdcd7 --- /dev/null +++ b/media/base/cpu_features.h @@ -0,0 +1,18 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file provide utility functions to check CPU features such as SSE2, +// NEON. + +#ifndef MEDIA_BASE_CPU_FEATURES_H_ +#define MEDIA_BASE_CPU_FEATURES_H_ + +namespace media { + +// Returns true if CPU has SSE2 support. +bool hasSSE2(); + +} // namespace media + +#endif // MEDIA_BASE_CPU_FEATURES_H_ diff --git a/media/base/cpu_features_arm.cc b/media/base/cpu_features_arm.cc new file mode 100644 index 0000000..e86fc97 --- /dev/null +++ b/media/base/cpu_features_arm.cc @@ -0,0 +1,13 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/cpu_features.h" + +namespace media { + +bool hasSSE2() { + return false; +} + +} // namespace media diff --git a/media/base/cpu_features_x86.cc b/media/base/cpu_features_x86.cc new file mode 100644 index 0000000..98dfba1 --- /dev/null +++ b/media/base/cpu_features_x86.cc @@ -0,0 +1,54 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Code in this file is taked from +// third_party/skia/src/opts/opts_check_SSE2.cpp. + +// Note that this file cannot be compiled with -msse2 in gcc. + +#include "build/build_config.h" +#include "media/base/cpu_features.h" + +namespace media { + +#if defined(ARCH_CPU_X86_64) +/* All x86_64 machines have SSE2, so don't even bother checking. */ +bool hasSSE2() { + return true; +} +#else +#ifdef _MSC_VER +static inline void getcpuid(int info_type, int info[4]) { + __asm { + mov eax, [info_type] + cpuid + mov edi, [info] + mov [edi], eax + mov [edi+4], ebx + mov [edi+8], ecx + mov [edi+12], edx + } +} +#else +static inline void getcpuid(int info_type, int info[4]) { + // We save and restore ebx, so this code can be compatible with -fPIC + asm volatile ( + "pushl %%ebx \n\t" + "cpuid \n\t" + "movl %%ebx, %1 \n\t" + "popl %%ebx \n\t" + : "=a"(info[0]), "=r"(info[1]), "=c"(info[2]), "=d"(info[3]) + : "a"(info_type) + ); +} +#endif + +bool hasSSE2() { + int cpu_info[4] = { 0 }; + getcpuid(1, cpu_info); + return (cpu_info[3] & (1<<26)) != 0; +} +#endif + +} // namespace media diff --git a/media/base/yuv_convert.cc b/media/base/yuv_convert.cc index bea0e50..f6e2857 100644 --- a/media/base/yuv_convert.cc +++ b/media/base/yuv_convert.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -17,7 +17,8 @@ #include "media/base/yuv_convert.h" -// Header for low level row functions. +#include "media/base/cpu_features.h" +#include "media/base/yuv_convert_internal.h" #include "media/base/yuv_row.h" #if USE_MMX @@ -343,4 +344,33 @@ void ScaleYUVToRGB32(const uint8* y_buf, EMMS(); } +void ConvertRGB32ToYUV(const uint8* rgbframe, + uint8* yplane, + uint8* uplane, + uint8* vplane, + int width, + int height, + int rgbstride, + int ystride, + int uvstride) { + static void (*convert_proc)(const uint8*, uint8*, uint8*, uint8*, + int, int, int, int, int) = NULL; + if (!convert_proc) { +#ifdef __arm__ + // For ARM processors, always use C version. + // TODO(hclam): Implement a NEON version. + convert_proc = &ConvertRGB32ToYUV_C; +#else + // For x86 processors, check if SSE2 is supported. + if (hasSSE2()) + convert_proc = &ConvertRGB32ToYUV_SSE2; + else + convert_proc = &ConvertRGB32ToYUV_C; +#endif + } + + convert_proc(rgbframe, yplane, uplane, vplane, width, height, + rgbstride, ystride, uvstride); +} + } // namespace media diff --git a/media/base/yuv_convert_c.cc b/media/base/yuv_convert_c.cc index 1744a7a..986bf8e 100644 --- a/media/base/yuv_convert_c.cc +++ b/media/base/yuv_convert_c.cc @@ -3,9 +3,7 @@ // found in the LICENSE file. #include "media/base/yuv_convert.h" -#include "media/base/yuv_row.h" - -#if !USE_SSE2 +#include "media/base/yuv_convert_internal.h" namespace media { @@ -18,15 +16,15 @@ static int clip_byte(int x) { return x; } -void ConvertRGB32ToYUV(const uint8* rgbframe, - uint8* yplane, - uint8* uplane, - uint8* vplane, - int width, - int height, - int rgbstride, - int ystride, - int uvstride) { +void ConvertRGB32ToYUV_C(const uint8* rgbframe, + uint8* yplane, + uint8* uplane, + uint8* vplane, + int width, + int height, + int rgbstride, + int ystride, + int uvstride) { for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { // Since the input pixel format is RGB32, there are 4 bytes per pixel. @@ -51,5 +49,3 @@ void ConvertRGB32ToYUV(const uint8* rgbframe, } } // namespace media - -#endif diff --git a/media/base/yuv_convert_internal.h b/media/base/yuv_convert_internal.h new file mode 100644 index 0000000..7a8ee34 --- /dev/null +++ b/media/base/yuv_convert_internal.h @@ -0,0 +1,39 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file defines the YUV conversion functions for each specific +// optimization. + +#ifndef MEDIA_BASE_YUV_CONVERT_INTERNAL_H_ +#define MEDIA_BASE_YUV_CONVERT_INTERNAL_H_ + +#include "base/basictypes.h" + +namespace media { + +// SSE2 version of converting RGBA to YV12. +extern void ConvertRGB32ToYUV_SSE2(const uint8* rgbframe, + uint8* yplane, + uint8* uplane, + uint8* vplane, + int width, + int height, + int rgbstride, + int ystride, + int uvstride); + +// C version of converting RGBA to YV12. +void ConvertRGB32ToYUV_C(const uint8* rgbframe, + uint8* yplane, + uint8* uplane, + uint8* vplane, + int width, + int height, + int rgbstride, + int ystride, + int uvstride); + +} // namespace media + +#endif // MEDIA_BASE_YUV_CONVERT_INTERNAL_H_ diff --git a/media/base/yuv_convert_sse2.cc b/media/base/yuv_convert_sse2.cc index 02ee33c..e2c62f57 100644 --- a/media/base/yuv_convert_sse2.cc +++ b/media/base/yuv_convert_sse2.cc @@ -3,11 +3,9 @@ // found in the LICENSE file. #include "media/base/yuv_convert.h" +#include "media/base/yuv_convert_internal.h" #include "media/base/yuv_row.h" -// TODO(hclam): Perform runtime check to enable SSE2 routines. -#if USE_SSE2 - #if defined(_MSC_VER) #include <intrin.h> #else @@ -162,16 +160,15 @@ void FastConvertRGB32ToYUVRow(const uint8* rgb_buf_1, } } -// TODO(hclam): Add code to do runtime SSE2 detection. -void ConvertRGB32ToYUV(const uint8* rgbframe, - uint8* yplane, - uint8* uplane, - uint8* vplane, - int width, - int height, - int rgbstride, - int ystride, - int uvstride) { +extern void ConvertRGB32ToYUV_SSE2(const uint8* rgbframe, + uint8* yplane, + uint8* uplane, + uint8* vplane, + int width, + int height, + int rgbstride, + int ystride, + int uvstride) { // Make sure |width| is a multiple of 2. width = (width / 2) * 2; for (int i = 0; i < height; i += 2) { @@ -190,5 +187,3 @@ void ConvertRGB32ToYUV(const uint8* rgbframe, } } // namespace media - -#endif |