SharedTextureMacIOSurface.cpp (3798B)
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/. */ 5 6 #include "SharedTextureMacIOSurface.h" 7 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" 13 14 namespace mozilla::webgpu { 15 16 // static 17 UniquePtr<SharedTextureMacIOSurface> SharedTextureMacIOSurface::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; 24 return nullptr; 25 } 26 27 if (aWidth > MacIOSurface::GetMaxWidth() || 28 aHeight > MacIOSurface::GetMaxHeight()) { 29 gfxCriticalNoteOnce << "Requested MacIOSurface is too large: (" << aWidth 30 << ", " << aHeight << ")"; 31 return nullptr; 32 } 33 34 RefPtr<MacIOSurface> surface = 35 MacIOSurface::CreateIOSurface(aWidth, aHeight, true); 36 if (!surface) { 37 gfxCriticalNoteOnce << "Failed to create MacIOSurface: (" << aWidth << ", " 38 << aHeight << ")"; 39 return nullptr; 40 } 41 42 return MakeUnique<SharedTextureMacIOSurface>( 43 aParent, aDeviceId, aWidth, aHeight, aFormat, aUsage, std::move(surface)); 44 } 45 46 SharedTextureMacIOSurface::SharedTextureMacIOSurface( 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 : SharedTexture(aWidth, aHeight, aFormat, aUsage), 52 mParent(aParent), 53 mDeviceId(aDeviceId), 54 mSurface(std::move(aSurface)) {} 55 56 SharedTextureMacIOSurface::~SharedTextureMacIOSurface() {} 57 58 uint32_t SharedTextureMacIOSurface::GetIOSurfaceId() { 59 return mSurface->GetIOSurfaceID(); 60 } 61 62 Maybe<layers::SurfaceDescriptor> 63 SharedTextureMacIOSurface::ToSurfaceDescriptor() { 64 MOZ_ASSERT(mSubmissionIndex > 0); 65 66 RefPtr<layers::GpuFence> gpuFence; 67 UniquePtr<ffi::WGPUMetalSharedEventHandle> eventHandle( 68 wgpu_server_get_device_fence_metal_shared_event(mParent->GetContext(), 69 mDeviceId)); 70 if (eventHandle) { 71 gpuFence = layers::GpuFenceMTLSharedEvent::Create(std::move(eventHandle), 72 mSubmissionIndex); 73 } else { 74 gfxCriticalNoteOnce << "Failed to get MetalSharedEventHandle"; 75 } 76 77 return Some(layers::SurfaceDescriptorMacIOSurface( 78 mSurface->GetIOSurfaceID(), !mSurface->HasAlpha(), 79 mSurface->GetYUVColorSpace(), std::move(gpuFence))); 80 } 81 82 void SharedTextureMacIOSurface::GetSnapshot(const ipc::Shmem& aDestShmem, 83 const gfx::IntSize& aSize) { 84 if (!mSurface->Lock()) { 85 gfxCriticalNoteOnce << "Failed to lock MacIOSurface"; 86 return; 87 } 88 89 const size_t bytesPerRow = mSurface->GetBytesPerRow(); 90 const uint32_t stride = layers::ImageDataSerializer::ComputeRGBStride( 91 gfx::SurfaceFormat::B8G8R8A8, aSize.width); 92 uint8_t* src = (uint8_t*)mSurface->GetBaseAddress(); 93 uint8_t* dst = aDestShmem.get<uint8_t>(); 94 95 MOZ_ASSERT(stride * aSize.height <= aDestShmem.Size<uint8_t>()); 96 97 for (int y = 0; y < aSize.height; y++) { 98 memcpy(dst, src, stride); 99 src += bytesPerRow; 100 dst += stride; 101 } 102 103 mSurface->Unlock(); 104 } 105 106 } // namespace mozilla::webgpu