1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "ExternalTextureMacIOSurface.h"
8 #include "mozilla/gfx/Logging.h"
9 #include "mozilla/gfx/MacIOSurface.h"
10 #include "mozilla/layers/GpuFenceMTLSharedEvent.h"
11 #include "mozilla/layers/ImageDataSerializer.h"
12 #include "mozilla/webgpu/WebGPUParent.h"
14 namespace mozilla::webgpu
{
17 UniquePtr
<ExternalTextureMacIOSurface
> ExternalTextureMacIOSurface::Create(
18 WebGPUParent
* aParent
, const ffi::WGPUDeviceId aDeviceId
,
19 const uint32_t aWidth
, const uint32_t aHeight
,
20 const struct ffi::WGPUTextureFormat aFormat
,
21 const ffi::WGPUTextureUsages aUsage
) {
22 if (aFormat
.tag
!= ffi::WGPUTextureFormat_Bgra8Unorm
) {
23 gfxCriticalNoteOnce
<< "Non supported format: " << aFormat
.tag
;
27 if (aWidth
> MacIOSurface::GetMaxWidth() ||
28 aHeight
> MacIOSurface::GetMaxHeight()) {
29 gfxCriticalNoteOnce
<< "Requested MacIOSurface is too large: (" << aWidth
30 << ", " << aHeight
<< ")";
34 RefPtr
<MacIOSurface
> surface
=
35 MacIOSurface::CreateIOSurface(aWidth
, aHeight
, true);
37 gfxCriticalNoteOnce
<< "Failed to create MacIOSurface: (" << aWidth
<< ", "
42 return MakeUnique
<ExternalTextureMacIOSurface
>(
43 aParent
, aDeviceId
, aWidth
, aHeight
, aFormat
, aUsage
, std::move(surface
));
46 ExternalTextureMacIOSurface::ExternalTextureMacIOSurface(
47 WebGPUParent
* aParent
, const ffi::WGPUDeviceId aDeviceId
,
48 const uint32_t aWidth
, const uint32_t aHeight
,
49 const struct ffi::WGPUTextureFormat aFormat
,
50 const ffi::WGPUTextureUsages aUsage
, RefPtr
<MacIOSurface
>&& aSurface
)
51 : ExternalTexture(aWidth
, aHeight
, aFormat
, aUsage
),
54 mSurface(std::move(aSurface
)) {}
56 ExternalTextureMacIOSurface::~ExternalTextureMacIOSurface() {}
58 void* ExternalTextureMacIOSurface::GetExternalTextureHandle() {
62 uint32_t ExternalTextureMacIOSurface::GetIOSurfaceId() {
63 return mSurface
->GetIOSurfaceID();
66 Maybe
<layers::SurfaceDescriptor
>
67 ExternalTextureMacIOSurface::ToSurfaceDescriptor(
68 Maybe
<gfx::FenceInfo
>& aFenceInfo
) {
69 MOZ_ASSERT(mSubmissionIndex
> 0);
71 RefPtr
<layers::GpuFence
> gpuFence
;
72 UniquePtr
<ffi::WGPUMetalSharedEventHandle
> eventHandle(
73 wgpu_server_get_device_fence_metal_shared_event(mParent
->GetContext(),
76 gpuFence
= layers::GpuFenceMTLSharedEvent::Create(std::move(eventHandle
),
79 gfxCriticalNoteOnce
<< "Failed to get MetalSharedEventHandle";
82 return Some(layers::SurfaceDescriptorMacIOSurface(
83 mSurface
->GetIOSurfaceID(), !mSurface
->HasAlpha(),
84 mSurface
->GetYUVColorSpace(), std::move(gpuFence
)));
87 void ExternalTextureMacIOSurface::GetSnapshot(const ipc::Shmem
& aDestShmem
,
88 const gfx::IntSize
& aSize
) {
89 if (!mSurface
->Lock()) {
90 gfxCriticalNoteOnce
<< "Failed to lock MacIOSurface";
94 const size_t bytesPerRow
= mSurface
->GetBytesPerRow();
95 const uint32_t stride
= layers::ImageDataSerializer::ComputeRGBStride(
96 gfx::SurfaceFormat::B8G8R8A8
, aSize
.width
);
97 uint8_t* src
= (uint8_t*)mSurface
->GetBaseAddress();
98 uint8_t* dst
= aDestShmem
.get
<uint8_t>();
100 MOZ_ASSERT(stride
* aSize
.height
<= aDestShmem
.Size
<uint8_t>());
102 for (int y
= 0; y
< aSize
.height
; y
++) {
103 memcpy(dst
, src
, stride
);
111 } // namespace mozilla::webgpu