michael@0: diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp michael@0: --- a/gfx/ycbcr/yuv_convert.cpp michael@0: +++ b/gfx/ycbcr/yuv_convert.cpp michael@0: @@ -6,145 +6,102 @@ michael@0: // http://www.fourcc.org/yuv.php michael@0: // The actual conversion is best described here michael@0: // http://en.wikipedia.org/wiki/YUV michael@0: // An article on optimizing YUV conversion using tables instead of multiplies michael@0: // http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf michael@0: // michael@0: // YV12 is a full plane of Y and a half height, half width chroma planes michael@0: // YV16 is a full plane of Y and a full height, half width chroma planes michael@0: +// YV24 is a full plane of Y and a full height, full width chroma planes michael@0: // michael@0: // ARGB pixel format is output, which on little endian is stored as BGRA. michael@0: // The alpha is set to 255, allowing the application to use RGBA or RGB32. michael@0: michael@0: -#include "media/base/yuv_convert.h" michael@0: +#include "yuv_convert.h" michael@0: michael@0: // Header for low level row functions. michael@0: -#include "media/base/yuv_row.h" michael@0: - michael@0: -#if USE_MMX michael@0: -#if defined(_MSC_VER) michael@0: -#include michael@0: -#else michael@0: -#include michael@0: -#endif michael@0: -#endif michael@0: - michael@0: -#if USE_SSE2 michael@0: -#include michael@0: -#endif michael@0: - michael@0: -namespace media { michael@0: - michael@0: +#include "yuv_row.h" michael@0: +#include "mozilla/SSE.h" michael@0: + michael@0: +namespace mozilla { michael@0: + michael@0: +namespace gfx { michael@0: + michael@0: // 16.16 fixed point arithmetic michael@0: const int kFractionBits = 16; michael@0: const int kFractionMax = 1 << kFractionBits; michael@0: const int kFractionMask = ((1 << kFractionBits) - 1); michael@0: michael@0: // Convert a frame of YUV to 32 bit ARGB. michael@0: -void ConvertYUVToRGB32(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int height, michael@0: - int y_pitch, michael@0: - int uv_pitch, michael@0: - int rgb_pitch, michael@0: - YUVType yuv_type) { michael@0: - unsigned int y_shift = yuv_type; michael@0: - for (int y = 0; y < height; ++y) { michael@0: - uint8* rgb_row = rgb_buf + y * rgb_pitch; michael@0: - const uint8* y_ptr = y_buf + y * y_pitch; michael@0: - const uint8* u_ptr = u_buf + (y >> y_shift) * uv_pitch; michael@0: - const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch; michael@0: - michael@0: - FastConvertYUVToRGB32Row(y_ptr, michael@0: - u_ptr, michael@0: - v_ptr, michael@0: - rgb_row, michael@0: - width); michael@0: - } michael@0: +NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int pic_x, michael@0: + int pic_y, michael@0: + int pic_width, michael@0: + int pic_height, michael@0: + int y_pitch, michael@0: + int uv_pitch, michael@0: + int rgb_pitch, michael@0: + YUVType yuv_type) { michael@0: + unsigned int y_shift = yuv_type == YV12 ? 1 : 0; michael@0: + unsigned int x_shift = yuv_type == YV24 ? 0 : 1; michael@0: + // Test for SSE because the optimized code uses movntq, which is not part of MMX. michael@0: + bool has_sse = supports_mmx() && supports_sse(); michael@0: + // There is no optimized YV24 SSE routine so we check for this and michael@0: + // fall back to the C code. michael@0: + has_sse &= yuv_type != YV24; michael@0: + bool odd_pic_x = yuv_type != YV24 && pic_x % 2 != 0; michael@0: + int x_width = odd_pic_x ? pic_width - 1 : pic_width; michael@0: + michael@0: + for (int y = pic_y; y < pic_height + pic_y; ++y) { michael@0: + uint8* rgb_row = rgb_buf + (y - pic_y) * rgb_pitch; michael@0: + const uint8* y_ptr = y_buf + y * y_pitch + pic_x; michael@0: + const uint8* u_ptr = u_buf + (y >> y_shift) * uv_pitch + (pic_x >> x_shift); michael@0: + const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch + (pic_x >> x_shift); michael@0: + michael@0: + if (odd_pic_x) { michael@0: + // Handle the single odd pixel manually and use the michael@0: + // fast routines for the remaining. michael@0: + FastConvertYUVToRGB32Row_C(y_ptr++, michael@0: + u_ptr++, michael@0: + v_ptr++, michael@0: + rgb_row, michael@0: + 1, michael@0: + x_shift); michael@0: + rgb_row += 4; michael@0: + } michael@0: + michael@0: + if (has_sse) { michael@0: + FastConvertYUVToRGB32Row(y_ptr, michael@0: + u_ptr, michael@0: + v_ptr, michael@0: + rgb_row, michael@0: + x_width); michael@0: + } michael@0: + else { michael@0: + FastConvertYUVToRGB32Row_C(y_ptr, michael@0: + u_ptr, michael@0: + v_ptr, michael@0: + rgb_row, michael@0: + x_width, michael@0: + x_shift); michael@0: + } michael@0: + } michael@0: michael@0: // MMX used for FastConvertYUVToRGB32Row requires emms instruction. michael@0: - EMMS(); michael@0: -} michael@0: - michael@0: -#if USE_SSE2 michael@0: -// FilterRows combines two rows of the image using linear interpolation. michael@0: -// SSE2 version does 16 pixels at a time michael@0: - michael@0: -static void FilterRows(uint8* ybuf, const uint8* y0_ptr, const uint8* y1_ptr, michael@0: - int source_width, int source_y_fraction) { michael@0: - __m128i zero = _mm_setzero_si128(); michael@0: - __m128i y1_fraction = _mm_set1_epi16(source_y_fraction); michael@0: - __m128i y0_fraction = _mm_set1_epi16(256 - source_y_fraction); michael@0: - michael@0: - const __m128i* y0_ptr128 = reinterpret_cast(y0_ptr); michael@0: - const __m128i* y1_ptr128 = reinterpret_cast(y1_ptr); michael@0: - __m128i* dest128 = reinterpret_cast<__m128i*>(ybuf); michael@0: - __m128i* end128 = reinterpret_cast<__m128i*>(ybuf + source_width); michael@0: - michael@0: - do { michael@0: - __m128i y0 = _mm_loadu_si128(y0_ptr128); michael@0: - __m128i y1 = _mm_loadu_si128(y1_ptr128); michael@0: - __m128i y2 = _mm_unpackhi_epi8(y0, zero); michael@0: - __m128i y3 = _mm_unpackhi_epi8(y1, zero); michael@0: - y0 = _mm_unpacklo_epi8(y0, zero); michael@0: - y1 = _mm_unpacklo_epi8(y1, zero); michael@0: - y0 = _mm_mullo_epi16(y0, y0_fraction); michael@0: - y1 = _mm_mullo_epi16(y1, y1_fraction); michael@0: - y2 = _mm_mullo_epi16(y2, y0_fraction); michael@0: - y3 = _mm_mullo_epi16(y3, y1_fraction); michael@0: - y0 = _mm_add_epi16(y0, y1); michael@0: - y2 = _mm_add_epi16(y2, y3); michael@0: - y0 = _mm_srli_epi16(y0, 8); michael@0: - y2 = _mm_srli_epi16(y2, 8); michael@0: - y0 = _mm_packus_epi16(y0, y2); michael@0: - *dest128++ = y0; michael@0: - ++y0_ptr128; michael@0: - ++y1_ptr128; michael@0: - } while (dest128 < end128); michael@0: -} michael@0: -#elif USE_MMX michael@0: -// MMX version does 8 pixels at a time michael@0: -static void FilterRows(uint8* ybuf, const uint8* y0_ptr, const uint8* y1_ptr, michael@0: - int source_width, int source_y_fraction) { michael@0: - __m64 zero = _mm_setzero_si64(); michael@0: - __m64 y1_fraction = _mm_set1_pi16(source_y_fraction); michael@0: - __m64 y0_fraction = _mm_set1_pi16(256 - source_y_fraction); michael@0: - michael@0: - const __m64* y0_ptr64 = reinterpret_cast(y0_ptr); michael@0: - const __m64* y1_ptr64 = reinterpret_cast(y1_ptr); michael@0: - __m64* dest64 = reinterpret_cast<__m64*>(ybuf); michael@0: - __m64* end64 = reinterpret_cast<__m64*>(ybuf + source_width); michael@0: - michael@0: - do { michael@0: - __m64 y0 = *y0_ptr64++; michael@0: - __m64 y1 = *y1_ptr64++; michael@0: - __m64 y2 = _mm_unpackhi_pi8(y0, zero); michael@0: - __m64 y3 = _mm_unpackhi_pi8(y1, zero); michael@0: - y0 = _mm_unpacklo_pi8(y0, zero); michael@0: - y1 = _mm_unpacklo_pi8(y1, zero); michael@0: - y0 = _mm_mullo_pi16(y0, y0_fraction); michael@0: - y1 = _mm_mullo_pi16(y1, y1_fraction); michael@0: - y2 = _mm_mullo_pi16(y2, y0_fraction); michael@0: - y3 = _mm_mullo_pi16(y3, y1_fraction); michael@0: - y0 = _mm_add_pi16(y0, y1); michael@0: - y2 = _mm_add_pi16(y2, y3); michael@0: - y0 = _mm_srli_pi16(y0, 8); michael@0: - y2 = _mm_srli_pi16(y2, 8); michael@0: - y0 = _mm_packs_pu16(y0, y2); michael@0: - *dest64++ = y0; michael@0: - } while (dest64 < end64); michael@0: -} michael@0: -#else // no MMX or SSE2 michael@0: + if (has_sse) michael@0: + EMMS(); michael@0: +} michael@0: + michael@0: // C version does 8 at a time to mimic MMX code michael@0: -static void FilterRows(uint8* ybuf, const uint8* y0_ptr, const uint8* y1_ptr, michael@0: - int source_width, int source_y_fraction) { michael@0: +static void FilterRows_C(uint8* ybuf, const uint8* y0_ptr, const uint8* y1_ptr, michael@0: + int source_width, int source_y_fraction) { michael@0: int y1_fraction = source_y_fraction; michael@0: int y0_fraction = 256 - y1_fraction; michael@0: uint8* end = ybuf + source_width; michael@0: do { michael@0: ybuf[0] = (y0_ptr[0] * y0_fraction + y1_ptr[0] * y1_fraction) >> 8; michael@0: ybuf[1] = (y0_ptr[1] * y0_fraction + y1_ptr[1] * y1_fraction) >> 8; michael@0: ybuf[2] = (y0_ptr[2] * y0_fraction + y1_ptr[2] * y1_fraction) >> 8; michael@0: ybuf[3] = (y0_ptr[3] * y0_fraction + y1_ptr[3] * y1_fraction) >> 8; michael@0: @@ -152,46 +140,77 @@ static void FilterRows(uint8* ybuf, cons michael@0: ybuf[5] = (y0_ptr[5] * y0_fraction + y1_ptr[5] * y1_fraction) >> 8; michael@0: ybuf[6] = (y0_ptr[6] * y0_fraction + y1_ptr[6] * y1_fraction) >> 8; michael@0: ybuf[7] = (y0_ptr[7] * y0_fraction + y1_ptr[7] * y1_fraction) >> 8; michael@0: y0_ptr += 8; michael@0: y1_ptr += 8; michael@0: ybuf += 8; michael@0: } while (ybuf < end); michael@0: } michael@0: -#endif michael@0: + michael@0: +#ifdef MOZILLA_MAY_SUPPORT_MMX michael@0: +void FilterRows_MMX(uint8* ybuf, const uint8* y0_ptr, const uint8* y1_ptr, michael@0: + int source_width, int source_y_fraction); michael@0: +#endif michael@0: + michael@0: +#ifdef MOZILLA_MAY_SUPPORT_SSE2 michael@0: +void FilterRows_SSE2(uint8* ybuf, const uint8* y0_ptr, const uint8* y1_ptr, michael@0: + int source_width, int source_y_fraction); michael@0: +#endif michael@0: + michael@0: +static inline void FilterRows(uint8* ybuf, const uint8* y0_ptr, michael@0: + const uint8* y1_ptr, int source_width, michael@0: + int source_y_fraction) { michael@0: +#ifdef MOZILLA_MAY_SUPPORT_SSE2 michael@0: + if (mozilla::supports_sse2()) { michael@0: + FilterRows_SSE2(ybuf, y0_ptr, y1_ptr, source_width, source_y_fraction); michael@0: + return; michael@0: + } michael@0: +#endif michael@0: + michael@0: +#ifdef MOZILLA_MAY_SUPPORT_MMX michael@0: + if (mozilla::supports_mmx()) { michael@0: + FilterRows_MMX(ybuf, y0_ptr, y1_ptr, source_width, source_y_fraction); michael@0: + return; michael@0: + } michael@0: +#endif michael@0: + michael@0: + FilterRows_C(ybuf, y0_ptr, y1_ptr, source_width, source_y_fraction); michael@0: +} michael@0: michael@0: michael@0: // Scale a frame of YUV to 32 bit ARGB. michael@0: -void ScaleYUVToRGB32(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int source_width, michael@0: - int source_height, michael@0: - int width, michael@0: - int height, michael@0: - int y_pitch, michael@0: - int uv_pitch, michael@0: - int rgb_pitch, michael@0: - YUVType yuv_type, michael@0: - Rotate view_rotate, michael@0: - ScaleFilter filter) { michael@0: +NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int source_width, michael@0: + int source_height, michael@0: + int width, michael@0: + int height, michael@0: + int y_pitch, michael@0: + int uv_pitch, michael@0: + int rgb_pitch, michael@0: + YUVType yuv_type, michael@0: + Rotate view_rotate, michael@0: + ScaleFilter filter) { michael@0: + bool has_mmx = supports_mmx(); michael@0: + michael@0: // 4096 allows 3 buffers to fit in 12k. michael@0: // Helps performance on CPU with 16K L1 cache. michael@0: // Large enough for 3830x2160 and 30" displays which are 2560x1600. michael@0: const int kFilterBufferSize = 4096; michael@0: // Disable filtering if the screen is too big (to avoid buffer overflows). michael@0: // This should never happen to regular users: they don't have monitors michael@0: // wider than 4096 pixels. michael@0: // TODO(fbarchard): Allow rotated videos to filter. michael@0: if (source_width > kFilterBufferSize || view_rotate) michael@0: filter = FILTER_NONE; michael@0: michael@0: - unsigned int y_shift = yuv_type; michael@0: + unsigned int y_shift = yuv_type == YV12 ? 1 : 0; michael@0: // Diagram showing origin and direction of source sampling. michael@0: // ->0 4<- michael@0: // 7 3 michael@0: // michael@0: // 6 5 michael@0: // ->1 2<- michael@0: // Rotations that start at right side of image. michael@0: if ((view_rotate == ROTATE_180) || michael@0: @@ -276,17 +295,17 @@ void ScaleYUVToRGB32(const uint8* y_buf, michael@0: int source_uv_fraction = michael@0: ((source_y_subpixel >> y_shift) & kFractionMask) >> 8; michael@0: michael@0: const uint8* y_ptr = y0_ptr; michael@0: const uint8* u_ptr = u0_ptr; michael@0: const uint8* v_ptr = v0_ptr; michael@0: // Apply vertical filtering if necessary. michael@0: // TODO(fbarchard): Remove memcpy when not necessary. michael@0: - if (filter & media::FILTER_BILINEAR_V) { michael@0: + if (filter & mozilla::gfx::FILTER_BILINEAR_V) { michael@0: if (yscale_fixed != kFractionMax && michael@0: source_y_fraction && ((source_y + 1) < source_height)) { michael@0: FilterRows(ybuf, y0_ptr, y1_ptr, source_width, source_y_fraction); michael@0: } else { michael@0: memcpy(ybuf, y0_ptr, source_width); michael@0: } michael@0: y_ptr = ybuf; michael@0: ybuf[source_width] = ybuf[source_width-1]; michael@0: @@ -303,44 +322,50 @@ void ScaleYUVToRGB32(const uint8* y_buf, michael@0: u_ptr = ubuf; michael@0: v_ptr = vbuf; michael@0: ubuf[uv_source_width] = ubuf[uv_source_width - 1]; michael@0: vbuf[uv_source_width] = vbuf[uv_source_width - 1]; michael@0: } michael@0: if (source_dx == kFractionMax) { // Not scaled michael@0: FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr, michael@0: dest_pixel, width); michael@0: - } else { michael@0: - if (filter & FILTER_BILINEAR_H) { michael@0: + } else if (filter & FILTER_BILINEAR_H) { michael@0: LinearScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr, michael@0: dest_pixel, width, source_dx); michael@0: } else { michael@0: // Specialized scalers and rotation. michael@0: -#if USE_MMX && defined(_MSC_VER) michael@0: +#if defined(MOZILLA_MAY_SUPPORT_SSE) && defined(_MSC_VER) && defined(_M_IX86) michael@0: + if(mozilla::supports_sse()) { michael@0: if (width == (source_width * 2)) { michael@0: - DoubleYUVToRGB32Row(y_ptr, u_ptr, v_ptr, michael@0: - dest_pixel, width); michael@0: + DoubleYUVToRGB32Row_SSE(y_ptr, u_ptr, v_ptr, michael@0: + dest_pixel, width); michael@0: } else if ((source_dx & kFractionMask) == 0) { michael@0: // Scaling by integer scale factor. ie half. michael@0: - ConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr, michael@0: - dest_pixel, width, michael@0: - source_dx >> kFractionBits); michael@0: + ConvertYUVToRGB32Row_SSE(y_ptr, u_ptr, v_ptr, michael@0: + dest_pixel, width, michael@0: + source_dx >> kFractionBits); michael@0: } else if (source_dx_uv == source_dx) { // Not rotated. michael@0: ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr, michael@0: dest_pixel, width, source_dx); michael@0: } else { michael@0: - RotateConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr, michael@0: - dest_pixel, width, michael@0: - source_dx >> kFractionBits, michael@0: - source_dx_uv >> kFractionBits); michael@0: + RotateConvertYUVToRGB32Row_SSE(y_ptr, u_ptr, v_ptr, michael@0: + dest_pixel, width, michael@0: + source_dx >> kFractionBits, michael@0: + source_dx_uv >> kFractionBits); michael@0: } michael@0: + } michael@0: + else { michael@0: + ScaleYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr, michael@0: + dest_pixel, width, source_dx); michael@0: + } michael@0: #else michael@0: - ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr, michael@0: - dest_pixel, width, source_dx); michael@0: -#endif michael@0: - } michael@0: + ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr, michael@0: + dest_pixel, width, source_dx); michael@0: +#endif michael@0: } michael@0: } michael@0: // MMX used for FastConvertYUVToRGB32Row and FilterRows requires emms. michael@0: - EMMS(); michael@0: -} michael@0: - michael@0: -} // namespace media michael@0: + if (has_mmx) michael@0: + EMMS(); michael@0: +} michael@0: + michael@0: +} // namespace gfx michael@0: +} // namespace mozilla michael@0: diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h michael@0: --- a/gfx/ycbcr/yuv_convert.h michael@0: +++ b/gfx/ycbcr/yuv_convert.h michael@0: @@ -1,72 +1,79 @@ michael@0: // Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #ifndef MEDIA_BASE_YUV_CONVERT_H_ michael@0: #define MEDIA_BASE_YUV_CONVERT_H_ michael@0: michael@0: -#include "base/basictypes.h" michael@0: - michael@0: -namespace media { michael@0: - michael@0: +#include "chromium_types.h" michael@0: +#include "gfxCore.h" michael@0: + michael@0: +namespace mozilla { michael@0: + michael@0: +namespace gfx { michael@0: + michael@0: // Type of YUV surface. michael@0: // The value of these enums matter as they are used to shift vertical indices. michael@0: enum YUVType { michael@0: - YV16 = 0, // YV16 is half width and full height chroma channels. michael@0: - YV12 = 1, // YV12 is half width and half height chroma channels. michael@0: + YV12 = 0, // YV12 is half width and half height chroma channels. michael@0: + YV16 = 1, // YV16 is half width and full height chroma channels. michael@0: + YV24 = 2 // YV24 is full width and full height chroma channels. michael@0: }; michael@0: michael@0: // Mirror means flip the image horizontally, as in looking in a mirror. michael@0: // Rotate happens after mirroring. michael@0: enum Rotate { michael@0: ROTATE_0, // Rotation off. michael@0: ROTATE_90, // Rotate clockwise. michael@0: ROTATE_180, // Rotate upside down. michael@0: ROTATE_270, // Rotate counter clockwise. michael@0: MIRROR_ROTATE_0, // Mirror horizontally. michael@0: MIRROR_ROTATE_90, // Mirror then Rotate clockwise. michael@0: MIRROR_ROTATE_180, // Mirror vertically. michael@0: - MIRROR_ROTATE_270, // Transpose. michael@0: + MIRROR_ROTATE_270 // Transpose. michael@0: }; michael@0: michael@0: // Filter affects how scaling looks. michael@0: enum ScaleFilter { michael@0: FILTER_NONE = 0, // No filter (point sampled). michael@0: FILTER_BILINEAR_H = 1, // Bilinear horizontal filter. michael@0: FILTER_BILINEAR_V = 2, // Bilinear vertical filter. michael@0: - FILTER_BILINEAR = 3, // Bilinear filter. michael@0: + FILTER_BILINEAR = 3 // Bilinear filter. michael@0: }; michael@0: michael@0: // Convert a frame of YUV to 32 bit ARGB. michael@0: // Pass in YV16/YV12 depending on source format michael@0: -void ConvertYUVToRGB32(const uint8* yplane, michael@0: - const uint8* uplane, michael@0: - const uint8* vplane, michael@0: - uint8* rgbframe, michael@0: - int width, michael@0: - int height, michael@0: - int ystride, michael@0: - int uvstride, michael@0: - int rgbstride, michael@0: - YUVType yuv_type); michael@0: +NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* yplane, michael@0: + const uint8* uplane, michael@0: + const uint8* vplane, michael@0: + uint8* rgbframe, michael@0: + int pic_x, michael@0: + int pic_y, michael@0: + int pic_width, michael@0: + int pic_height, michael@0: + int ystride, michael@0: + int uvstride, michael@0: + int rgbstride, michael@0: + YUVType yuv_type); michael@0: michael@0: // Scale a frame of YUV to 32 bit ARGB. michael@0: // Supports rotation and mirroring. michael@0: -void ScaleYUVToRGB32(const uint8* yplane, michael@0: - const uint8* uplane, michael@0: - const uint8* vplane, michael@0: - uint8* rgbframe, michael@0: - int source_width, michael@0: - int source_height, michael@0: - int width, michael@0: - int height, michael@0: - int ystride, michael@0: - int uvstride, michael@0: - int rgbstride, michael@0: - YUVType yuv_type, michael@0: - Rotate view_rotate, michael@0: - ScaleFilter filter); michael@0: - michael@0: -} // namespace media michael@0: - michael@0: +NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* yplane, michael@0: + const uint8* uplane, michael@0: + const uint8* vplane, michael@0: + uint8* rgbframe, michael@0: + int source_width, michael@0: + int source_height, michael@0: + int width, michael@0: + int height, michael@0: + int ystride, michael@0: + int uvstride, michael@0: + int rgbstride, michael@0: + YUVType yuv_type, michael@0: + Rotate view_rotate, michael@0: + ScaleFilter filter); michael@0: + michael@0: +} // namespace gfx michael@0: +} // namespace mozilla michael@0: + michael@0: #endif // MEDIA_BASE_YUV_CONVERT_H_ michael@0: diff --git a/gfx/ycbcr/yuv_convert_mmx.cpp b/gfx/ycbcr/yuv_convert_mmx.cpp michael@0: new file mode 100644 michael@0: --- /dev/null michael@0: +++ b/gfx/ycbcr/yuv_convert_mmx.cpp michael@0: @@ -0,0 +1,45 @@ michael@0: +// Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: +// Use of this source code is governed by a BSD-style license that can be michael@0: +// found in the LICENSE file. michael@0: + michael@0: +#include michael@0: +#include "yuv_row.h" michael@0: + michael@0: +namespace mozilla { michael@0: +namespace gfx { michael@0: + michael@0: +// FilterRows combines two rows of the image using linear interpolation. michael@0: +// MMX version does 8 pixels at a time. michael@0: +void FilterRows_MMX(uint8* ybuf, const uint8* y0_ptr, const uint8* y1_ptr, michael@0: + int source_width, int source_y_fraction) { michael@0: + __m64 zero = _mm_setzero_si64(); michael@0: + __m64 y1_fraction = _mm_set1_pi16(source_y_fraction); michael@0: + __m64 y0_fraction = _mm_set1_pi16(256 - source_y_fraction); michael@0: + michael@0: + const __m64* y0_ptr64 = reinterpret_cast(y0_ptr); michael@0: + const __m64* y1_ptr64 = reinterpret_cast(y1_ptr); michael@0: + __m64* dest64 = reinterpret_cast<__m64*>(ybuf); michael@0: + __m64* end64 = reinterpret_cast<__m64*>(ybuf + source_width); michael@0: + michael@0: + do { michael@0: + __m64 y0 = *y0_ptr64++; michael@0: + __m64 y1 = *y1_ptr64++; michael@0: + __m64 y2 = _mm_unpackhi_pi8(y0, zero); michael@0: + __m64 y3 = _mm_unpackhi_pi8(y1, zero); michael@0: + y0 = _mm_unpacklo_pi8(y0, zero); michael@0: + y1 = _mm_unpacklo_pi8(y1, zero); michael@0: + y0 = _mm_mullo_pi16(y0, y0_fraction); michael@0: + y1 = _mm_mullo_pi16(y1, y1_fraction); michael@0: + y2 = _mm_mullo_pi16(y2, y0_fraction); michael@0: + y3 = _mm_mullo_pi16(y3, y1_fraction); michael@0: + y0 = _mm_add_pi16(y0, y1); michael@0: + y2 = _mm_add_pi16(y2, y3); michael@0: + y0 = _mm_srli_pi16(y0, 8); michael@0: + y2 = _mm_srli_pi16(y2, 8); michael@0: + y0 = _mm_packs_pu16(y0, y2); michael@0: + *dest64++ = y0; michael@0: + } while (dest64 < end64); michael@0: +} michael@0: + michael@0: +} michael@0: +} michael@0: diff --git a/gfx/ycbcr/yuv_convert_sse2.cpp b/gfx/ycbcr/yuv_convert_sse2.cpp michael@0: new file mode 100644 michael@0: --- /dev/null michael@0: +++ b/gfx/ycbcr/yuv_convert_sse2.cpp michael@0: @@ -0,0 +1,47 @@ michael@0: +// Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: +// Use of this source code is governed by a BSD-style license that can be michael@0: +// found in the LICENSE file. michael@0: + michael@0: +#include michael@0: +#include "yuv_row.h" michael@0: + michael@0: +namespace mozilla { michael@0: +namespace gfx { michael@0: + michael@0: +// FilterRows combines two rows of the image using linear interpolation. michael@0: +// SSE2 version does 16 pixels at a time. michael@0: +void FilterRows_SSE2(uint8* ybuf, const uint8* y0_ptr, const uint8* y1_ptr, michael@0: + int source_width, int source_y_fraction) { michael@0: + __m128i zero = _mm_setzero_si128(); michael@0: + __m128i y1_fraction = _mm_set1_epi16(source_y_fraction); michael@0: + __m128i y0_fraction = _mm_set1_epi16(256 - source_y_fraction); michael@0: + michael@0: + const __m128i* y0_ptr128 = reinterpret_cast(y0_ptr); michael@0: + const __m128i* y1_ptr128 = reinterpret_cast(y1_ptr); michael@0: + __m128i* dest128 = reinterpret_cast<__m128i*>(ybuf); michael@0: + __m128i* end128 = reinterpret_cast<__m128i*>(ybuf + source_width); michael@0: + michael@0: + do { michael@0: + __m128i y0 = _mm_loadu_si128(y0_ptr128); michael@0: + __m128i y1 = _mm_loadu_si128(y1_ptr128); michael@0: + __m128i y2 = _mm_unpackhi_epi8(y0, zero); michael@0: + __m128i y3 = _mm_unpackhi_epi8(y1, zero); michael@0: + y0 = _mm_unpacklo_epi8(y0, zero); michael@0: + y1 = _mm_unpacklo_epi8(y1, zero); michael@0: + y0 = _mm_mullo_epi16(y0, y0_fraction); michael@0: + y1 = _mm_mullo_epi16(y1, y1_fraction); michael@0: + y2 = _mm_mullo_epi16(y2, y0_fraction); michael@0: + y3 = _mm_mullo_epi16(y3, y1_fraction); michael@0: + y0 = _mm_add_epi16(y0, y1); michael@0: + y2 = _mm_add_epi16(y2, y3); michael@0: + y0 = _mm_srli_epi16(y0, 8); michael@0: + y2 = _mm_srli_epi16(y2, 8); michael@0: + y0 = _mm_packus_epi16(y0, y2); michael@0: + *dest128++ = y0; michael@0: + ++y0_ptr128; michael@0: + ++y1_ptr128; michael@0: + } while (dest128 < end128); michael@0: +} michael@0: + michael@0: +} michael@0: +} michael@0: diff --git a/gfx/ycbcr/yuv_row.h b/gfx/ycbcr/yuv_row.h michael@0: --- a/gfx/ycbcr/yuv_row.h michael@0: +++ b/gfx/ycbcr/yuv_row.h michael@0: @@ -5,109 +5,133 @@ michael@0: // yuv_row internal functions to handle YUV conversion and scaling to RGB. michael@0: // These functions are used from both yuv_convert.cc and yuv_scale.cc. michael@0: michael@0: // TODO(fbarchard): Write function that can handle rotation and scaling. michael@0: michael@0: #ifndef MEDIA_BASE_YUV_ROW_H_ michael@0: #define MEDIA_BASE_YUV_ROW_H_ michael@0: michael@0: -#include "base/basictypes.h" michael@0: +#include "chromium_types.h" michael@0: michael@0: extern "C" { michael@0: // Can only do 1x. michael@0: // This is the second fastest of the scalers. michael@0: void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width); michael@0: michael@0: -// Can do 1x, half size or any scale down by an integer amount. michael@0: -// Step can be negative (mirroring, rotate 180). michael@0: -// This is the third fastest of the scalers. michael@0: -void ConvertYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int step); michael@0: - michael@0: -// Rotate is like Convert, but applies different step to Y versus U and V. michael@0: -// This allows rotation by 90 or 270, by stepping by stride. michael@0: -// This is the forth fastest of the scalers. michael@0: -void RotateConvertYUVToRGB32Row(const uint8* y_buf, michael@0: +void FastConvertYUVToRGB32Row_C(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: - int ystep, michael@0: - int uvstep); michael@0: + unsigned int x_shift); michael@0: + michael@0: +void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width); michael@0: + michael@0: +// Can do 1x, half size or any scale down by an integer amount. michael@0: +// Step can be negative (mirroring, rotate 180). michael@0: +// This is the third fastest of the scalers. michael@0: +// Only defined on Windows x86-32. michael@0: +void ConvertYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int step); michael@0: + michael@0: +// Rotate is like Convert, but applies different step to Y versus U and V. michael@0: +// This allows rotation by 90 or 270, by stepping by stride. michael@0: +// This is the forth fastest of the scalers. michael@0: +// Only defined on Windows x86-32. michael@0: +void RotateConvertYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int ystep, michael@0: + int uvstep); michael@0: michael@0: // Doubler does 4 pixels at a time. Each pixel is replicated. michael@0: // This is the fastest of the scalers. michael@0: -void DoubleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width); michael@0: +// Only defined on Windows x86-32. michael@0: +void DoubleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width); michael@0: michael@0: // Handles arbitrary scaling up or down. michael@0: // Mirroring is supported, but not 90 or 270 degree rotation. michael@0: // Chroma is under sampled every 2 pixels for performance. michael@0: void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx); michael@0: michael@0: +void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx); michael@0: + michael@0: +void ScaleYUVToRGB32Row_C(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx); michael@0: + michael@0: // Handles arbitrary scaling up or down with bilinear filtering. michael@0: // Mirroring is supported, but not 90 or 270 degree rotation. michael@0: // Chroma is under sampled every 2 pixels for performance. michael@0: // This is the slowest of the scalers. michael@0: void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx); michael@0: michael@0: +void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx); michael@0: + michael@0: +void LinearScaleYUVToRGB32Row_C(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx); michael@0: + michael@0: + michael@0: #if defined(_MSC_VER) michael@0: #define SIMD_ALIGNED(var) __declspec(align(16)) var michael@0: #else michael@0: #define SIMD_ALIGNED(var) var __attribute__((aligned(16))) michael@0: #endif michael@0: extern SIMD_ALIGNED(int16 kCoefficientsRgbY[768][4]); michael@0: michael@0: -// Method to force C version. michael@0: -//#define USE_MMX 0 michael@0: -//#define USE_SSE2 0 michael@0: - michael@0: -#if !defined(USE_MMX) michael@0: -// Windows, Mac and Linux/BSD use MMX michael@0: -#if defined(__MMX__) || defined(_MSC_VER) michael@0: -#define USE_MMX 1 michael@0: -#else michael@0: -#define USE_MMX 0 michael@0: -#endif michael@0: -#endif michael@0: - michael@0: -#if !defined(USE_SSE2) michael@0: -#if defined(__SSE2__) || defined(ARCH_CPU_X86_64) || _M_IX86_FP==2 michael@0: -#define USE_SSE2 1 michael@0: -#else michael@0: -#define USE_SSE2 0 michael@0: -#endif michael@0: -#endif michael@0: - michael@0: // x64 uses MMX2 (SSE) so emms is not required. michael@0: // Warning C4799: function has no EMMS instruction. michael@0: // EMMS() is slow and should be called by the calling function once per image. michael@0: -#if USE_MMX && !defined(ARCH_CPU_X86_64) michael@0: +#if defined(ARCH_CPU_X86) && !defined(ARCH_CPU_X86_64) michael@0: #if defined(_MSC_VER) michael@0: #define EMMS() __asm emms michael@0: #pragma warning(disable: 4799) michael@0: #else michael@0: #define EMMS() asm("emms") michael@0: #endif michael@0: #else michael@0: #define EMMS() michael@0: diff --git a/gfx/ycbcr/yuv_row_c.cpp b/gfx/ycbcr/yuv_row_c.cpp michael@0: --- a/gfx/ycbcr/yuv_row_c.cpp michael@0: +++ b/gfx/ycbcr/yuv_row_c.cpp michael@0: @@ -1,812 +1,18 @@ michael@0: // Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: -#include "media/base/yuv_row.h" michael@0: - michael@0: -#ifdef _DEBUG michael@0: -#include "base/logging.h" michael@0: -#else michael@0: +#include "yuv_row.h" michael@0: + michael@0: #define DCHECK(a) michael@0: -#endif michael@0: michael@0: extern "C" { michael@0: michael@0: -#if USE_SSE2 && defined(ARCH_CPU_X86_64) michael@0: - michael@0: -// AMD64 ABI uses register paremters. michael@0: -void FastConvertYUVToRGB32Row(const uint8* y_buf, // rdi michael@0: - const uint8* u_buf, // rsi michael@0: - const uint8* v_buf, // rdx michael@0: - uint8* rgb_buf, // rcx michael@0: - int width) { // r8 michael@0: - asm( michael@0: - "jmp convertend\n" michael@0: -"convertloop:" michael@0: - "movzb (%1),%%r10\n" michael@0: - "add $0x1,%1\n" michael@0: - "movzb (%2),%%r11\n" michael@0: - "add $0x1,%2\n" michael@0: - "movq 2048(%5,%%r10,8),%%xmm0\n" michael@0: - "movzb (%0),%%r10\n" michael@0: - "movq 4096(%5,%%r11,8),%%xmm1\n" michael@0: - "movzb 0x1(%0),%%r11\n" michael@0: - "paddsw %%xmm1,%%xmm0\n" michael@0: - "movq (%5,%%r10,8),%%xmm2\n" michael@0: - "add $0x2,%0\n" michael@0: - "movq (%5,%%r11,8),%%xmm3\n" michael@0: - "paddsw %%xmm0,%%xmm2\n" michael@0: - "paddsw %%xmm0,%%xmm3\n" michael@0: - "shufps $0x44,%%xmm3,%%xmm2\n" michael@0: - "psraw $0x6,%%xmm2\n" michael@0: - "packuswb %%xmm2,%%xmm2\n" michael@0: - "movq %%xmm2,0x0(%3)\n" michael@0: - "add $0x8,%3\n" michael@0: -"convertend:" michael@0: - "sub $0x2,%4\n" michael@0: - "jns convertloop\n" michael@0: - michael@0: -"convertnext:" michael@0: - "add $0x1,%4\n" michael@0: - "js convertdone\n" michael@0: - michael@0: - "movzb (%1),%%r10\n" michael@0: - "movq 2048(%5,%%r10,8),%%xmm0\n" michael@0: - "movzb (%2),%%r10\n" michael@0: - "movq 4096(%5,%%r10,8),%%xmm1\n" michael@0: - "paddsw %%xmm1,%%xmm0\n" michael@0: - "movzb (%0),%%r10\n" michael@0: - "movq (%5,%%r10,8),%%xmm1\n" michael@0: - "paddsw %%xmm0,%%xmm1\n" michael@0: - "psraw $0x6,%%xmm1\n" michael@0: - "packuswb %%xmm1,%%xmm1\n" michael@0: - "movd %%xmm1,0x0(%3)\n" michael@0: -"convertdone:" michael@0: - : michael@0: - : "r"(y_buf), // %0 michael@0: - "r"(u_buf), // %1 michael@0: - "r"(v_buf), // %2 michael@0: - "r"(rgb_buf), // %3 michael@0: - "r"(width), // %4 michael@0: - "r" (kCoefficientsRgbY) // %5 michael@0: - : "memory", "r10", "r11", "xmm0", "xmm1", "xmm2", "xmm3" michael@0: -); michael@0: -} michael@0: - michael@0: -void ScaleYUVToRGB32Row(const uint8* y_buf, // rdi michael@0: - const uint8* u_buf, // rsi michael@0: - const uint8* v_buf, // rdx michael@0: - uint8* rgb_buf, // rcx michael@0: - int width, // r8 michael@0: - int source_dx) { // r9 michael@0: - asm( michael@0: - "xor %%r11,%%r11\n" michael@0: - "sub $0x2,%4\n" michael@0: - "js scalenext\n" michael@0: - michael@0: -"scaleloop:" michael@0: - "mov %%r11,%%r10\n" michael@0: - "sar $0x11,%%r10\n" michael@0: - "movzb (%1,%%r10,1),%%rax\n" michael@0: - "movq 2048(%5,%%rax,8),%%xmm0\n" michael@0: - "movzb (%2,%%r10,1),%%rax\n" michael@0: - "movq 4096(%5,%%rax,8),%%xmm1\n" michael@0: - "lea (%%r11,%6),%%r10\n" michael@0: - "sar $0x10,%%r11\n" michael@0: - "movzb (%0,%%r11,1),%%rax\n" michael@0: - "paddsw %%xmm1,%%xmm0\n" michael@0: - "movq (%5,%%rax,8),%%xmm1\n" michael@0: - "lea (%%r10,%6),%%r11\n" michael@0: - "sar $0x10,%%r10\n" michael@0: - "movzb (%0,%%r10,1),%%rax\n" michael@0: - "movq (%5,%%rax,8),%%xmm2\n" michael@0: - "paddsw %%xmm0,%%xmm1\n" michael@0: - "paddsw %%xmm0,%%xmm2\n" michael@0: - "shufps $0x44,%%xmm2,%%xmm1\n" michael@0: - "psraw $0x6,%%xmm1\n" michael@0: - "packuswb %%xmm1,%%xmm1\n" michael@0: - "movq %%xmm1,0x0(%3)\n" michael@0: - "add $0x8,%3\n" michael@0: - "sub $0x2,%4\n" michael@0: - "jns scaleloop\n" michael@0: - michael@0: -"scalenext:" michael@0: - "add $0x1,%4\n" michael@0: - "js scaledone\n" michael@0: - michael@0: - "mov %%r11,%%r10\n" michael@0: - "sar $0x11,%%r10\n" michael@0: - "movzb (%1,%%r10,1),%%rax\n" michael@0: - "movq 2048(%5,%%rax,8),%%xmm0\n" michael@0: - "movzb (%2,%%r10,1),%%rax\n" michael@0: - "movq 4096(%5,%%rax,8),%%xmm1\n" michael@0: - "paddsw %%xmm1,%%xmm0\n" michael@0: - "sar $0x10,%%r11\n" michael@0: - "movzb (%0,%%r11,1),%%rax\n" michael@0: - "movq (%5,%%rax,8),%%xmm1\n" michael@0: - "paddsw %%xmm0,%%xmm1\n" michael@0: - "psraw $0x6,%%xmm1\n" michael@0: - "packuswb %%xmm1,%%xmm1\n" michael@0: - "movd %%xmm1,0x0(%3)\n" michael@0: - michael@0: -"scaledone:" michael@0: - : michael@0: - : "r"(y_buf), // %0 michael@0: - "r"(u_buf), // %1 michael@0: - "r"(v_buf), // %2 michael@0: - "r"(rgb_buf), // %3 michael@0: - "r"(width), // %4 michael@0: - "r" (kCoefficientsRgbY), // %5 michael@0: - "r"(static_cast(source_dx)) // %6 michael@0: - : "memory", "r10", "r11", "rax", "xmm0", "xmm1", "xmm2" michael@0: -); michael@0: -} michael@0: - michael@0: -void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx) { michael@0: - asm( michael@0: - "xor %%r11,%%r11\n" // x = 0 michael@0: - "sub $0x2,%4\n" michael@0: - "js .lscalenext\n" michael@0: - "cmp $0x20000,%6\n" // if source_dx >= 2.0 michael@0: - "jl .lscalehalf\n" michael@0: - "mov $0x8000,%%r11\n" // x = 0.5 for 1/2 or less michael@0: -".lscalehalf:" michael@0: - michael@0: -".lscaleloop:" michael@0: - "mov %%r11,%%r10\n" michael@0: - "sar $0x11,%%r10\n" michael@0: - michael@0: - "movzb (%1, %%r10, 1), %%r13 \n" michael@0: - "movzb 1(%1, %%r10, 1), %%r14 \n" michael@0: - "mov %%r11, %%rax \n" michael@0: - "and $0x1fffe, %%rax \n" michael@0: - "imul %%rax, %%r14 \n" michael@0: - "xor $0x1fffe, %%rax \n" michael@0: - "imul %%rax, %%r13 \n" michael@0: - "add %%r14, %%r13 \n" michael@0: - "shr $17, %%r13 \n" michael@0: - "movq 2048(%5,%%r13,8), %%xmm0\n" michael@0: - michael@0: - "movzb (%2, %%r10, 1), %%r13 \n" michael@0: - "movzb 1(%2, %%r10, 1), %%r14 \n" michael@0: - "mov %%r11, %%rax \n" michael@0: - "and $0x1fffe, %%rax \n" michael@0: - "imul %%rax, %%r14 \n" michael@0: - "xor $0x1fffe, %%rax \n" michael@0: - "imul %%rax, %%r13 \n" michael@0: - "add %%r14, %%r13 \n" michael@0: - "shr $17, %%r13 \n" michael@0: - "movq 4096(%5,%%r13,8), %%xmm1\n" michael@0: - michael@0: - "mov %%r11, %%rax \n" michael@0: - "lea (%%r11,%6),%%r10\n" michael@0: - "sar $0x10,%%r11\n" michael@0: - "paddsw %%xmm1,%%xmm0\n" michael@0: - michael@0: - "movzb (%0, %%r11, 1), %%r13 \n" michael@0: - "movzb 1(%0, %%r11, 1), %%r14 \n" michael@0: - "and $0xffff, %%rax \n" michael@0: - "imul %%rax, %%r14 \n" michael@0: - "xor $0xffff, %%rax \n" michael@0: - "imul %%rax, %%r13 \n" michael@0: - "add %%r14, %%r13 \n" michael@0: - "shr $16, %%r13 \n" michael@0: - "movq (%5,%%r13,8),%%xmm1\n" michael@0: - michael@0: - "mov %%r10, %%rax \n" michael@0: - "lea (%%r10,%6),%%r11\n" michael@0: - "sar $0x10,%%r10\n" michael@0: - michael@0: - "movzb (%0,%%r10,1), %%r13 \n" michael@0: - "movzb 1(%0,%%r10,1), %%r14 \n" michael@0: - "and $0xffff, %%rax \n" michael@0: - "imul %%rax, %%r14 \n" michael@0: - "xor $0xffff, %%rax \n" michael@0: - "imul %%rax, %%r13 \n" michael@0: - "add %%r14, %%r13 \n" michael@0: - "shr $16, %%r13 \n" michael@0: - "movq (%5,%%r13,8),%%xmm2\n" michael@0: - michael@0: - "paddsw %%xmm0,%%xmm1\n" michael@0: - "paddsw %%xmm0,%%xmm2\n" michael@0: - "shufps $0x44,%%xmm2,%%xmm1\n" michael@0: - "psraw $0x6,%%xmm1\n" michael@0: - "packuswb %%xmm1,%%xmm1\n" michael@0: - "movq %%xmm1,0x0(%3)\n" michael@0: - "add $0x8,%3\n" michael@0: - "sub $0x2,%4\n" michael@0: - "jns .lscaleloop\n" michael@0: - michael@0: -".lscalenext:" michael@0: - "add $0x1,%4\n" michael@0: - "js .lscaledone\n" michael@0: - michael@0: - "mov %%r11,%%r10\n" michael@0: - "sar $0x11,%%r10\n" michael@0: - michael@0: - "movzb (%1,%%r10,1), %%r13 \n" michael@0: - "movq 2048(%5,%%r13,8),%%xmm0\n" michael@0: - michael@0: - "movzb (%2,%%r10,1), %%r13 \n" michael@0: - "movq 4096(%5,%%r13,8),%%xmm1\n" michael@0: - michael@0: - "paddsw %%xmm1,%%xmm0\n" michael@0: - "sar $0x10,%%r11\n" michael@0: - michael@0: - "movzb (%0,%%r11,1), %%r13 \n" michael@0: - "movq (%5,%%r13,8),%%xmm1\n" michael@0: - michael@0: - "paddsw %%xmm0,%%xmm1\n" michael@0: - "psraw $0x6,%%xmm1\n" michael@0: - "packuswb %%xmm1,%%xmm1\n" michael@0: - "movd %%xmm1,0x0(%3)\n" michael@0: - michael@0: -".lscaledone:" michael@0: - : michael@0: - : "r"(y_buf), // %0 michael@0: - "r"(u_buf), // %1 michael@0: - "r"(v_buf), // %2 michael@0: - "r"(rgb_buf), // %3 michael@0: - "r"(width), // %4 michael@0: - "r" (kCoefficientsRgbY), // %5 michael@0: - "r"(static_cast(source_dx)) // %6 michael@0: - : "memory", "r10", "r11", "r13", "r14", "rax", "xmm0", "xmm1", "xmm2" michael@0: -); michael@0: -} michael@0: - michael@0: -#elif USE_MMX && !defined(ARCH_CPU_X86_64) && !defined(__PIC__) michael@0: - michael@0: -// PIC version is slower because less registers are available, so michael@0: -// non-PIC is used on platforms where it is possible. michael@0: - michael@0: -void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width); michael@0: - asm( michael@0: - ".text\n" michael@0: - ".global FastConvertYUVToRGB32Row\n" michael@0: -"FastConvertYUVToRGB32Row:\n" michael@0: - "pusha\n" michael@0: - "mov 0x24(%esp),%edx\n" michael@0: - "mov 0x28(%esp),%edi\n" michael@0: - "mov 0x2c(%esp),%esi\n" michael@0: - "mov 0x30(%esp),%ebp\n" michael@0: - "mov 0x34(%esp),%ecx\n" michael@0: - "jmp convertend\n" michael@0: - michael@0: -"convertloop:" michael@0: - "movzbl (%edi),%eax\n" michael@0: - "add $0x1,%edi\n" michael@0: - "movzbl (%esi),%ebx\n" michael@0: - "add $0x1,%esi\n" michael@0: - "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: - "movzbl (%edx),%eax\n" michael@0: - "paddsw kCoefficientsRgbY+4096(,%ebx,8),%mm0\n" michael@0: - "movzbl 0x1(%edx),%ebx\n" michael@0: - "movq kCoefficientsRgbY(,%eax,8),%mm1\n" michael@0: - "add $0x2,%edx\n" michael@0: - "movq kCoefficientsRgbY(,%ebx,8),%mm2\n" michael@0: - "paddsw %mm0,%mm1\n" michael@0: - "paddsw %mm0,%mm2\n" michael@0: - "psraw $0x6,%mm1\n" michael@0: - "psraw $0x6,%mm2\n" michael@0: - "packuswb %mm2,%mm1\n" michael@0: - "movntq %mm1,0x0(%ebp)\n" michael@0: - "add $0x8,%ebp\n" michael@0: -"convertend:" michael@0: - "sub $0x2,%ecx\n" michael@0: - "jns convertloop\n" michael@0: - michael@0: - "and $0x1,%ecx\n" michael@0: - "je convertdone\n" michael@0: - michael@0: - "movzbl (%edi),%eax\n" michael@0: - "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: - "movzbl (%esi),%eax\n" michael@0: - "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" michael@0: - "movzbl (%edx),%eax\n" michael@0: - "movq kCoefficientsRgbY(,%eax,8),%mm1\n" michael@0: - "paddsw %mm0,%mm1\n" michael@0: - "psraw $0x6,%mm1\n" michael@0: - "packuswb %mm1,%mm1\n" michael@0: - "movd %mm1,0x0(%ebp)\n" michael@0: -"convertdone:" michael@0: - "popa\n" michael@0: - "ret\n" michael@0: -); michael@0: - michael@0: - michael@0: -void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx); michael@0: - asm( michael@0: - ".text\n" michael@0: - ".global ScaleYUVToRGB32Row\n" michael@0: -"ScaleYUVToRGB32Row:\n" michael@0: - "pusha\n" michael@0: - "mov 0x24(%esp),%edx\n" michael@0: - "mov 0x28(%esp),%edi\n" michael@0: - "mov 0x2c(%esp),%esi\n" michael@0: - "mov 0x30(%esp),%ebp\n" michael@0: - "mov 0x34(%esp),%ecx\n" michael@0: - "xor %ebx,%ebx\n" michael@0: - "jmp scaleend\n" michael@0: - michael@0: -"scaleloop:" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - "movzbl (%edi,%eax,1),%eax\n" michael@0: - "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - "movzbl (%esi,%eax,1),%eax\n" michael@0: - "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "add 0x38(%esp),%ebx\n" michael@0: - "sar $0x10,%eax\n" michael@0: - "movzbl (%edx,%eax,1),%eax\n" michael@0: - "movq kCoefficientsRgbY(,%eax,8),%mm1\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "add 0x38(%esp),%ebx\n" michael@0: - "sar $0x10,%eax\n" michael@0: - "movzbl (%edx,%eax,1),%eax\n" michael@0: - "movq kCoefficientsRgbY(,%eax,8),%mm2\n" michael@0: - "paddsw %mm0,%mm1\n" michael@0: - "paddsw %mm0,%mm2\n" michael@0: - "psraw $0x6,%mm1\n" michael@0: - "psraw $0x6,%mm2\n" michael@0: - "packuswb %mm2,%mm1\n" michael@0: - "movntq %mm1,0x0(%ebp)\n" michael@0: - "add $0x8,%ebp\n" michael@0: -"scaleend:" michael@0: - "sub $0x2,%ecx\n" michael@0: - "jns scaleloop\n" michael@0: - michael@0: - "and $0x1,%ecx\n" michael@0: - "je scaledone\n" michael@0: - michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - "movzbl (%edi,%eax,1),%eax\n" michael@0: - "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - "movzbl (%esi,%eax,1),%eax\n" michael@0: - "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x10,%eax\n" michael@0: - "movzbl (%edx,%eax,1),%eax\n" michael@0: - "movq kCoefficientsRgbY(,%eax,8),%mm1\n" michael@0: - "paddsw %mm0,%mm1\n" michael@0: - "psraw $0x6,%mm1\n" michael@0: - "packuswb %mm1,%mm1\n" michael@0: - "movd %mm1,0x0(%ebp)\n" michael@0: - michael@0: -"scaledone:" michael@0: - "popa\n" michael@0: - "ret\n" michael@0: -); michael@0: - michael@0: -void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx); michael@0: - asm( michael@0: - ".text\n" michael@0: - ".global LinearScaleYUVToRGB32Row\n" michael@0: -"LinearScaleYUVToRGB32Row:\n" michael@0: - "pusha\n" michael@0: - "mov 0x24(%esp),%edx\n" michael@0: - "mov 0x28(%esp),%edi\n" michael@0: - "mov 0x30(%esp),%ebp\n" michael@0: - michael@0: - // source_width = width * source_dx + ebx michael@0: - "mov 0x34(%esp), %ecx\n" michael@0: - "imull 0x38(%esp), %ecx\n" michael@0: - "mov %ecx, 0x34(%esp)\n" michael@0: - michael@0: - "mov 0x38(%esp), %ecx\n" michael@0: - "xor %ebx,%ebx\n" // x = 0 michael@0: - "cmp $0x20000,%ecx\n" // if source_dx >= 2.0 michael@0: - "jl .lscaleend\n" michael@0: - "mov $0x8000,%ebx\n" // x = 0.5 for 1/2 or less michael@0: - "jmp .lscaleend\n" michael@0: - michael@0: -".lscaleloop:" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - michael@0: - "movzbl (%edi,%eax,1),%ecx\n" michael@0: - "movzbl 1(%edi,%eax,1),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "andl $0x1fffe, %eax \n" michael@0: - "imul %eax, %esi \n" michael@0: - "xorl $0x1fffe, %eax \n" michael@0: - "imul %eax, %ecx \n" michael@0: - "addl %esi, %ecx \n" michael@0: - "shrl $17, %ecx \n" michael@0: - "movq kCoefficientsRgbY+2048(,%ecx,8),%mm0\n" michael@0: - michael@0: - "mov 0x2c(%esp),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - michael@0: - "movzbl (%esi,%eax,1),%ecx\n" michael@0: - "movzbl 1(%esi,%eax,1),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "andl $0x1fffe, %eax \n" michael@0: - "imul %eax, %esi \n" michael@0: - "xorl $0x1fffe, %eax \n" michael@0: - "imul %eax, %ecx \n" michael@0: - "addl %esi, %ecx \n" michael@0: - "shrl $17, %ecx \n" michael@0: - "paddsw kCoefficientsRgbY+4096(,%ecx,8),%mm0\n" michael@0: - michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x10,%eax\n" michael@0: - "movzbl (%edx,%eax,1),%ecx\n" michael@0: - "movzbl 1(%edx,%eax,1),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "add 0x38(%esp),%ebx\n" michael@0: - "andl $0xffff, %eax \n" michael@0: - "imul %eax, %esi \n" michael@0: - "xorl $0xffff, %eax \n" michael@0: - "imul %eax, %ecx \n" michael@0: - "addl %esi, %ecx \n" michael@0: - "shrl $16, %ecx \n" michael@0: - "movq kCoefficientsRgbY(,%ecx,8),%mm1\n" michael@0: - michael@0: - "cmp 0x34(%esp), %ebx\n" michael@0: - "jge .lscalelastpixel\n" michael@0: - michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x10,%eax\n" michael@0: - "movzbl (%edx,%eax,1),%ecx\n" michael@0: - "movzbl 1(%edx,%eax,1),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "add 0x38(%esp),%ebx\n" michael@0: - "andl $0xffff, %eax \n" michael@0: - "imul %eax, %esi \n" michael@0: - "xorl $0xffff, %eax \n" michael@0: - "imul %eax, %ecx \n" michael@0: - "addl %esi, %ecx \n" michael@0: - "shrl $16, %ecx \n" michael@0: - "movq kCoefficientsRgbY(,%ecx,8),%mm2\n" michael@0: - michael@0: - "paddsw %mm0,%mm1\n" michael@0: - "paddsw %mm0,%mm2\n" michael@0: - "psraw $0x6,%mm1\n" michael@0: - "psraw $0x6,%mm2\n" michael@0: - "packuswb %mm2,%mm1\n" michael@0: - "movntq %mm1,0x0(%ebp)\n" michael@0: - "add $0x8,%ebp\n" michael@0: - michael@0: -".lscaleend:" michael@0: - "cmp 0x34(%esp), %ebx\n" michael@0: - "jl .lscaleloop\n" michael@0: - "popa\n" michael@0: - "ret\n" michael@0: - michael@0: -".lscalelastpixel:" michael@0: - "paddsw %mm0, %mm1\n" michael@0: - "psraw $6, %mm1\n" michael@0: - "packuswb %mm1, %mm1\n" michael@0: - "movd %mm1, (%ebp)\n" michael@0: - "popa\n" michael@0: - "ret\n" michael@0: -); michael@0: - michael@0: -#elif USE_MMX && !defined(ARCH_CPU_X86_64) && defined(__PIC__) michael@0: - michael@0: -extern void PICConvertYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int16 *kCoefficientsRgbY); michael@0: - asm( michael@0: - ".text\n" michael@0: -#if defined(OS_MACOSX) michael@0: -"_PICConvertYUVToRGB32Row:\n" michael@0: -#else michael@0: -"PICConvertYUVToRGB32Row:\n" michael@0: -#endif michael@0: - "pusha\n" michael@0: - "mov 0x24(%esp),%edx\n" michael@0: - "mov 0x28(%esp),%edi\n" michael@0: - "mov 0x2c(%esp),%esi\n" michael@0: - "mov 0x30(%esp),%ebp\n" michael@0: - "mov 0x38(%esp),%ecx\n" michael@0: - michael@0: - "jmp .Lconvertend\n" michael@0: - michael@0: -".Lconvertloop:" michael@0: - "movzbl (%edi),%eax\n" michael@0: - "add $0x1,%edi\n" michael@0: - "movzbl (%esi),%ebx\n" michael@0: - "add $0x1,%esi\n" michael@0: - "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: - "movzbl (%edx),%eax\n" michael@0: - "paddsw 4096(%ecx,%ebx,8),%mm0\n" michael@0: - "movzbl 0x1(%edx),%ebx\n" michael@0: - "movq 0(%ecx,%eax,8),%mm1\n" michael@0: - "add $0x2,%edx\n" michael@0: - "movq 0(%ecx,%ebx,8),%mm2\n" michael@0: - "paddsw %mm0,%mm1\n" michael@0: - "paddsw %mm0,%mm2\n" michael@0: - "psraw $0x6,%mm1\n" michael@0: - "psraw $0x6,%mm2\n" michael@0: - "packuswb %mm2,%mm1\n" michael@0: - "movntq %mm1,0x0(%ebp)\n" michael@0: - "add $0x8,%ebp\n" michael@0: -".Lconvertend:" michael@0: - "subl $0x2,0x34(%esp)\n" michael@0: - "jns .Lconvertloop\n" michael@0: - michael@0: - "andl $0x1,0x34(%esp)\n" michael@0: - "je .Lconvertdone\n" michael@0: - michael@0: - "movzbl (%edi),%eax\n" michael@0: - "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: - "movzbl (%esi),%eax\n" michael@0: - "paddsw 4096(%ecx,%eax,8),%mm0\n" michael@0: - "movzbl (%edx),%eax\n" michael@0: - "movq 0(%ecx,%eax,8),%mm1\n" michael@0: - "paddsw %mm0,%mm1\n" michael@0: - "psraw $0x6,%mm1\n" michael@0: - "packuswb %mm1,%mm1\n" michael@0: - "movd %mm1,0x0(%ebp)\n" michael@0: -".Lconvertdone:\n" michael@0: - "popa\n" michael@0: - "ret\n" michael@0: -); michael@0: - michael@0: -void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width) { michael@0: - PICConvertYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width, michael@0: - &kCoefficientsRgbY[0][0]); michael@0: -} michael@0: - michael@0: -extern void PICScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx, michael@0: - int16 *kCoefficientsRgbY); michael@0: - michael@0: - asm( michael@0: - ".text\n" michael@0: -#if defined(OS_MACOSX) michael@0: -"_PICScaleYUVToRGB32Row:\n" michael@0: -#else michael@0: -"PICScaleYUVToRGB32Row:\n" michael@0: -#endif michael@0: - "pusha\n" michael@0: - "mov 0x24(%esp),%edx\n" michael@0: - "mov 0x28(%esp),%edi\n" michael@0: - "mov 0x2c(%esp),%esi\n" michael@0: - "mov 0x30(%esp),%ebp\n" michael@0: - "mov 0x3c(%esp),%ecx\n" michael@0: - "xor %ebx,%ebx\n" michael@0: - "jmp Lscaleend\n" michael@0: - michael@0: -"Lscaleloop:" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - "movzbl (%edi,%eax,1),%eax\n" michael@0: - "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - "movzbl (%esi,%eax,1),%eax\n" michael@0: - "paddsw 4096(%ecx,%eax,8),%mm0\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "add 0x38(%esp),%ebx\n" michael@0: - "sar $0x10,%eax\n" michael@0: - "movzbl (%edx,%eax,1),%eax\n" michael@0: - "movq 0(%ecx,%eax,8),%mm1\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "add 0x38(%esp),%ebx\n" michael@0: - "sar $0x10,%eax\n" michael@0: - "movzbl (%edx,%eax,1),%eax\n" michael@0: - "movq 0(%ecx,%eax,8),%mm2\n" michael@0: - "paddsw %mm0,%mm1\n" michael@0: - "paddsw %mm0,%mm2\n" michael@0: - "psraw $0x6,%mm1\n" michael@0: - "psraw $0x6,%mm2\n" michael@0: - "packuswb %mm2,%mm1\n" michael@0: - "movntq %mm1,0x0(%ebp)\n" michael@0: - "add $0x8,%ebp\n" michael@0: -"Lscaleend:" michael@0: - "subl $0x2,0x34(%esp)\n" michael@0: - "jns Lscaleloop\n" michael@0: - michael@0: - "andl $0x1,0x34(%esp)\n" michael@0: - "je Lscaledone\n" michael@0: - michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - "movzbl (%edi,%eax,1),%eax\n" michael@0: - "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - "movzbl (%esi,%eax,1),%eax\n" michael@0: - "paddsw 4096(%ecx,%eax,8),%mm0\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x10,%eax\n" michael@0: - "movzbl (%edx,%eax,1),%eax\n" michael@0: - "movq 0(%ecx,%eax,8),%mm1\n" michael@0: - "paddsw %mm0,%mm1\n" michael@0: - "psraw $0x6,%mm1\n" michael@0: - "packuswb %mm1,%mm1\n" michael@0: - "movd %mm1,0x0(%ebp)\n" michael@0: - michael@0: -"Lscaledone:" michael@0: - "popa\n" michael@0: - "ret\n" michael@0: -); michael@0: - michael@0: - michael@0: -void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx) { michael@0: - PICScaleYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width, source_dx, michael@0: - &kCoefficientsRgbY[0][0]); michael@0: -} michael@0: - michael@0: -void PICLinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx, michael@0: - int16 *kCoefficientsRgbY); michael@0: - asm( michael@0: - ".text\n" michael@0: -#if defined(OS_MACOSX) michael@0: -"_PICLinearScaleYUVToRGB32Row:\n" michael@0: -#else michael@0: -"PICLinearScaleYUVToRGB32Row:\n" michael@0: -#endif michael@0: - "pusha\n" michael@0: - "mov 0x24(%esp),%edx\n" michael@0: - "mov 0x30(%esp),%ebp\n" michael@0: - "mov 0x34(%esp),%ecx\n" michael@0: - "mov 0x3c(%esp),%edi\n" michael@0: - "xor %ebx,%ebx\n" michael@0: - michael@0: - // source_width = width * source_dx + ebx michael@0: - "mov 0x34(%esp), %ecx\n" michael@0: - "imull 0x38(%esp), %ecx\n" michael@0: - "mov %ecx, 0x34(%esp)\n" michael@0: - michael@0: - "mov 0x38(%esp), %ecx\n" michael@0: - "xor %ebx,%ebx\n" // x = 0 michael@0: - "cmp $0x20000,%ecx\n" // if source_dx >= 2.0 michael@0: - "jl .lscaleend\n" michael@0: - "mov $0x8000,%ebx\n" // x = 0.5 for 1/2 or less michael@0: - "jmp .lscaleend\n" michael@0: - michael@0: -".lscaleloop:" michael@0: - "mov 0x28(%esp),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - michael@0: - "movzbl (%esi,%eax,1),%ecx\n" michael@0: - "movzbl 1(%esi,%eax,1),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "andl $0x1fffe, %eax \n" michael@0: - "imul %eax, %esi \n" michael@0: - "xorl $0x1fffe, %eax \n" michael@0: - "imul %eax, %ecx \n" michael@0: - "addl %esi, %ecx \n" michael@0: - "shrl $17, %ecx \n" michael@0: - "movq 2048(%edi,%ecx,8),%mm0\n" michael@0: - michael@0: - "mov 0x2c(%esp),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: - michael@0: - "movzbl (%esi,%eax,1),%ecx\n" michael@0: - "movzbl 1(%esi,%eax,1),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "andl $0x1fffe, %eax \n" michael@0: - "imul %eax, %esi \n" michael@0: - "xorl $0x1fffe, %eax \n" michael@0: - "imul %eax, %ecx \n" michael@0: - "addl %esi, %ecx \n" michael@0: - "shrl $17, %ecx \n" michael@0: - "paddsw 4096(%edi,%ecx,8),%mm0\n" michael@0: - michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x10,%eax\n" michael@0: - "movzbl (%edx,%eax,1),%ecx\n" michael@0: - "movzbl 1(%edx,%eax,1),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "add 0x38(%esp),%ebx\n" michael@0: - "andl $0xffff, %eax \n" michael@0: - "imul %eax, %esi \n" michael@0: - "xorl $0xffff, %eax \n" michael@0: - "imul %eax, %ecx \n" michael@0: - "addl %esi, %ecx \n" michael@0: - "shrl $16, %ecx \n" michael@0: - "movq (%edi,%ecx,8),%mm1\n" michael@0: - michael@0: - "cmp 0x34(%esp), %ebx\n" michael@0: - "jge .lscalelastpixel\n" michael@0: - michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x10,%eax\n" michael@0: - "movzbl (%edx,%eax,1),%ecx\n" michael@0: - "movzbl 1(%edx,%eax,1),%esi\n" michael@0: - "mov %ebx,%eax\n" michael@0: - "add 0x38(%esp),%ebx\n" michael@0: - "andl $0xffff, %eax \n" michael@0: - "imul %eax, %esi \n" michael@0: - "xorl $0xffff, %eax \n" michael@0: - "imul %eax, %ecx \n" michael@0: - "addl %esi, %ecx \n" michael@0: - "shrl $16, %ecx \n" michael@0: - "movq (%edi,%ecx,8),%mm2\n" michael@0: - michael@0: - "paddsw %mm0,%mm1\n" michael@0: - "paddsw %mm0,%mm2\n" michael@0: - "psraw $0x6,%mm1\n" michael@0: - "psraw $0x6,%mm2\n" michael@0: - "packuswb %mm2,%mm1\n" michael@0: - "movntq %mm1,0x0(%ebp)\n" michael@0: - "add $0x8,%ebp\n" michael@0: - michael@0: -".lscaleend:" michael@0: - "cmp %ebx, 0x34(%esp)\n" michael@0: - "jg .lscaleloop\n" michael@0: - "popa\n" michael@0: - "ret\n" michael@0: - michael@0: -".lscalelastpixel:" michael@0: - "paddsw %mm0, %mm1\n" michael@0: - "psraw $6, %mm1\n" michael@0: - "packuswb %mm1, %mm1\n" michael@0: - "movd %mm1, (%ebp)\n" michael@0: - "popa\n" michael@0: - "ret\n" michael@0: -); michael@0: - michael@0: -void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx) { michael@0: - PICLinearScaleYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width, source_dx, michael@0: - &kCoefficientsRgbY[0][0]); michael@0: -} michael@0: - michael@0: -#else // USE_MMX michael@0: - michael@0: // C reference code that mimic the YUV assembly. michael@0: #define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x))) michael@0: #define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \ michael@0: (((x) + (y)) > 32767 ? 32767 : ((x) + (y)))) michael@0: michael@0: static inline void YuvPixel(uint8 y, michael@0: uint8 u, michael@0: uint8 v, michael@0: @@ -833,66 +39,71 @@ static inline void YuvPixel(uint8 y, michael@0: a >>= 6; michael@0: michael@0: *reinterpret_cast(rgb_buf) = (packuswb(b)) | michael@0: (packuswb(g) << 8) | michael@0: (packuswb(r) << 16) | michael@0: (packuswb(a) << 24); michael@0: } michael@0: michael@0: -void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width) { michael@0: +void FastConvertYUVToRGB32Row_C(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + unsigned int x_shift) { michael@0: for (int x = 0; x < width; x += 2) { michael@0: - uint8 u = u_buf[x >> 1]; michael@0: - uint8 v = v_buf[x >> 1]; michael@0: + uint8 u = u_buf[x >> x_shift]; michael@0: + uint8 v = v_buf[x >> x_shift]; michael@0: uint8 y0 = y_buf[x]; michael@0: YuvPixel(y0, u, v, rgb_buf); michael@0: if ((x + 1) < width) { michael@0: uint8 y1 = y_buf[x + 1]; michael@0: + if (x_shift == 0) { michael@0: + u = u_buf[x + 1]; michael@0: + v = v_buf[x + 1]; michael@0: + } michael@0: YuvPixel(y1, u, v, rgb_buf + 4); michael@0: } michael@0: rgb_buf += 8; // Advance 2 pixels. michael@0: } michael@0: } michael@0: michael@0: // 16.16 fixed point is used. A shift by 16 isolates the integer. michael@0: // A shift by 17 is used to further subsample the chrominence channels. michael@0: // & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits, michael@0: // for 1/65536 pixel accurate interpolation. michael@0: -void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx) { michael@0: +void ScaleYUVToRGB32Row_C(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx) { michael@0: int x = 0; michael@0: for (int i = 0; i < width; i += 2) { michael@0: int y = y_buf[x >> 16]; michael@0: int u = u_buf[(x >> 17)]; michael@0: int v = v_buf[(x >> 17)]; michael@0: YuvPixel(y, u, v, rgb_buf); michael@0: x += source_dx; michael@0: if ((i + 1) < width) { michael@0: y = y_buf[x >> 16]; michael@0: YuvPixel(y, u, v, rgb_buf+4); michael@0: x += source_dx; michael@0: } michael@0: rgb_buf += 8; michael@0: } michael@0: } michael@0: michael@0: -void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx) { michael@0: +void LinearScaleYUVToRGB32Row_C(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx) { michael@0: int x = 0; michael@0: if (source_dx >= 0x20000) { michael@0: x = 32768; michael@0: } michael@0: for (int i = 0; i < width; i += 2) { michael@0: int y0 = y_buf[x >> 16]; michael@0: int y1 = y_buf[(x >> 16) + 1]; michael@0: int u0 = u_buf[(x >> 17)]; michael@0: @@ -913,11 +124,10 @@ void LinearScaleYUVToRGB32Row(const uint michael@0: y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; michael@0: YuvPixel(y, u, v, rgb_buf+4); michael@0: x += source_dx; michael@0: } michael@0: rgb_buf += 8; michael@0: } michael@0: } michael@0: michael@0: -#endif // USE_MMX michael@0: } // extern "C" michael@0: michael@0: diff --git a/gfx/ycbcr/yuv_row_posix.cpp b/gfx/ycbcr/yuv_row_posix.cpp michael@0: --- a/gfx/ycbcr/yuv_row_posix.cpp michael@0: +++ b/gfx/ycbcr/yuv_row_posix.cpp michael@0: @@ -1,33 +1,32 @@ michael@0: // Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: -#include "media/base/yuv_row.h" michael@0: - michael@0: -#ifdef _DEBUG michael@0: -#include "base/logging.h" michael@0: -#else michael@0: +#include "yuv_row.h" michael@0: +#include "mozilla/SSE.h" michael@0: + michael@0: #define DCHECK(a) michael@0: -#endif michael@0: michael@0: extern "C" { michael@0: michael@0: -#if USE_SSE2 && defined(ARCH_CPU_X86_64) michael@0: +#if defined(ARCH_CPU_X86_64) michael@0: + michael@0: +// We don't need CPUID guards here, since x86-64 implies SSE2. michael@0: michael@0: // AMD64 ABI uses register paremters. michael@0: void FastConvertYUVToRGB32Row(const uint8* y_buf, // rdi michael@0: const uint8* u_buf, // rsi michael@0: const uint8* v_buf, // rdx michael@0: uint8* rgb_buf, // rcx michael@0: int width) { // r8 michael@0: asm( michael@0: - "jmp convertend\n" michael@0: -"convertloop:" michael@0: + "jmp 1f\n" michael@0: +"0:" michael@0: "movzb (%1),%%r10\n" michael@0: "add $0x1,%1\n" michael@0: "movzb (%2),%%r11\n" michael@0: "add $0x1,%2\n" michael@0: "movq 2048(%5,%%r10,8),%%xmm0\n" michael@0: "movzb (%0),%%r10\n" michael@0: "movq 4096(%5,%%r11,8),%%xmm1\n" michael@0: "movzb 0x1(%0),%%r11\n" michael@0: @@ -37,36 +36,36 @@ void FastConvertYUVToRGB32Row(const uint michael@0: "movq (%5,%%r11,8),%%xmm3\n" michael@0: "paddsw %%xmm0,%%xmm2\n" michael@0: "paddsw %%xmm0,%%xmm3\n" michael@0: "shufps $0x44,%%xmm3,%%xmm2\n" michael@0: "psraw $0x6,%%xmm2\n" michael@0: "packuswb %%xmm2,%%xmm2\n" michael@0: "movq %%xmm2,0x0(%3)\n" michael@0: "add $0x8,%3\n" michael@0: -"convertend:" michael@0: +"1:" michael@0: "sub $0x2,%4\n" michael@0: - "jns convertloop\n" michael@0: - michael@0: -"convertnext:" michael@0: + "jns 0b\n" michael@0: + michael@0: +"2:" michael@0: "add $0x1,%4\n" michael@0: - "js convertdone\n" michael@0: + "js 3f\n" michael@0: michael@0: "movzb (%1),%%r10\n" michael@0: "movq 2048(%5,%%r10,8),%%xmm0\n" michael@0: "movzb (%2),%%r10\n" michael@0: "movq 4096(%5,%%r10,8),%%xmm1\n" michael@0: "paddsw %%xmm1,%%xmm0\n" michael@0: "movzb (%0),%%r10\n" michael@0: "movq (%5,%%r10,8),%%xmm1\n" michael@0: "paddsw %%xmm0,%%xmm1\n" michael@0: "psraw $0x6,%%xmm1\n" michael@0: "packuswb %%xmm1,%%xmm1\n" michael@0: "movd %%xmm1,0x0(%3)\n" michael@0: -"convertdone:" michael@0: +"3:" michael@0: : michael@0: : "r"(y_buf), // %0 michael@0: "r"(u_buf), // %1 michael@0: "r"(v_buf), // %2 michael@0: "r"(rgb_buf), // %3 michael@0: "r"(width), // %4 michael@0: "r" (kCoefficientsRgbY) // %5 michael@0: : "memory", "r10", "r11", "xmm0", "xmm1", "xmm2", "xmm3" michael@0: @@ -77,19 +76,19 @@ void ScaleYUVToRGB32Row(const uint8* y_b michael@0: const uint8* u_buf, // rsi michael@0: const uint8* v_buf, // rdx michael@0: uint8* rgb_buf, // rcx michael@0: int width, // r8 michael@0: int source_dx) { // r9 michael@0: asm( michael@0: "xor %%r11,%%r11\n" michael@0: "sub $0x2,%4\n" michael@0: - "js scalenext\n" michael@0: - michael@0: -"scaleloop:" michael@0: + "js 1f\n" michael@0: + michael@0: +"0:" michael@0: "mov %%r11,%%r10\n" michael@0: "sar $0x11,%%r10\n" michael@0: "movzb (%1,%%r10,1),%%rax\n" michael@0: "movq 2048(%5,%%rax,8),%%xmm0\n" michael@0: "movzb (%2,%%r10,1),%%rax\n" michael@0: "movq 4096(%5,%%rax,8),%%xmm1\n" michael@0: "lea (%%r11,%6),%%r10\n" michael@0: "sar $0x10,%%r11\n" michael@0: @@ -103,38 +102,38 @@ void ScaleYUVToRGB32Row(const uint8* y_b michael@0: "paddsw %%xmm0,%%xmm1\n" michael@0: "paddsw %%xmm0,%%xmm2\n" michael@0: "shufps $0x44,%%xmm2,%%xmm1\n" michael@0: "psraw $0x6,%%xmm1\n" michael@0: "packuswb %%xmm1,%%xmm1\n" michael@0: "movq %%xmm1,0x0(%3)\n" michael@0: "add $0x8,%3\n" michael@0: "sub $0x2,%4\n" michael@0: - "jns scaleloop\n" michael@0: - michael@0: -"scalenext:" michael@0: + "jns 0b\n" michael@0: + michael@0: +"1:" michael@0: "add $0x1,%4\n" michael@0: - "js scaledone\n" michael@0: + "js 2f\n" michael@0: michael@0: "mov %%r11,%%r10\n" michael@0: "sar $0x11,%%r10\n" michael@0: "movzb (%1,%%r10,1),%%rax\n" michael@0: "movq 2048(%5,%%rax,8),%%xmm0\n" michael@0: "movzb (%2,%%r10,1),%%rax\n" michael@0: "movq 4096(%5,%%rax,8),%%xmm1\n" michael@0: "paddsw %%xmm1,%%xmm0\n" michael@0: "sar $0x10,%%r11\n" michael@0: "movzb (%0,%%r11,1),%%rax\n" michael@0: "movq (%5,%%rax,8),%%xmm1\n" michael@0: "paddsw %%xmm0,%%xmm1\n" michael@0: "psraw $0x6,%%xmm1\n" michael@0: "packuswb %%xmm1,%%xmm1\n" michael@0: "movd %%xmm1,0x0(%3)\n" michael@0: michael@0: -"scaledone:" michael@0: +"2:" michael@0: : michael@0: : "r"(y_buf), // %0 michael@0: "r"(u_buf), // %1 michael@0: "r"(v_buf), // %2 michael@0: "r"(rgb_buf), // %3 michael@0: "r"(width), // %4 michael@0: "r" (kCoefficientsRgbY), // %5 michael@0: "r"(static_cast(source_dx)) // %6 michael@0: @@ -146,23 +145,23 @@ void LinearScaleYUVToRGB32Row(const uint michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) { michael@0: asm( michael@0: "xor %%r11,%%r11\n" // x = 0 michael@0: "sub $0x2,%4\n" michael@0: - "js .lscalenext\n" michael@0: + "js 2f\n" michael@0: "cmp $0x20000,%6\n" // if source_dx >= 2.0 michael@0: - "jl .lscalehalf\n" michael@0: + "jl 0f\n" michael@0: "mov $0x8000,%%r11\n" // x = 0.5 for 1/2 or less michael@0: -".lscalehalf:" michael@0: - michael@0: -".lscaleloop:" michael@0: +"0:" michael@0: + michael@0: +"1:" michael@0: "mov %%r11,%%r10\n" michael@0: "sar $0x11,%%r10\n" michael@0: michael@0: "movzb (%1, %%r10, 1), %%r13 \n" michael@0: "movzb 1(%1, %%r10, 1), %%r14 \n" michael@0: "mov %%r11, %%rax \n" michael@0: "and $0x1fffe, %%rax \n" michael@0: "imul %%rax, %%r14 \n" michael@0: @@ -215,21 +214,21 @@ void LinearScaleYUVToRGB32Row(const uint michael@0: "paddsw %%xmm0,%%xmm1\n" michael@0: "paddsw %%xmm0,%%xmm2\n" michael@0: "shufps $0x44,%%xmm2,%%xmm1\n" michael@0: "psraw $0x6,%%xmm1\n" michael@0: "packuswb %%xmm1,%%xmm1\n" michael@0: "movq %%xmm1,0x0(%3)\n" michael@0: "add $0x8,%3\n" michael@0: "sub $0x2,%4\n" michael@0: - "jns .lscaleloop\n" michael@0: - michael@0: -".lscalenext:" michael@0: + "jns 1b\n" michael@0: + michael@0: +"2:" michael@0: "add $0x1,%4\n" michael@0: - "js .lscaledone\n" michael@0: + "js 3f\n" michael@0: michael@0: "mov %%r11,%%r10\n" michael@0: "sar $0x11,%%r10\n" michael@0: michael@0: "movzb (%1,%%r10,1), %%r13 \n" michael@0: "movq 2048(%5,%%r13,8),%%xmm0\n" michael@0: michael@0: "movzb (%2,%%r10,1), %%r13 \n" michael@0: @@ -241,52 +240,52 @@ void LinearScaleYUVToRGB32Row(const uint michael@0: "movzb (%0,%%r11,1), %%r13 \n" michael@0: "movq (%5,%%r13,8),%%xmm1\n" michael@0: michael@0: "paddsw %%xmm0,%%xmm1\n" michael@0: "psraw $0x6,%%xmm1\n" michael@0: "packuswb %%xmm1,%%xmm1\n" michael@0: "movd %%xmm1,0x0(%3)\n" michael@0: michael@0: -".lscaledone:" michael@0: +"3:" michael@0: : michael@0: : "r"(y_buf), // %0 michael@0: "r"(u_buf), // %1 michael@0: "r"(v_buf), // %2 michael@0: "r"(rgb_buf), // %3 michael@0: "r"(width), // %4 michael@0: "r" (kCoefficientsRgbY), // %5 michael@0: "r"(static_cast(source_dx)) // %6 michael@0: : "memory", "r10", "r11", "r13", "r14", "rax", "xmm0", "xmm1", "xmm2" michael@0: ); michael@0: } michael@0: michael@0: -#elif USE_MMX && !defined(ARCH_CPU_X86_64) && !defined(__PIC__) michael@0: +#elif defined(MOZILLA_MAY_SUPPORT_SSE) && defined(ARCH_CPU_X86_32) && !defined(__PIC__) michael@0: michael@0: // PIC version is slower because less registers are available, so michael@0: // non-PIC is used on platforms where it is possible. michael@0: - michael@0: -void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width); michael@0: +void FastConvertYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width); michael@0: asm( michael@0: ".text\n" michael@0: - ".global FastConvertYUVToRGB32Row\n" michael@0: -"FastConvertYUVToRGB32Row:\n" michael@0: + ".global FastConvertYUVToRGB32Row_SSE\n" michael@0: + ".type FastConvertYUVToRGB32Row_SSE, @function\n" michael@0: +"FastConvertYUVToRGB32Row_SSE:\n" michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x28(%esp),%edi\n" michael@0: "mov 0x2c(%esp),%esi\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: "mov 0x34(%esp),%ecx\n" michael@0: - "jmp convertend\n" michael@0: - michael@0: -"convertloop:" michael@0: + "jmp 1f\n" michael@0: + michael@0: +"0:" michael@0: "movzbl (%edi),%eax\n" michael@0: "add $0x1,%edi\n" michael@0: "movzbl (%esi),%ebx\n" michael@0: "add $0x1,%esi\n" michael@0: "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: "movzbl (%edx),%eax\n" michael@0: "paddsw kCoefficientsRgbY+4096(,%ebx,8),%mm0\n" michael@0: "movzbl 0x1(%edx),%ebx\n" michael@0: @@ -295,59 +294,77 @@ void FastConvertYUVToRGB32Row(const uint michael@0: "movq kCoefficientsRgbY(,%ebx,8),%mm2\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: -"convertend:" michael@0: +"1:" michael@0: "sub $0x2,%ecx\n" michael@0: - "jns convertloop\n" michael@0: + "jns 0b\n" michael@0: michael@0: "and $0x1,%ecx\n" michael@0: - "je convertdone\n" michael@0: + "je 2f\n" michael@0: michael@0: "movzbl (%edi),%eax\n" michael@0: "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: "movzbl (%esi),%eax\n" michael@0: "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" michael@0: "movzbl (%edx),%eax\n" michael@0: "movq kCoefficientsRgbY(,%eax,8),%mm1\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "packuswb %mm1,%mm1\n" michael@0: "movd %mm1,0x0(%ebp)\n" michael@0: -"convertdone:" michael@0: +"2:" michael@0: "popa\n" michael@0: "ret\n" michael@0: +#if !defined(XP_MACOSX) michael@0: + ".previous\n" michael@0: +#endif michael@0: ); michael@0: michael@0: - michael@0: -void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx); michael@0: +void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width) michael@0: +{ michael@0: + if (mozilla::supports_sse()) { michael@0: + FastConvertYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width); michael@0: + return; michael@0: + } michael@0: + michael@0: + FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, 1); michael@0: +} michael@0: + michael@0: + michael@0: +void ScaleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx); michael@0: asm( michael@0: ".text\n" michael@0: - ".global ScaleYUVToRGB32Row\n" michael@0: -"ScaleYUVToRGB32Row:\n" michael@0: + ".global ScaleYUVToRGB32Row_SSE\n" michael@0: + ".type ScaleYUVToRGB32Row_SSE, @function\n" michael@0: +"ScaleYUVToRGB32Row_SSE:\n" michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x28(%esp),%edi\n" michael@0: "mov 0x2c(%esp),%esi\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: "mov 0x34(%esp),%ecx\n" michael@0: "xor %ebx,%ebx\n" michael@0: - "jmp scaleend\n" michael@0: - michael@0: -"scaleloop:" michael@0: + "jmp 1f\n" michael@0: + michael@0: +"0:" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%edi,%eax,1),%eax\n" michael@0: "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%esi,%eax,1),%eax\n" michael@0: "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" michael@0: @@ -363,22 +380,22 @@ void ScaleYUVToRGB32Row(const uint8* y_b michael@0: "movq kCoefficientsRgbY(,%eax,8),%mm2\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: -"scaleend:" michael@0: +"1:" michael@0: "sub $0x2,%ecx\n" michael@0: - "jns scaleloop\n" michael@0: + "jns 0b\n" michael@0: michael@0: "and $0x1,%ecx\n" michael@0: - "je scaledone\n" michael@0: + "je 2f\n" michael@0: michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%edi,%eax,1),%eax\n" michael@0: "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%esi,%eax,1),%eax\n" michael@0: @@ -387,51 +404,71 @@ void ScaleYUVToRGB32Row(const uint8* y_b michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%eax\n" michael@0: "movq kCoefficientsRgbY(,%eax,8),%mm1\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "packuswb %mm1,%mm1\n" michael@0: "movd %mm1,0x0(%ebp)\n" michael@0: michael@0: -"scaledone:" michael@0: +"2:" michael@0: "popa\n" michael@0: "ret\n" michael@0: +#if !defined(XP_MACOSX) michael@0: + ".previous\n" michael@0: +#endif michael@0: ); michael@0: michael@0: -void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx); michael@0: +void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx) michael@0: +{ michael@0: + if (mozilla::supports_sse()) { michael@0: + ScaleYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, michael@0: + width, source_dx); michael@0: + } michael@0: + michael@0: + ScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, michael@0: + width, source_dx); michael@0: +} michael@0: + michael@0: +void LinearScaleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx); michael@0: asm( michael@0: ".text\n" michael@0: - ".global LinearScaleYUVToRGB32Row\n" michael@0: -"LinearScaleYUVToRGB32Row:\n" michael@0: + ".global LinearScaleYUVToRGB32Row_SSE\n" michael@0: + ".type LinearScaleYUVToRGB32Row_SSE, @function\n" michael@0: +"LinearScaleYUVToRGB32Row_SSE:\n" michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x28(%esp),%edi\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: michael@0: // source_width = width * source_dx + ebx michael@0: "mov 0x34(%esp), %ecx\n" michael@0: "imull 0x38(%esp), %ecx\n" michael@0: "mov %ecx, 0x34(%esp)\n" michael@0: michael@0: "mov 0x38(%esp), %ecx\n" michael@0: "xor %ebx,%ebx\n" // x = 0 michael@0: "cmp $0x20000,%ecx\n" // if source_dx >= 2.0 michael@0: - "jl .lscaleend\n" michael@0: + "jl 1f\n" michael@0: "mov $0x8000,%ebx\n" // x = 0.5 for 1/2 or less michael@0: - "jmp .lscaleend\n" michael@0: - michael@0: -".lscaleloop:" michael@0: - "mov %ebx,%eax\n" michael@0: - "sar $0x11,%eax\n" michael@0: + "jmp 1f\n" michael@0: + michael@0: +"0:" michael@0: + "mov %ebx,%eax\n" michael@0: + "sar $0x11,%eax\n" michael@0: michael@0: "movzbl (%edi,%eax,1),%ecx\n" michael@0: "movzbl 1(%edi,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "andl $0x1fffe, %eax \n" michael@0: "imul %eax, %esi \n" michael@0: "xorl $0x1fffe, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: @@ -464,17 +501,17 @@ void LinearScaleYUVToRGB32Row(const uint michael@0: "imul %eax, %esi \n" michael@0: "xorl $0xffff, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: "addl %esi, %ecx \n" michael@0: "shrl $16, %ecx \n" michael@0: "movq kCoefficientsRgbY(,%ecx,8),%mm1\n" michael@0: michael@0: "cmp 0x34(%esp), %ebx\n" michael@0: - "jge .lscalelastpixel\n" michael@0: + "jge 2f\n" michael@0: michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%ecx\n" michael@0: "movzbl 1(%edx,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "add 0x38(%esp),%ebx\n" michael@0: "andl $0xffff, %eax \n" michael@0: @@ -488,56 +525,76 @@ void LinearScaleYUVToRGB32Row(const uint michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: michael@0: -".lscaleend:" michael@0: +"1:" michael@0: "cmp 0x34(%esp), %ebx\n" michael@0: - "jl .lscaleloop\n" michael@0: + "jl 0b\n" michael@0: "popa\n" michael@0: "ret\n" michael@0: michael@0: -".lscalelastpixel:" michael@0: +"2:" michael@0: "paddsw %mm0, %mm1\n" michael@0: "psraw $6, %mm1\n" michael@0: "packuswb %mm1, %mm1\n" michael@0: "movd %mm1, (%ebp)\n" michael@0: "popa\n" michael@0: "ret\n" michael@0: +#if !defined(XP_MACOSX) michael@0: + ".previous\n" michael@0: +#endif michael@0: ); michael@0: michael@0: -#elif USE_MMX && !defined(ARCH_CPU_X86_64) && defined(__PIC__) michael@0: - michael@0: -extern void PICConvertYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int16 *kCoefficientsRgbY); michael@0: +void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx) michael@0: +{ michael@0: + if (mozilla::supports_sse()) { michael@0: + LinearScaleYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, michael@0: + width, source_dx); michael@0: + } michael@0: + michael@0: + LinearScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, michael@0: + width, source_dx); michael@0: +} michael@0: + michael@0: +#elif defined(MOZILLA_MAY_SUPPORT_SSE) && defined(ARCH_CPU_X86_32) && defined(__PIC__) michael@0: + michael@0: +void PICConvertYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int16 *kCoefficientsRgbY); michael@0: + michael@0: asm( michael@0: ".text\n" michael@0: -#if defined(OS_MACOSX) michael@0: -"_PICConvertYUVToRGB32Row:\n" michael@0: +#if defined(XP_MACOSX) michael@0: +"_PICConvertYUVToRGB32Row_SSE:\n" michael@0: #else michael@0: -"PICConvertYUVToRGB32Row:\n" michael@0: +"PICConvertYUVToRGB32Row_SSE:\n" michael@0: #endif michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x28(%esp),%edi\n" michael@0: "mov 0x2c(%esp),%esi\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: "mov 0x38(%esp),%ecx\n" michael@0: michael@0: - "jmp .Lconvertend\n" michael@0: - michael@0: -".Lconvertloop:" michael@0: + "jmp 1f\n" michael@0: + michael@0: +"0:" michael@0: "movzbl (%edi),%eax\n" michael@0: "add $0x1,%edi\n" michael@0: "movzbl (%esi),%ebx\n" michael@0: "add $0x1,%esi\n" michael@0: "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: "movzbl (%edx),%eax\n" michael@0: "paddsw 4096(%ecx,%ebx,8),%mm0\n" michael@0: "movzbl 0x1(%edx),%ebx\n" michael@0: @@ -546,72 +603,81 @@ extern void PICConvertYUVToRGB32Row(cons michael@0: "movq 0(%ecx,%ebx,8),%mm2\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: -".Lconvertend:" michael@0: +"1:" michael@0: "subl $0x2,0x34(%esp)\n" michael@0: - "jns .Lconvertloop\n" michael@0: + "jns 0b\n" michael@0: michael@0: "andl $0x1,0x34(%esp)\n" michael@0: - "je .Lconvertdone\n" michael@0: + "je 2f\n" michael@0: michael@0: "movzbl (%edi),%eax\n" michael@0: "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: "movzbl (%esi),%eax\n" michael@0: "paddsw 4096(%ecx,%eax,8),%mm0\n" michael@0: "movzbl (%edx),%eax\n" michael@0: "movq 0(%ecx,%eax,8),%mm1\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "packuswb %mm1,%mm1\n" michael@0: "movd %mm1,0x0(%ebp)\n" michael@0: -".Lconvertdone:\n" michael@0: +"2:" michael@0: "popa\n" michael@0: "ret\n" michael@0: +#if !defined(XP_MACOSX) michael@0: + ".previous\n" michael@0: +#endif michael@0: ); michael@0: michael@0: void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: - int width) { michael@0: - PICConvertYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width, michael@0: - &kCoefficientsRgbY[0][0]); michael@0: -} michael@0: - michael@0: -extern void PICScaleYUVToRGB32Row(const uint8* y_buf, michael@0: + int width) michael@0: +{ michael@0: + if (mozilla::supports_sse()) { michael@0: + PICConvertYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width, michael@0: + &kCoefficientsRgbY[0][0]); michael@0: + return; michael@0: + } michael@0: + michael@0: + FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, 1); michael@0: +} michael@0: + michael@0: +void PICScaleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx, michael@0: int16 *kCoefficientsRgbY); michael@0: michael@0: asm( michael@0: ".text\n" michael@0: -#if defined(OS_MACOSX) michael@0: -"_PICScaleYUVToRGB32Row:\n" michael@0: +#if defined(XP_MACOSX) michael@0: +"_PICScaleYUVToRGB32Row_SSE:\n" michael@0: #else michael@0: -"PICScaleYUVToRGB32Row:\n" michael@0: +"PICScaleYUVToRGB32Row_SSE:\n" michael@0: #endif michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x28(%esp),%edi\n" michael@0: "mov 0x2c(%esp),%esi\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: "mov 0x3c(%esp),%ecx\n" michael@0: "xor %ebx,%ebx\n" michael@0: - "jmp Lscaleend\n" michael@0: - michael@0: -"Lscaleloop:" michael@0: + "jmp 1f\n" michael@0: + michael@0: +"0:" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%edi,%eax,1),%eax\n" michael@0: "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%esi,%eax,1),%eax\n" michael@0: "paddsw 4096(%ecx,%eax,8),%mm0\n" michael@0: @@ -627,22 +693,22 @@ extern void PICScaleYUVToRGB32Row(const michael@0: "movq 0(%ecx,%eax,8),%mm2\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: -"Lscaleend:" michael@0: +"1:" michael@0: "subl $0x2,0x34(%esp)\n" michael@0: - "jns Lscaleloop\n" michael@0: + "jns 0b\n" michael@0: michael@0: "andl $0x1,0x34(%esp)\n" michael@0: - "je Lscaledone\n" michael@0: + "je 2f\n" michael@0: michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%edi,%eax,1),%eax\n" michael@0: "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%esi,%eax,1),%eax\n" michael@0: @@ -651,66 +717,75 @@ extern void PICScaleYUVToRGB32Row(const michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%eax\n" michael@0: "movq 0(%ecx,%eax,8),%mm1\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "packuswb %mm1,%mm1\n" michael@0: "movd %mm1,0x0(%ebp)\n" michael@0: michael@0: -"Lscaledone:" michael@0: +"2:" michael@0: "popa\n" michael@0: "ret\n" michael@0: +#if !defined(XP_MACOSX) michael@0: + ".previous\n" michael@0: +#endif michael@0: ); michael@0: michael@0: - michael@0: void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: - int source_dx) { michael@0: - PICScaleYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width, source_dx, michael@0: - &kCoefficientsRgbY[0][0]); michael@0: -} michael@0: - michael@0: -void PICLinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx, michael@0: - int16 *kCoefficientsRgbY); michael@0: + int source_dx) michael@0: +{ michael@0: + if (mozilla::supports_sse()) { michael@0: + PICScaleYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width, source_dx, michael@0: + &kCoefficientsRgbY[0][0]); michael@0: + return; michael@0: + } michael@0: + michael@0: + ScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: +} michael@0: + michael@0: +void PICLinearScaleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx, michael@0: + int16 *kCoefficientsRgbY); michael@0: + michael@0: asm( michael@0: ".text\n" michael@0: -#if defined(OS_MACOSX) michael@0: -"_PICLinearScaleYUVToRGB32Row:\n" michael@0: +#if defined(XP_MACOSX) michael@0: +"_PICLinearScaleYUVToRGB32Row_SSE:\n" michael@0: #else michael@0: -"PICLinearScaleYUVToRGB32Row:\n" michael@0: +"PICLinearScaleYUVToRGB32Row_SSE:\n" michael@0: #endif michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: "mov 0x34(%esp),%ecx\n" michael@0: "mov 0x3c(%esp),%edi\n" michael@0: "xor %ebx,%ebx\n" michael@0: michael@0: // source_width = width * source_dx + ebx michael@0: "mov 0x34(%esp), %ecx\n" michael@0: "imull 0x38(%esp), %ecx\n" michael@0: "mov %ecx, 0x34(%esp)\n" michael@0: michael@0: "mov 0x38(%esp), %ecx\n" michael@0: "xor %ebx,%ebx\n" // x = 0 michael@0: "cmp $0x20000,%ecx\n" // if source_dx >= 2.0 michael@0: - "jl .lscaleend\n" michael@0: + "jl 1f\n" michael@0: "mov $0x8000,%ebx\n" // x = 0.5 for 1/2 or less michael@0: - "jmp .lscaleend\n" michael@0: - michael@0: -".lscaleloop:" michael@0: + "jmp 1f\n" michael@0: + michael@0: +"0:" michael@0: "mov 0x28(%esp),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: michael@0: "movzbl (%esi,%eax,1),%ecx\n" michael@0: "movzbl 1(%esi,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "andl $0x1fffe, %eax \n" michael@0: @@ -746,17 +821,17 @@ void PICLinearScaleYUVToRGB32Row(const u michael@0: "imul %eax, %esi \n" michael@0: "xorl $0xffff, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: "addl %esi, %ecx \n" michael@0: "shrl $16, %ecx \n" michael@0: "movq (%edi,%ecx,8),%mm1\n" michael@0: michael@0: "cmp 0x34(%esp), %ebx\n" michael@0: - "jge .lscalelastpixel\n" michael@0: + "jge 2f\n" michael@0: michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%ecx\n" michael@0: "movzbl 1(%edx,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "add 0x38(%esp),%ebx\n" michael@0: "andl $0xffff, %eax \n" michael@0: @@ -770,154 +845,71 @@ void PICLinearScaleYUVToRGB32Row(const u michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: michael@0: -".lscaleend:" michael@0: +"1:" michael@0: "cmp %ebx, 0x34(%esp)\n" michael@0: - "jg .lscaleloop\n" michael@0: + "jg 0b\n" michael@0: "popa\n" michael@0: "ret\n" michael@0: michael@0: -".lscalelastpixel:" michael@0: +"2:" michael@0: "paddsw %mm0, %mm1\n" michael@0: "psraw $6, %mm1\n" michael@0: "packuswb %mm1, %mm1\n" michael@0: "movd %mm1, (%ebp)\n" michael@0: "popa\n" michael@0: "ret\n" michael@0: +#if !defined(XP_MACOSX) michael@0: + ".previous\n" michael@0: +#endif michael@0: ); michael@0: michael@0: + michael@0: void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx) { michael@0: - PICLinearScaleYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width, source_dx, michael@0: - &kCoefficientsRgbY[0][0]); michael@0: -} michael@0: - michael@0: -#else // USE_MMX michael@0: - michael@0: -// C reference code that mimic the YUV assembly. michael@0: -#define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x))) michael@0: -#define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \ michael@0: - (((x) + (y)) > 32767 ? 32767 : ((x) + (y)))) michael@0: - michael@0: -static inline void YuvPixel(uint8 y, michael@0: - uint8 u, michael@0: - uint8 v, michael@0: - uint8* rgb_buf) { michael@0: - michael@0: - int b = kCoefficientsRgbY[256+u][0]; michael@0: - int g = kCoefficientsRgbY[256+u][1]; michael@0: - int r = kCoefficientsRgbY[256+u][2]; michael@0: - int a = kCoefficientsRgbY[256+u][3]; michael@0: - michael@0: - b = paddsw(b, kCoefficientsRgbY[512+v][0]); michael@0: - g = paddsw(g, kCoefficientsRgbY[512+v][1]); michael@0: - r = paddsw(r, kCoefficientsRgbY[512+v][2]); michael@0: - a = paddsw(a, kCoefficientsRgbY[512+v][3]); michael@0: - michael@0: - b = paddsw(b, kCoefficientsRgbY[y][0]); michael@0: - g = paddsw(g, kCoefficientsRgbY[y][1]); michael@0: - r = paddsw(r, kCoefficientsRgbY[y][2]); michael@0: - a = paddsw(a, kCoefficientsRgbY[y][3]); michael@0: - michael@0: - b >>= 6; michael@0: - g >>= 6; michael@0: - r >>= 6; michael@0: - a >>= 6; michael@0: - michael@0: - *reinterpret_cast(rgb_buf) = (packuswb(b)) | michael@0: - (packuswb(g) << 8) | michael@0: - (packuswb(r) << 16) | michael@0: - (packuswb(a) << 24); michael@0: -} michael@0: - michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx) michael@0: +{ michael@0: + if (mozilla::supports_sse()) { michael@0: + PICLinearScaleYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width, michael@0: + source_dx, &kCoefficientsRgbY[0][0]); michael@0: + return; michael@0: + } michael@0: + michael@0: + LinearScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: +} michael@0: +#else michael@0: void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width) { michael@0: - for (int x = 0; x < width; x += 2) { michael@0: - uint8 u = u_buf[x >> 1]; michael@0: - uint8 v = v_buf[x >> 1]; michael@0: - uint8 y0 = y_buf[x]; michael@0: - YuvPixel(y0, u, v, rgb_buf); michael@0: - if ((x + 1) < width) { michael@0: - uint8 y1 = y_buf[x + 1]; michael@0: - YuvPixel(y1, u, v, rgb_buf + 4); michael@0: - } michael@0: - rgb_buf += 8; // Advance 2 pixels. michael@0: - } michael@0: -} michael@0: - michael@0: -// 16.16 fixed point is used. A shift by 16 isolates the integer. michael@0: -// A shift by 17 is used to further subsample the chrominence channels. michael@0: -// & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits, michael@0: -// for 1/65536 pixel accurate interpolation. michael@0: + FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, 1); michael@0: +} michael@0: + michael@0: void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) { michael@0: - int x = 0; michael@0: - for (int i = 0; i < width; i += 2) { michael@0: - int y = y_buf[x >> 16]; michael@0: - int u = u_buf[(x >> 17)]; michael@0: - int v = v_buf[(x >> 17)]; michael@0: - YuvPixel(y, u, v, rgb_buf); michael@0: - x += source_dx; michael@0: - if ((i + 1) < width) { michael@0: - y = y_buf[x >> 16]; michael@0: - YuvPixel(y, u, v, rgb_buf+4); michael@0: - x += source_dx; michael@0: - } michael@0: - rgb_buf += 8; michael@0: - } michael@0: -} michael@0: + ScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: +} michael@0: michael@0: void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) { michael@0: - int x = 0; michael@0: - if (source_dx >= 0x20000) { michael@0: - x = 32768; michael@0: - } michael@0: - for (int i = 0; i < width; i += 2) { michael@0: - int y0 = y_buf[x >> 16]; michael@0: - int y1 = y_buf[(x >> 16) + 1]; michael@0: - int u0 = u_buf[(x >> 17)]; michael@0: - int u1 = u_buf[(x >> 17) + 1]; michael@0: - int v0 = v_buf[(x >> 17)]; michael@0: - int v1 = v_buf[(x >> 17) + 1]; michael@0: - int y_frac = (x & 65535); michael@0: - int uv_frac = ((x >> 1) & 65535); michael@0: - int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; michael@0: - int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16; michael@0: - int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16; michael@0: - YuvPixel(y, u, v, rgb_buf); michael@0: - x += source_dx; michael@0: - if ((i + 1) < width) { michael@0: - y0 = y_buf[x >> 16]; michael@0: - y1 = y_buf[(x >> 16) + 1]; michael@0: - y_frac = (x & 65535); michael@0: - y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; michael@0: - YuvPixel(y, u, v, rgb_buf+4); michael@0: - x += source_dx; michael@0: - } michael@0: - rgb_buf += 8; michael@0: - } michael@0: -} michael@0: - michael@0: -#endif // USE_MMX michael@0: -} // extern "C" michael@0: - michael@0: + LinearScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: +} michael@0: +#endif michael@0: + michael@0: +} michael@0: diff --git a/gfx/ycbcr/yuv_row_table.cpp b/gfx/ycbcr/yuv_row_table.cpp michael@0: --- a/gfx/ycbcr/yuv_row_table.cpp michael@0: +++ b/gfx/ycbcr/yuv_row_table.cpp michael@0: @@ -1,13 +1,13 @@ michael@0: // Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: -#include "media/base/yuv_row.h" michael@0: +#include "yuv_row.h" michael@0: michael@0: extern "C" { michael@0: michael@0: #define RGBY(i) { \ michael@0: static_cast(1.164 * 64 * (i - 16) + 0.5), \ michael@0: static_cast(1.164 * 64 * (i - 16) + 0.5), \ michael@0: static_cast(1.164 * 64 * (i - 16) + 0.5), \ michael@0: 0 \ michael@0: diff --git a/gfx/ycbcr/yuv_row_win.cpp b/gfx/ycbcr/yuv_row_win.cpp michael@0: --- a/gfx/ycbcr/yuv_row_win.cpp michael@0: +++ b/gfx/ycbcr/yuv_row_win.cpp michael@0: @@ -1,26 +1,27 @@ michael@0: // Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: -#include "media/base/yuv_row.h" michael@0: +#include "yuv_row.h" michael@0: +#include "mozilla/SSE.h" michael@0: michael@0: #define kCoefficientsRgbU kCoefficientsRgbY + 2048 michael@0: #define kCoefficientsRgbV kCoefficientsRgbY + 4096 michael@0: michael@0: extern "C" { michael@0: michael@0: -#if USE_MMX michael@0: -__declspec(naked) michael@0: -void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width) { michael@0: +#if defined(MOZILLA_MAY_SUPPORT_SSE) && defined(_M_IX86) michael@0: +__declspec(naked) michael@0: +void FastConvertYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width) { michael@0: __asm { michael@0: pushad michael@0: mov edx, [esp + 32 + 4] // Y michael@0: mov edi, [esp + 32 + 8] // U michael@0: mov esi, [esp + 32 + 12] // V michael@0: mov ebp, [esp + 32 + 16] // rgb michael@0: mov ecx, [esp + 32 + 20] // width michael@0: jmp convertend michael@0: @@ -64,22 +65,22 @@ void FastConvertYUVToRGB32Row(const uint michael@0: convertdone : michael@0: michael@0: popad michael@0: ret michael@0: } michael@0: } michael@0: michael@0: __declspec(naked) michael@0: -void ConvertYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int step) { michael@0: +void ConvertYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int step) { michael@0: __asm { michael@0: pushad michael@0: mov edx, [esp + 32 + 4] // Y michael@0: mov edi, [esp + 32 + 8] // U michael@0: mov esi, [esp + 32 + 12] // V michael@0: mov ebp, [esp + 32 + 16] // rgb michael@0: mov ecx, [esp + 32 + 20] // width michael@0: mov ebx, [esp + 32 + 24] // step michael@0: @@ -125,23 +126,23 @@ void ConvertYUVToRGB32Row(const uint8* y michael@0: wdone : michael@0: michael@0: popad michael@0: ret michael@0: } michael@0: } michael@0: michael@0: __declspec(naked) michael@0: -void RotateConvertYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int ystep, michael@0: - int uvstep) { michael@0: +void RotateConvertYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int ystep, michael@0: + int uvstep) { michael@0: __asm { michael@0: pushad michael@0: mov edx, [esp + 32 + 4] // Y michael@0: mov edi, [esp + 32 + 8] // U michael@0: mov esi, [esp + 32 + 12] // V michael@0: mov ebp, [esp + 32 + 16] // rgb michael@0: mov ecx, [esp + 32 + 20] // width michael@0: jmp wend michael@0: @@ -188,21 +189,21 @@ void RotateConvertYUVToRGB32Row(const ui michael@0: wdone : michael@0: michael@0: popad michael@0: ret michael@0: } michael@0: } michael@0: michael@0: __declspec(naked) michael@0: -void DoubleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width) { michael@0: +void DoubleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width) { michael@0: __asm { michael@0: pushad michael@0: mov edx, [esp + 32 + 4] // Y michael@0: mov edi, [esp + 32 + 8] // U michael@0: mov esi, [esp + 32 + 12] // V michael@0: mov ebp, [esp + 32 + 16] // rgb michael@0: mov ecx, [esp + 32 + 20] // width michael@0: jmp wend michael@0: @@ -256,26 +257,26 @@ void DoubleYUVToRGB32Row(const uint8* y_ michael@0: jns wloop1 michael@0: wdone : michael@0: popad michael@0: ret michael@0: } michael@0: } michael@0: michael@0: // This version does general purpose scaling by any amount, up or down. michael@0: -// The only thing it can not do it rotation by 90 or 270. michael@0: -// For performance the chroma is under sampled, reducing cost of a 3x michael@0: +// The only thing it cannot do is rotation by 90 or 270. michael@0: +// For performance the chroma is under-sampled, reducing cost of a 3x michael@0: // 1080p scale from 8.4 ms to 5.4 ms. michael@0: __declspec(naked) michael@0: -void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx) { michael@0: +void ScaleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx) { michael@0: __asm { michael@0: pushad michael@0: mov edx, [esp + 32 + 4] // Y michael@0: mov edi, [esp + 32 + 8] // U michael@0: mov esi, [esp + 32 + 12] // V michael@0: mov ebp, [esp + 32 + 16] // rgb michael@0: mov ecx, [esp + 32 + 20] // width michael@0: xor ebx, ebx // x michael@0: @@ -333,22 +334,22 @@ void ScaleYUVToRGB32Row(const uint8* y_b michael@0: michael@0: scaledone : michael@0: popad michael@0: ret michael@0: } michael@0: } michael@0: michael@0: __declspec(naked) michael@0: -void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: - const uint8* u_buf, michael@0: - const uint8* v_buf, michael@0: - uint8* rgb_buf, michael@0: - int width, michael@0: - int source_dx) { michael@0: +void LinearScaleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: + const uint8* u_buf, michael@0: + const uint8* v_buf, michael@0: + uint8* rgb_buf, michael@0: + int width, michael@0: + int source_dx) { michael@0: __asm { michael@0: pushad michael@0: mov edx, [esp + 32 + 4] // Y michael@0: mov edi, [esp + 32 + 8] // U michael@0: // [esp + 32 + 12] // V michael@0: mov ebp, [esp + 32 + 16] // rgb michael@0: mov ecx, [esp + 32 + 20] // width michael@0: imul ecx, [esp + 32 + 24] // source_dx michael@0: @@ -438,152 +439,60 @@ lscalelastpixel: michael@0: paddsw mm1, mm0 michael@0: psraw mm1, 6 michael@0: packuswb mm1, mm1 michael@0: movd [ebp], mm1 michael@0: popad michael@0: ret michael@0: }; michael@0: } michael@0: -#else // USE_MMX michael@0: - michael@0: -// C reference code that mimic the YUV assembly. michael@0: -#define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x))) michael@0: -#define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \ michael@0: - (((x) + (y)) > 32767 ? 32767 : ((x) + (y)))) michael@0: - michael@0: -static inline void YuvPixel(uint8 y, michael@0: - uint8 u, michael@0: - uint8 v, michael@0: - uint8* rgb_buf) { michael@0: - michael@0: - int b = kCoefficientsRgbY[256+u][0]; michael@0: - int g = kCoefficientsRgbY[256+u][1]; michael@0: - int r = kCoefficientsRgbY[256+u][2]; michael@0: - int a = kCoefficientsRgbY[256+u][3]; michael@0: - michael@0: - b = paddsw(b, kCoefficientsRgbY[512+v][0]); michael@0: - g = paddsw(g, kCoefficientsRgbY[512+v][1]); michael@0: - r = paddsw(r, kCoefficientsRgbY[512+v][2]); michael@0: - a = paddsw(a, kCoefficientsRgbY[512+v][3]); michael@0: - michael@0: - b = paddsw(b, kCoefficientsRgbY[y][0]); michael@0: - g = paddsw(g, kCoefficientsRgbY[y][1]); michael@0: - r = paddsw(r, kCoefficientsRgbY[y][2]); michael@0: - a = paddsw(a, kCoefficientsRgbY[y][3]); michael@0: - michael@0: - b >>= 6; michael@0: - g >>= 6; michael@0: - r >>= 6; michael@0: - a >>= 6; michael@0: - michael@0: - *reinterpret_cast(rgb_buf) = (packuswb(b)) | michael@0: - (packuswb(g) << 8) | michael@0: - (packuswb(r) << 16) | michael@0: - (packuswb(a) << 24); michael@0: -} michael@0: - michael@0: -#if TEST_MMX_YUV michael@0: -static inline void YuvPixel(uint8 y, michael@0: - uint8 u, michael@0: - uint8 v, michael@0: - uint8* rgb_buf) { michael@0: - michael@0: - __asm { michael@0: - movzx eax, u michael@0: - movq mm0, [kCoefficientsRgbY+2048 + 8 * eax] michael@0: - movzx eax, v michael@0: - paddsw mm0, [kCoefficientsRgbY+4096 + 8 * eax] michael@0: - movzx eax, y michael@0: - movq mm1, [kCoefficientsRgbY + 8 * eax] michael@0: - paddsw mm1, mm0 michael@0: - psraw mm1, 6 michael@0: - packuswb mm1, mm1 michael@0: - mov eax, rgb_buf michael@0: - movd [eax], mm1 michael@0: - emms michael@0: - } michael@0: -} michael@0: -#endif michael@0: +#endif // if defined(MOZILLA_MAY_SUPPORT_SSE) && defined(_M_IX86) michael@0: michael@0: void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width) { michael@0: - for (int x = 0; x < width; x += 2) { michael@0: - uint8 u = u_buf[x >> 1]; michael@0: - uint8 v = v_buf[x >> 1]; michael@0: - uint8 y0 = y_buf[x]; michael@0: - YuvPixel(y0, u, v, rgb_buf); michael@0: - if ((x + 1) < width) { michael@0: - uint8 y1 = y_buf[x + 1]; michael@0: - YuvPixel(y1, u, v, rgb_buf + 4); michael@0: - } michael@0: - rgb_buf += 8; // Advance 2 pixels. michael@0: - } michael@0: -} michael@0: - michael@0: -// 16.16 fixed point is used. A shift by 16 isolates the integer. michael@0: -// A shift by 17 is used to further subsample the chrominence channels. michael@0: -// & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits, michael@0: -// for 1/65536 pixel accurate interpolation. michael@0: +#if defined(MOZILLA_MAY_SUPPORT_SSE) && defined(_M_IX86) michael@0: + if (mozilla::supports_sse()) { michael@0: + FastConvertYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width); michael@0: + return; michael@0: + } michael@0: +#endif michael@0: + michael@0: + FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, 1); michael@0: +} michael@0: + michael@0: void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) { michael@0: - int x = 0; michael@0: - for (int i = 0; i < width; i += 2) { michael@0: - int y = y_buf[x >> 16]; michael@0: - int u = u_buf[(x >> 17)]; michael@0: - int v = v_buf[(x >> 17)]; michael@0: - YuvPixel(y, u, v, rgb_buf); michael@0: - x += source_dx; michael@0: - if ((i + 1) < width) { michael@0: - y = y_buf[x >> 16]; michael@0: - YuvPixel(y, u, v, rgb_buf+4); michael@0: - x += source_dx; michael@0: - } michael@0: - rgb_buf += 8; michael@0: - } michael@0: -} michael@0: + michael@0: +#if defined(MOZILLA_MAY_SUPPORT_SSE) && defined(_M_IX86) michael@0: + if (mozilla::supports_sse()) { michael@0: + ScaleYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: + return; michael@0: + } michael@0: +#endif michael@0: + michael@0: + ScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: +} michael@0: michael@0: void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) { michael@0: - int x = 0; michael@0: - if (source_dx >= 0x20000) { michael@0: - x = 32768; michael@0: - } michael@0: - for (int i = 0; i < width; i += 2) { michael@0: - int y0 = y_buf[x >> 16]; michael@0: - int y1 = y_buf[(x >> 16) + 1]; michael@0: - int u0 = u_buf[(x >> 17)]; michael@0: - int u1 = u_buf[(x >> 17) + 1]; michael@0: - int v0 = v_buf[(x >> 17)]; michael@0: - int v1 = v_buf[(x >> 17) + 1]; michael@0: - int y_frac = (x & 65535); michael@0: - int uv_frac = ((x >> 1) & 65535); michael@0: - int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; michael@0: - int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16; michael@0: - int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16; michael@0: - YuvPixel(y, u, v, rgb_buf); michael@0: - x += source_dx; michael@0: - if ((i + 1) < width) { michael@0: - y0 = y_buf[x >> 16]; michael@0: - y1 = y_buf[(x >> 16) + 1]; michael@0: - y_frac = (x & 65535); michael@0: - y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; michael@0: - YuvPixel(y, u, v, rgb_buf+4); michael@0: - x += source_dx; michael@0: - } michael@0: - rgb_buf += 8; michael@0: - } michael@0: -} michael@0: - michael@0: -#endif // USE_MMX michael@0: -} // extern "C" michael@0: - michael@0: +#if defined(MOZILLA_MAY_SUPPORT_SSE) && defined(_M_IX86) michael@0: + if (mozilla::supports_sse()) { michael@0: + LinearScaleYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width, michael@0: + source_dx); michael@0: + return; michael@0: + } michael@0: +#endif michael@0: + michael@0: + LinearScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: +} michael@0: + michael@0: +} // extern "C"