tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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