Bug 929513 - Add YCbCrUtils class and change gfxIntSize in BasicCompositor r=nical
authorTor Arvid Lund <torarvid@comoyo.com>
Fri, 13 Dec 2013 18:31:57 +0100
changeset 160441 a4ec1ee06e9d253be6f38014d6b09a4458042a82
parent 160440 526236089c17813a2e02e736cde55f83dd6cb6b8
child 160442 c4cb33486816b84ec21d13617088ef04e30fe879
push id25831
push userryanvm@gmail.com
push dateFri, 13 Dec 2013 21:16:01 +0000
treeherdermozilla-central@9d593727eb94 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs929513
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 929513 - Add YCbCrUtils class and change gfxIntSize in BasicCompositor r=nical The purpose of this patch is to replace usages of gfxIntSize with gfx::IntSize in BasicCompositor. The new class YCbCrUtils has two methods ported from gfxUtils in thebes. BasicCompositor now uses these methods instead of the ones in gfxUtils. Also changed gfxIntSize to gfx::IntSize and gfxImageFormat to gfx::SurfaceFormat.
gfx/layers/basic/BasicCompositor.cpp
gfx/ycbcr/YCbCrUtils.cpp
gfx/ycbcr/YCbCrUtils.h
gfx/ycbcr/moz.build
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -8,16 +8,17 @@
 #include "ipc/AutoOpenSurface.h"
 #include "mozilla/layers/Effects.h"
 #include "mozilla/layers/YCbCrImageDataSerializer.h"
 #include "nsIWidget.h"
 #include "gfx2DGlue.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Helpers.h"
 #include "gfxUtils.h"
+#include "YCbCrUtils.h"
 #include <algorithm>
 #include "ImageContainer.h"
 #define PIXMAN_DONT_DEFINE_STDINT
 #include "pixman.h"                     // for pixman_f_transform, etc
 
 namespace mozilla {
 using namespace mozilla::gfx;
 
@@ -170,34 +171,30 @@ public:
   }
 
   bool ConvertImageToRGB(const SurfaceDescriptor& aImage)
   {
     YCbCrImageDataDeserializer deserializer(aImage.get_YCbCrImage().data().get<uint8_t>());
     PlanarYCbCrData data;
     DeserializerToPlanarYCbCrImageData(deserializer, data);
 
-    gfxImageFormat format = gfxImageFormatRGB24;
-    gfxIntSize size;
-    gfxUtils::GetYCbCrToRGBDestFormatAndSize(data, format, size);
+    gfx::SurfaceFormat format = FORMAT_B8G8R8X8;
+    gfx::IntSize size;
+    gfx::GetYCbCrToRGBDestFormatAndSize(data, format, size);
     if (size.width > PlanarYCbCrImage::MAX_DIMENSION ||
         size.height > PlanarYCbCrImage::MAX_DIMENSION) {
       NS_ERROR("Illegal image dest width or height");
       return false;
     }
 
-    mSize = ToIntSize(size);
-    mFormat = (format == gfxImageFormatRGB24)
-              ? FORMAT_B8G8R8X8
-              : FORMAT_B8G8R8A8;
+    mSize = size;
+    mFormat = format;
 
     RefPtr<DataSourceSurface> surface = Factory::CreateDataSourceSurface(mSize, mFormat);
-    gfxUtils::ConvertYCbCrToRGB(data, format, size,
-                                surface->GetData(),
-                                surface->Stride());
+    gfx::ConvertYCbCrToRGB(data, format, size, surface->GetData(), surface->Stride());
 
     mSurface = surface;
     return true;
   }
 };
 
 TemporaryRef<DeprecatedTextureHost>
 CreateBasicDeprecatedTextureHost(SurfaceDescriptorType aDescriptorType,
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/YCbCrUtils.cpp
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gfx2DGlue.h"
+
+#include "YCbCrUtils.h"
+#include "yuv_convert.h"
+#include "ycbcr_to_rgb565.h"
+
+namespace mozilla {
+namespace gfx {
+
+void
+GetYCbCrToRGBDestFormatAndSize(const layers::PlanarYCbCrData& aData,
+                               SurfaceFormat& aSuggestedFormat,
+                               IntSize& aSuggestedSize)
+{
+  YUVType yuvtype =
+    TypeFromSize(aData.mYSize.width,
+                 aData.mYSize.height,
+                 aData.mCbCrSize.width,
+                 aData.mCbCrSize.height);
+
+  // 'prescale' is true if the scaling is to be done as part of the
+  // YCbCr to RGB conversion rather than on the RGB data when rendered.
+  bool prescale = aSuggestedSize.width > 0 && aSuggestedSize.height > 0 &&
+                  aSuggestedSize != aData.mPicSize;
+
+  if (aSuggestedFormat == FORMAT_R5G6B5) {
+#if defined(HAVE_YCBCR_TO_RGB565)
+    if (prescale &&
+        !IsScaleYCbCrToRGB565Fast(aData.mPicX,
+                                  aData.mPicY,
+                                  aData.mPicSize.width,
+                                  aData.mPicSize.height,
+                                  aSuggestedSize.width,
+                                  aSuggestedSize.height,
+                                  yuvtype,
+                                  FILTER_BILINEAR) &&
+        IsConvertYCbCrToRGB565Fast(aData.mPicX,
+                                   aData.mPicY,
+                                   aData.mPicSize.width,
+                                   aData.mPicSize.height,
+                                   yuvtype)) {
+      prescale = false;
+    }
+#else
+    // yuv2rgb16 function not available
+    aSuggestedFormat = FORMAT_B8G8R8X8;
+#endif
+  }
+  else if (aSuggestedFormat != FORMAT_B8G8R8X8) {
+    // No other formats are currently supported.
+    aSuggestedFormat = FORMAT_B8G8R8X8;
+  }
+  if (aSuggestedFormat == FORMAT_B8G8R8X8) {
+    /* ScaleYCbCrToRGB32 does not support a picture offset, nor 4:4:4 data.
+     See bugs 639415 and 640073. */
+    if (aData.mPicX != 0 || aData.mPicY != 0 || yuvtype == YV24)
+      prescale = false;
+  }
+  if (!prescale) {
+    aSuggestedSize = aData.mPicSize;
+  }
+}
+
+void
+ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
+                  const SurfaceFormat& aDestFormat,
+                  const IntSize& aDestSize,
+                  unsigned char* aDestBuffer,
+                  int32_t aStride)
+{
+  // ConvertYCbCrToRGB et al. assume the chroma planes are rounded up if the
+  // luma plane is odd sized.
+  MOZ_ASSERT((aData.mCbCrSize.width == aData.mYSize.width ||
+              aData.mCbCrSize.width == (aData.mYSize.width + 1) >> 1) &&
+             (aData.mCbCrSize.height == aData.mYSize.height ||
+              aData.mCbCrSize.height == (aData.mYSize.height + 1) >> 1));
+  YUVType yuvtype =
+    TypeFromSize(aData.mYSize.width,
+                 aData.mYSize.height,
+                 aData.mCbCrSize.width,
+                 aData.mCbCrSize.height);
+
+  // Convert from YCbCr to RGB now, scaling the image if needed.
+  if (aDestSize != ToIntSize(aData.mPicSize)) {
+#if defined(HAVE_YCBCR_TO_RGB565)
+    if (aDestFormat == FORMAT_R5G6B5) {
+      ScaleYCbCrToRGB565(aData.mYChannel,
+                         aData.mCbChannel,
+                         aData.mCrChannel,
+                         aDestBuffer,
+                         aData.mPicX,
+                         aData.mPicY,
+                         aData.mPicSize.width,
+                         aData.mPicSize.height,
+                         aDestSize.width,
+                         aDestSize.height,
+                         aData.mYStride,
+                         aData.mCbCrStride,
+                         aStride,
+                         yuvtype,
+                         FILTER_BILINEAR);
+    } else
+#endif
+      ScaleYCbCrToRGB32(aData.mYChannel, //
+                        aData.mCbChannel,
+                        aData.mCrChannel,
+                        aDestBuffer,
+                        aData.mPicSize.width,
+                        aData.mPicSize.height,
+                        aDestSize.width,
+                        aDestSize.height,
+                        aData.mYStride,
+                        aData.mCbCrStride,
+                        aStride,
+                        yuvtype,
+                        ROTATE_0,
+                        FILTER_BILINEAR);
+  } else { // no prescale
+#if defined(HAVE_YCBCR_TO_RGB565)
+    if (aDestFormat == FORMAT_R5G6B5) {
+      ConvertYCbCrToRGB565(aData.mYChannel,
+                           aData.mCbChannel,
+                           aData.mCrChannel,
+                           aDestBuffer,
+                           aData.mPicX,
+                           aData.mPicY,
+                           aData.mPicSize.width,
+                           aData.mPicSize.height,
+                           aData.mYStride,
+                           aData.mCbCrStride,
+                           aStride,
+                           yuvtype);
+    } else // aDestFormat != gfxImageFormatRGB16_565
+#endif
+      ConvertYCbCrToRGB32(aData.mYChannel, //
+                          aData.mCbChannel,
+                          aData.mCrChannel,
+                          aDestBuffer,
+                          aData.mPicX,
+                          aData.mPicY,
+                          aData.mPicSize.width,
+                          aData.mPicSize.height,
+                          aData.mYStride,
+                          aData.mCbCrStride,
+                          aStride,
+                          yuvtype);
+  }
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/YCbCrUtils.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_GFX_UTILS_H_
+#define MOZILLA_GFX_UTILS_H_
+
+#include "mozilla/gfx/Types.h"
+#include "ImageContainer.h"
+
+namespace mozilla {
+namespace gfx {
+
+void
+GetYCbCrToRGBDestFormatAndSize(const layers::PlanarYCbCrData& aData,
+                               SurfaceFormat& aSuggestedFormat,
+                               IntSize& aSuggestedSize);
+
+void
+ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
+                  const SurfaceFormat& aDestFormat,
+                  const IntSize& aDestSize,
+                  unsigned char* aDestBuffer,
+                  int32_t aStride);
+
+}
+}
+
+#endif /* MOZILLA_GFX_UTILS_H_ */
--- a/gfx/ycbcr/moz.build
+++ b/gfx/ycbcr/moz.build
@@ -2,22 +2,24 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS += [
     'chromium_types.h',
     'ycbcr_to_rgb565.h',
+    'YCbCrUtils.h',
     'yuv_convert.h',
     'yuv_row.h',
 ]
 
 UNIFIED_SOURCES += [
     'ycbcr_to_rgb565.cpp',
+    'YCbCrUtils.cpp',
     'yuv_convert.cpp',
     'yuv_row_c.cpp',
     'yuv_row_table.cpp',
 ]
 
 if CONFIG['INTEL_ARCHITECTURE']:
     SOURCES += [
         'yuv_convert_sse2.cpp',