Bug 1241665 - Move IOSurface YCbCr conversion code to a new file MacIOSurfaceHelpers.cpp. r=mattwoodrow, a=sylvestre
authorMarkus Stange <mstange@themasta.com>
Thu, 21 Jan 2016 23:38:53 +0100
changeset 298309 cb7ae108000d3f7626c59251a3338edc2b2c48b2
parent 298308 97e6ca995311c2ea072e492021049a68fa5d19b1
child 298310 bbf2df5dba13f860461f11585f154a8b81f93da5
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-esr52@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow, sylvestre
bugs1241665
milestone45.0a2
Bug 1241665 - Move IOSurface YCbCr conversion code to a new file MacIOSurfaceHelpers.cpp. r=mattwoodrow, a=sylvestre Ideally this would live in gfx/2d/MacIOSurface.cpp, but we don't have access to the YCbCr conversion utilities in Moz2D.
gfx/layers/MacIOSurfaceHelpers.cpp
gfx/layers/MacIOSurfaceHelpers.h
gfx/layers/MacIOSurfaceImage.cpp
gfx/layers/moz.build
new file mode 100644
--- /dev/null
+++ b/gfx/layers/MacIOSurfaceHelpers.cpp
@@ -0,0 +1,95 @@
+/* -*- 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/. */
+
+#include "MacIOSurfaceHelpers.h"
+#include "mozilla/gfx/MacIOSurface.h"
+#include "YCbCrUtils.h"
+
+namespace mozilla {
+
+using namespace gfx;
+
+namespace layers {
+
+already_AddRefed<SourceSurface>
+CreateSourceSurfaceFromMacIOSurface(MacIOSurface* aSurface)
+{
+  RefPtr<DataSourceSurface> dataSurface;
+  aSurface->Lock();
+  size_t bytesPerRow = aSurface->GetBytesPerRow();
+  size_t ioWidth = aSurface->GetDevicePixelWidth();
+  size_t ioHeight = aSurface->GetDevicePixelHeight();
+
+  SurfaceFormat format = aSurface->GetFormat() == SurfaceFormat::NV12 ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8;
+
+  dataSurface = Factory::CreateDataSourceSurface(IntSize(ioWidth, ioHeight), format);
+  if (NS_WARN_IF(!dataSurface)) {
+    return nullptr;
+  }
+
+  DataSourceSurface::MappedSurface mappedSurface;
+  if (!dataSurface->Map(DataSourceSurface::WRITE, &mappedSurface))
+    return nullptr;
+
+  if (aSurface->GetFormat() == SurfaceFormat::NV12) {
+    if (aSurface->GetDevicePixelWidth() > PlanarYCbCrImage::MAX_DIMENSION ||
+        aSurface->GetDevicePixelHeight() > PlanarYCbCrImage::MAX_DIMENSION) {
+      return nullptr;
+    }
+
+    /* Extract and separate the CbCr planes */
+    size_t cbCrStride = aSurface->GetBytesPerRow(1);
+    size_t cbCrWidth = aSurface->GetDevicePixelWidth(1);
+    size_t cbCrHeight = aSurface->GetDevicePixelHeight(1);
+
+    auto cbPlane = MakeUnique<uint8_t[]>(cbCrWidth * cbCrHeight);
+    auto crPlane = MakeUnique<uint8_t[]>(cbCrWidth * cbCrHeight);
+
+    uint8_t* src = (uint8_t*)aSurface->GetBaseAddressOfPlane(1);
+    uint8_t* cbDest = cbPlane.get();
+    uint8_t* crDest = crPlane.get();
+
+    for (size_t i = 0; i < cbCrHeight; i++) {
+      uint8_t* rowSrc = src + cbCrStride * i;
+      for (size_t j = 0; j < cbCrWidth; j++) {
+        *cbDest = *rowSrc;
+        cbDest++;
+        rowSrc++;
+        *crDest = *rowSrc;
+        crDest++;
+        rowSrc++;
+      }
+    }
+
+    /* Convert to RGB */
+    PlanarYCbCrData data;
+    data.mYChannel = (uint8_t*)aSurface->GetBaseAddressOfPlane(0);
+    data.mYStride = aSurface->GetBytesPerRow(0);
+    data.mYSize = IntSize(aSurface->GetDevicePixelWidth(0), aSurface->GetDevicePixelHeight(0));
+    data.mCbChannel = cbPlane.get();
+    data.mCrChannel = crPlane.get();
+    data.mCbCrStride = cbCrWidth;
+    data.mCbCrSize = IntSize(cbCrWidth, cbCrHeight);
+    data.mPicSize = data.mYSize;
+
+    ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
+  } else {
+    unsigned char* ioData = (unsigned char*)aSurface->GetBaseAddress();
+
+    for (size_t i = 0; i < ioHeight; ++i) {
+      memcpy(mappedSurface.mData + i * mappedSurface.mStride,
+             ioData + i * bytesPerRow,
+             ioWidth * 4);
+    }
+  }
+
+  dataSurface->Unmap();
+  aSurface->Unlock();
+
+  return dataSurface.forget();
+}
+
+} // namespace gfx
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/MacIOSurfaceHelpers.h
@@ -0,0 +1,28 @@
+/* -*- 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 GFX_MACIOSURFACEHELPERS_H
+#define GFX_MACIOSURFACEHELPERS_H
+
+class MacIOSurface;
+template<class T> struct already_AddRefed;
+
+namespace mozilla {
+
+namespace gfx {
+class SourceSurface;
+}
+
+namespace layers {
+
+// Unlike MacIOSurface::GetAsSurface, this also handles IOSurface formats
+// with multiple planes and does YCbCr to RGB conversion, if necessary.
+already_AddRefed<gfx::SourceSurface>
+CreateSourceSurfaceFromMacIOSurface(MacIOSurface* aSurface);
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // GFX_MACIOSURFACEHELPERS_H
--- a/gfx/layers/MacIOSurfaceImage.cpp
+++ b/gfx/layers/MacIOSurfaceImage.cpp
@@ -1,19 +1,19 @@
 /* -*- 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/. */
 
+#include "MacIOSurfaceHelpers.h"
 #include "MacIOSurfaceImage.h"
 #include "mozilla/layers/CompositableClient.h"
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/MacIOSurfaceTextureClientOGL.h"
 #include "mozilla/UniquePtr.h"
-#include "YCbCrUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 
 TextureClient*
 MacIOSurfaceImage::GetTextureClient(CompositableClient* aClient)
 {
@@ -25,82 +25,10 @@ MacIOSurfaceImage::GetTextureClient(Comp
     );
   }
   return mTextureClient;
 }
 
 already_AddRefed<SourceSurface>
 MacIOSurfaceImage::GetAsSourceSurface()
 {
-  RefPtr<DataSourceSurface> dataSurface;
-  mSurface->Lock();
-  size_t bytesPerRow = mSurface->GetBytesPerRow();
-  size_t ioWidth = mSurface->GetDevicePixelWidth();
-  size_t ioHeight = mSurface->GetDevicePixelHeight();
-
-  SurfaceFormat format = mSurface->GetFormat() == SurfaceFormat::NV12 ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8;
-
-  dataSurface = Factory::CreateDataSourceSurface(IntSize(ioWidth, ioHeight), format);
-  if (NS_WARN_IF(!dataSurface)) {
-    return nullptr;
-  }
-
-  DataSourceSurface::MappedSurface mappedSurface;
-  if (!dataSurface->Map(DataSourceSurface::WRITE, &mappedSurface))
-    return nullptr;
-
-  if (mSurface->GetFormat() == SurfaceFormat::NV12) {
-    if (mSurface->GetDevicePixelWidth() > PlanarYCbCrImage::MAX_DIMENSION ||
-        mSurface->GetDevicePixelHeight() > PlanarYCbCrImage::MAX_DIMENSION) {
-      return nullptr;
-    }
-
-    /* Extract and separate the CbCr planes */
-    size_t cbCrStride = mSurface->GetBytesPerRow(1);
-    size_t cbCrWidth = mSurface->GetDevicePixelWidth(1);
-    size_t cbCrHeight = mSurface->GetDevicePixelHeight(1);
-
-    auto cbPlane = MakeUnique<uint8_t[]>(cbCrWidth * cbCrHeight);
-    auto crPlane = MakeUnique<uint8_t[]>(cbCrWidth * cbCrHeight);
-
-    uint8_t* src = (uint8_t*)mSurface->GetBaseAddressOfPlane(1);
-    uint8_t* cbDest = cbPlane.get();
-    uint8_t* crDest = crPlane.get();
-
-    for (size_t i = 0; i < cbCrHeight; i++) {
-      uint8_t* rowSrc = src + cbCrStride * i;
-      for (size_t j = 0; j < cbCrWidth; j++) {
-        *cbDest = *rowSrc;
-        cbDest++;
-        rowSrc++;
-        *crDest = *rowSrc;
-        crDest++;
-        rowSrc++;
-      }
-    }
-
-    /* Convert to RGB */
-    PlanarYCbCrData data;
-    data.mYChannel = (uint8_t*)mSurface->GetBaseAddressOfPlane(0);
-    data.mYStride = mSurface->GetBytesPerRow(0);
-    data.mYSize = IntSize(mSurface->GetDevicePixelWidth(0), mSurface->GetDevicePixelHeight(0));
-    data.mCbChannel = cbPlane.get();
-    data.mCrChannel = crPlane.get();
-    data.mCbCrStride = cbCrWidth;
-    data.mCbCrSize = IntSize(cbCrWidth, cbCrHeight);
-    data.mPicSize = data.mYSize;
-
-    ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
-  } else {
-    unsigned char* ioData = (unsigned char*)mSurface->GetBaseAddress();
-
-    for (size_t i = 0; i < ioHeight; ++i) {
-      memcpy(mappedSurface.mData + i * mappedSurface.mStride,
-             ioData + i * bytesPerRow,
-             ioWidth * 4);
-    }
-  }
-
-  dataSurface->Unmap();
-  mSurface->Unlock();
-
-  return dataSurface.forget();
+  return CreateSourceSurfaceFromMacIOSurface(mSurface);
 }
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -199,23 +199,25 @@ if CONFIG['MOZ_X11']:
         'opengl/X11TextureSourceOGL.cpp',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     EXPORTS.mozilla.layers += [
         'opengl/GLManager.h',
     ]
     EXPORTS += [
+        'MacIOSurfaceHelpers.h',
         'MacIOSurfaceImage.h',
     ]
     UNIFIED_SOURCES += [
         'opengl/GLManager.cpp',
     ]
     SOURCES += [
         'ipc/ShadowLayerUtilsMac.cpp',
+        'MacIOSurfaceHelpers.cpp',
         'MacIOSurfaceImage.cpp',
     ]
 
 # NB: Gralloc is available on other platforms that use the android GL
 # libraries, but only Gonk is able to use it reliably because Gecko
 # has full system permissions there.
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     EXPORTS.mozilla.layers += [