Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  DMABufDevice.cpp   Sprache: C

 

/* 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/. */


#include "DMABufDevice.h"
#include "DMABufFormats.h"
#include "DMABufSurface.h"
#ifdef MOZ_WAYLAND
#  include "nsWaylandDisplay.h"
#endif
#include "base/message_loop.h"    // for MessageLoop
#include "mozilla/gfx/Logging.h"  // for gfxCriticalNote
#include "mozilla/StaticPrefs_widget.h"
#include "mozilla/StaticPrefs_media.h"
#include "mozilla/gfx/gfxVars.h"
#include "WidgetUtilsGtk.h"
#include "gfxConfig.h"
#include "nsIGfxInfo.h"
#include "GfxInfo.h"
#include "mozilla/Components.h"
#include "mozilla/ClearOnShutdown.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <mutex>
#include <unistd.h>

using namespace mozilla::gfx;

namespace mozilla {
namespace widget {

StaticMutex DMABufDeviceLock::sMutex;
DMABufDevice* DMABufDeviceLock::sDMABufDevice = nullptr;

bool sUseWebGLDmabufBackend = true;

#define GBMLIB_NAME "libgbm.so.1"
#define DRMLIB_NAME "libdrm.so.2"

bool GbmLib::sLoaded = false;
void* GbmLib::sGbmLibHandle = nullptr;
void* GbmLib::sXf86DrmLibHandle = nullptr;
CreateDeviceFunc GbmLib::sCreateDevice;
DestroyDeviceFunc GbmLib::sDestroyDevice;
CreateFunc GbmLib::sCreate;
CreateWithModifiersFunc GbmLib::sCreateWithModifiers;
CreateWithModifiers2Func GbmLib::sCreateWithModifiers2;
GetModifierFunc GbmLib::sGetModifier;
GetStrideFunc GbmLib::sGetStride;
GetFdFunc GbmLib::sGetFd;
DestroyFunc GbmLib::sDestroy;
MapFunc GbmLib::sMap;
UnmapFunc GbmLib::sUnmap;
GetPlaneCountFunc GbmLib::sGetPlaneCount;
GetHandleForPlaneFunc GbmLib::sGetHandleForPlane;
GetStrideForPlaneFunc GbmLib::sGetStrideForPlane;
GetOffsetFunc GbmLib::sGetOffset;
DeviceIsFormatSupportedFunc GbmLib::sDeviceIsFormatSupported;
DrmPrimeHandleToFDFunc GbmLib::sDrmPrimeHandleToFD;
CreateSurfaceFunc GbmLib::sCreateSurface;
DestroySurfaceFunc GbmLib::sDestroySurface;

bool GbmLib::IsLoaded() {
  return sCreateDevice != nullptr && sDestroyDevice != nullptr &&
         sCreate != nullptr && sCreateWithModifiers != nullptr &&
         sGetModifier != nullptr && sGetStride != nullptr &&
         sGetFd != nullptr && sDestroy != nullptr && sMap != nullptr &&
         sUnmap != nullptr && sGetPlaneCount != nullptr &&
         sGetHandleForPlane != nullptr && sGetStrideForPlane != nullptr &&
         sGetOffset != nullptr && sDeviceIsFormatSupported != nullptr &&
         sDrmPrimeHandleToFD != nullptr && sCreateSurface != nullptr &&
         sDestroySurface != nullptr;
}

bool GbmLib::Load() {
  static bool sTriedToLoad = false;
  if (sTriedToLoad) {
    return sLoaded;
  }

  sTriedToLoad = true;

  MOZ_ASSERT(!sGbmLibHandle);
  MOZ_ASSERT(!sLoaded);

  LOGDMABUF(("Loading DMABuf system library %s ...\n", GBMLIB_NAME));

  sGbmLibHandle = dlopen(GBMLIB_NAME, RTLD_LAZY | RTLD_LOCAL);
  if (!sGbmLibHandle) {
    LOGDMABUF(("Failed to load %s, dmabuf isn't available.\n", GBMLIB_NAME));
    return false;
  }

  sCreateDevice = (CreateDeviceFunc)dlsym(sGbmLibHandle, "gbm_create_device");
  sDestroyDevice =
      (DestroyDeviceFunc)dlsym(sGbmLibHandle, "gbm_device_destroy");
  sCreate = (CreateFunc)dlsym(sGbmLibHandle, "gbm_bo_create");
  sCreateWithModifiers = (CreateWithModifiersFunc)dlsym(
      sGbmLibHandle, "gbm_bo_create_with_modifiers");
  sCreateWithModifiers2 = (CreateWithModifiers2Func)dlsym(
      sGbmLibHandle, "gbm_bo_create_with_modifiers2");
  sGetModifier = (GetModifierFunc)dlsym(sGbmLibHandle, "gbm_bo_get_modifier");
  sGetStride = (GetStrideFunc)dlsym(sGbmLibHandle, "gbm_bo_get_stride");
  sGetFd = (GetFdFunc)dlsym(sGbmLibHandle, "gbm_bo_get_fd");
  sDestroy = (DestroyFunc)dlsym(sGbmLibHandle, "gbm_bo_destroy");
  sMap = (MapFunc)dlsym(sGbmLibHandle, "gbm_bo_map");
  sUnmap = (UnmapFunc)dlsym(sGbmLibHandle, "gbm_bo_unmap");
  sGetPlaneCount =
      (GetPlaneCountFunc)dlsym(sGbmLibHandle, "gbm_bo_get_plane_count");
  sGetHandleForPlane = (GetHandleForPlaneFunc)dlsym(
      sGbmLibHandle, "gbm_bo_get_handle_for_plane");
  sGetStrideForPlane = (GetStrideForPlaneFunc)dlsym(
      sGbmLibHandle, "gbm_bo_get_stride_for_plane");
  sGetOffset = (GetOffsetFunc)dlsym(sGbmLibHandle, "gbm_bo_get_offset");
  sDeviceIsFormatSupported = (DeviceIsFormatSupportedFunc)dlsym(
      sGbmLibHandle, "gbm_device_is_format_supported");
  sCreateSurface =
      (CreateSurfaceFunc)dlsym(sGbmLibHandle, "gbm_surface_create");
  sDestroySurface =
      (DestroySurfaceFunc)dlsym(sGbmLibHandle, "gbm_surface_destroy");

  sXf86DrmLibHandle = dlopen(DRMLIB_NAME, RTLD_LAZY | RTLD_LOCAL);
  if (!sXf86DrmLibHandle) {
    LOGDMABUF(("Failed to load %s, dmabuf isn't available.\n", DRMLIB_NAME));
    return false;
  }
  sDrmPrimeHandleToFD =
      (DrmPrimeHandleToFDFunc)dlsym(sXf86DrmLibHandle, "drmPrimeHandleToFD");
  sLoaded = IsLoaded();
  if (!sLoaded) {
    LOGDMABUF(("Failed to load all symbols from %s\n", GBMLIB_NAME));
  }
  return sLoaded;
}

DMABufDevice* DMABufDeviceLock::EnsureDMABufDevice() {
  sMutex.AssertCurrentThreadOwns();
  static std::once_flag onceFlag;
  std::call_once(onceFlag, [&] {
    sDMABufDevice = new DMABufDevice();
    if (sDMABufDevice->Init()) {
      LOGDMABUF(("EnsureDMABufDevice(): created DMABufDevice"));
    } else {
      nsCString failureId;
      (void)sDMABufDevice->IsEnabled(failureId);
      LOGDMABUF(("EnsureDMABufDevice(): failed to init DMABufDevice: %s",
                 failureId.get()));
    }
  });

  MOZ_DIAGNOSTIC_ASSERT(sDMABufDevice, "Missing DMABufDevice!");
  return sDMABufDevice;
}

void DMABufDeviceLock::Shutdown() {
  StaticMutexAutoLock lock(sMutex);
  delete sDMABufDevice;
  sDMABufDevice = nullptr;
}

DMABufDeviceLock::DMABufDeviceLock() {
  LOGDMABUF(("DMABufDeviceLock::DMABufDeviceLock() [%p]", this));
  sMutex.Lock();

  mDMABufDevice = EnsureDMABufDevice();
  mGBMDevice = mDMABufDevice->GetDevice(this);
}

DMABufDeviceLock::~DMABufDeviceLock() {
  LOGDMABUF(("DMABufDeviceLock::~DMABufDeviceLock() [%p]", this));
  sMutex.AssertCurrentThreadOwns();
  MOZ_DIAGNOSTIC_ASSERT(mDMABufDevice);

  mGBMDevice = nullptr;
  mDMABufDevice = nullptr;

  sMutex.Unlock();
}

gbm_device* DMABufDevice::GetDevice(DMABufDeviceLock* aDMABufDeviceLock) {
  LOGDMABUF(("DMABufDevice::GetDevice() [%p]", this));
  if (mDRMFd == -1) {
    LOGDMABUF(("  mDRMFd is missing!"));
    return nullptr;
  }
  if (!mGbmDevice) {
    mGbmDevice = GbmLib::CreateDevice(mDRMFd);
    if (!mGbmDevice) {
      LOGDMABUF(("  GbmLib::CreateDevice() failed for fd %d", mDRMFd));
    }
  }
  return mGbmDevice;
}

int DMABufDevice::GetDmabufFD(uint32_t aGEMHandle) {
  int fd;
  return GbmLib::DrmPrimeHandleToFD(mDRMFd, aGEMHandle, 0, &fd) < 0 ? -1 : fd;
}

int DMABufDevice::OpenDRMFd() {
  LOGDMABUF(("DMABufDevice::OpenDRMFd() DRM device %s", mDrmRenderNode.get()));
  return open(mDrmRenderNode.get(), O_RDWR | O_CLOEXEC);
}

bool DMABufDevice::IsEnabled(nsACString& aFailureId) {
  if (mDRMFd == -1) {
    aFailureId = mFailureId;
  }
  return mDRMFd != -1;
}

DMABufDevice::~DMABufDevice() {
  LOGDMABUF(("DMABufDevice::~DMABufDevice() [%p] mGbmDevice [%p] mDRMFd [%d]",
             this, mGbmDevice, mDRMFd));
  if (mGbmDevice) {
    GbmLib::DestroyDevice(mGbmDevice);
    mGbmDevice = nullptr;
  }
  if (mDRMFd != -1) {
    close(mDRMFd);
    mDRMFd = -1;
  }
}

bool DMABufDevice::Init() {
  LOGDMABUF(("DMABufDevice::Init()"));

  if (!GbmLib::IsAvailable()) {
    LOGDMABUF(("GbmLib is not available!"));
    mFailureId = "FEATURE_FAILURE_NO_LIBGBM";
    return false;
  }

  // See Bug 1865747 for details.
  if (XRE_IsParentProcess()) {
    if (auto* gbmBackend = getenv("GBM_BACKEND")) {
      const nsCOMPtr<nsIGfxInfo> gfxInfo = components::GfxInfo::Service();
      nsAutoString vendorID;
      gfxInfo->GetAdapterVendorID(vendorID);
      if (vendorID != GfxDriverInfo::GetDeviceVendor(DeviceVendor::NVIDIA)) {
        if (strstr(gbmBackend, "nvidia")) {
          unsetenv("GBM_BACKEND");
        }
      }
    }
  }

  mDrmRenderNode = nsAutoCString(getenv("MOZ_DRM_DEVICE"));
  if (mDrmRenderNode.IsEmpty()) {
    mDrmRenderNode.Assign(gfx::gfxVars::DrmRenderDevice());
  }
  if (mDrmRenderNode.IsEmpty()) {
    LOGDMABUF(("We're missing DRM render device!\n"));
    mFailureId = "FEATURE_FAILURE_NO_DRM_DEVICE";
    return false;
  }

  mDRMFd = OpenDRMFd();
  if (mDRMFd < 0) {
    LOGDMABUF(("Failed to open drm render node %s error %s\n",
               mDrmRenderNode.get(), strerror(errno)));
    mFailureId = "FEATURE_FAILURE_NO_DRM_DEVICE";
    return false;
  }

  if (NS_IsMainThread()) {
    DMABufSurface::InitMemoryReporting();
  } else {
    NS_DispatchToMainThread(
        NS_NewRunnableFunction("DMABufSurface::InitMemoryReporting()",
                               [] { DMABufSurface::InitMemoryReporting(); }));
  }

  LOGDMABUF(("DMABuf is enabled"));
  return true;
}

bool DMABufDevice::IsDMABufWebGLEnabled() {
  LOGDMABUF(
      ("DMABufDevice::IsDMABufWebGLEnabled: UseDMABuf %d "
       "sUseWebGLDmabufBackend %d "
       "UseDMABufWebGL %d\n",
       gfx::gfxVars::UseDMABuf(), sUseWebGLDmabufBackend,
       gfx::gfxVars::UseDMABufWebGL()));
  return gfx::gfxVars::UseDMABuf() && sUseWebGLDmabufBackend &&
         gfx::gfxVars::UseDMABufWebGL();
}

void DMABufDevice::DisableDMABufWebGL() { sUseWebGLDmabufBackend = false; }

}  // namespace widget
}  // namespace mozilla

Messung V0.5 in Prozent
C=98 H=100 G=98

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-09-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1126438
#Domains=1867298