commit d187ae71630af53a63e2469b182d9307a9d54857
parent 32d5db1a7754b291df243c0f118071b27be50f5f
Author: Markus Stange <mstange.moz@gmail.com>
Date: Tue, 7 Oct 2025 15:49:45 +0000
Bug 1992515 - Introduce an IOSurfacePort type for IPC serialization of IOSurface using mach_ports. r=bradwerth
Differential Revision: https://phabricator.services.mozilla.com/D267657
Diffstat:
2 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/gfx/layers/ipc/IOSurfacePort.h b/gfx/layers/ipc/IOSurfacePort.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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_IOSurfacePort_h__
+#define mozilla_gfx_IOSurfacePort_h__
+
+#include "chrome/common/ipc_message_utils.h"
+
+#ifdef XP_DARWIN
+# include <IOSurface/IOSurfaceRef.h>
+# include "mozilla/UniquePtrExtensions.h"
+# include "CFTypeRefPtr.h"
+#endif
+
+// This header file defines an IOSurface struct.
+//
+// It is a separate file for the following reasons:
+// - Forward-declaring CFTypeRefPtr<IOSurfaceRef> correctly is tricky.
+// - IOSurfaceRef.h defines global types like "Point" which can interfere with name resolution.
+// - Smaller header files allow limiting the scope of the name pollution.
+
+namespace mozilla::layers {
+
+// The IPC descriptor for an IOSurface.
+// As long as the port is alive, the IOSurface is automatically marked as "in use",
+// including while the port is in IPC transit.
+struct IOSurfacePort {
+#ifdef XP_DARWIN
+ UniqueMachSendRight mPort;
+
+ CFTypeRefPtr<IOSurfaceRef> GetSurface() const {
+ // Note that IOSurfaceLookupFromMachPort does *not* consume the port.
+ if (IOSurfaceRef s = IOSurfaceLookupFromMachPort(mPort.get())) {
+ return CFTypeRefPtr<IOSurfaceRef>::WrapUnderCreateRule(s);
+ }
+ return {};
+ }
+
+ static IOSurfacePort FromSurface(const CFTypeRefPtr<IOSurfaceRef>& aSurface) {
+ return {UniqueMachSendRight(IOSurfaceCreateMachPort(aSurface.get()))};
+ }
+#endif
+};
+
+} // namespace mozilla::layers
+
+namespace IPC {
+
+template <>
+struct ParamTraits<mozilla::layers::IOSurfacePort> {
+ using paramType = mozilla::layers::IOSurfacePort;
+
+ static void Write(MessageWriter* writer, paramType&& param) {
+#ifdef XP_DARWIN
+ WriteParam(writer, std::move(param.mPort));
+#endif
+ }
+ static bool Read(MessageReader* reader, paramType* result) {
+#ifdef XP_DARWIN
+ return ReadParam(reader, &result->mPort);
+#else
+ return true;
+#endif
+ }
+};
+
+} // namespace IPC
+
+#endif /* mozilla_gfx_IOSurfacePort_h__ */
diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build
@@ -169,6 +169,7 @@ EXPORTS.mozilla.layers += [
"ipc/ContentCompositorBridgeParent.h",
"ipc/ImageBridgeChild.h",
"ipc/ImageBridgeParent.h",
+ "ipc/IOSurfacePort.h",
"ipc/ISurfaceAllocator.h",
"ipc/KnowsCompositor.h",
"ipc/LayersMessageUtils.h",