SharedSurfaceDMABUF.cpp (3800B)
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 4; -*- */ 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 "SharedSurfaceDMABUF.h" 7 8 #include "gfxPlatform.h" 9 #include "GLContextEGL.h" 10 #include "MozFramebuffer.h" 11 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc 12 #include "mozilla/gfx/gfxVars.h" 13 #include "mozilla/widget/DMABufDevice.h" 14 15 namespace mozilla::gl { 16 17 /*static*/ 18 UniquePtr<SharedSurface_DMABUF> SharedSurface_DMABUF::Create( 19 const SharedSurfaceDesc& desc) { 20 RefPtr<DMABufSurface> surface; 21 UniquePtr<MozFramebuffer> fb; 22 23 const auto flags = static_cast<DMABufSurfaceFlags>( 24 DMABUF_SCANOUT | DMABUF_TEXTURE | DMABUF_USE_MODIFIERS | DMABUF_ALPHA); 25 surface = DMABufSurfaceRGBA::CreateDMABufSurface(desc.gl, desc.size.width, 26 desc.size.height, flags); 27 if (!surface || !surface->CreateTexture(desc.gl)) { 28 return nullptr; 29 } 30 const auto tex = surface->GetTexture(); 31 fb = MozFramebuffer::CreateForBacking(desc.gl, desc.size, 0, false, 32 LOCAL_GL_TEXTURE_2D, tex); 33 if (!fb) return nullptr; 34 35 return AsUnique(new SharedSurface_DMABUF(desc, std::move(fb), surface)); 36 } 37 38 SharedSurface_DMABUF::SharedSurface_DMABUF(const SharedSurfaceDesc& desc, 39 UniquePtr<MozFramebuffer> fb, 40 const RefPtr<DMABufSurface> surface) 41 : SharedSurface(desc, std::move(fb)), mSurface(surface) {} 42 43 SharedSurface_DMABUF::~SharedSurface_DMABUF() { 44 const auto& gl = mDesc.gl; 45 if (!gl || !gl->MakeCurrent()) { 46 return; 47 } 48 mSurface->ReleaseTextures(); 49 } 50 51 void SharedSurface_DMABUF::ProducerReleaseImpl() { mSurface->FenceSet(); } 52 53 void SharedSurface_DMABUF::WaitForBufferOwnership() { mSurface->FenceWait(); } 54 55 Maybe<layers::SurfaceDescriptor> SharedSurface_DMABUF::ToSurfaceDescriptor() { 56 layers::SurfaceDescriptor desc; 57 if (!mSurface->Serialize(desc)) return {}; 58 return Some(desc); 59 } 60 61 /*static*/ 62 UniquePtr<SurfaceFactory_DMABUF> SurfaceFactory_DMABUF::Create(GLContext& gl) { 63 if (!widget::DMABufDevice::IsDMABufWebGLEnabled()) { 64 return nullptr; 65 } 66 67 auto dmabufFactory = MakeUnique<SurfaceFactory_DMABUF>(gl); 68 if (dmabufFactory->CanCreateSurface(gl)) { 69 return dmabufFactory; 70 } 71 72 LOGDMABUF( 73 ("SurfaceFactory_DMABUF::Create() failed, fallback to SW buffers.\n")); 74 widget::DMABufDevice::DisableDMABufWebGL(); 75 return nullptr; 76 } 77 78 bool SurfaceFactory_DMABUF::CanCreateSurface(GLContext& gl) { 79 UniquePtr<SharedSurface> test = 80 CreateShared(gfx::IntSize(1, 1), gfx::ColorSpace2::SRGB); 81 if (!test) { 82 LOGDMABUF(( 83 "SurfaceFactory_DMABUF::CanCreateSurface() failed to create surface.")); 84 return false; 85 } 86 auto desc = test->ToSurfaceDescriptor(); 87 if (!desc) { 88 LOGDMABUF( 89 ("SurfaceFactory_DMABUF::CanCreateSurface() failed to serialize " 90 "surface.")); 91 return false; 92 } 93 RefPtr<DMABufSurface> importedSurface = 94 DMABufSurface::CreateDMABufSurface(*desc); 95 if (!importedSurface) { 96 LOGDMABUF(( 97 "SurfaceFactory_DMABUF::CanCreateSurface() failed to import surface.")); 98 return false; 99 } 100 if (!importedSurface->CreateTexture(&gl)) { 101 LOGDMABUF( 102 ("SurfaceFactory_DMABUF::CanCreateSurface() failed to create texture " 103 "over surface.")); 104 return false; 105 } 106 return true; 107 } 108 109 SurfaceFactory_DMABUF::SurfaceFactory_DMABUF(GLContext& gl) 110 : SurfaceFactory({&gl, SharedSurfaceType::EGLSurfaceDMABUF, 111 layers::TextureType::DMABUF, true}) {} 112 } // namespace mozilla::gl