Backed out 3 changesets (bug 1629788) for WaylandDMABufSurface.cpp related bustages CLOSED TREE

Backed out changeset 31fba4d1fe1d (bug 1629788)
Backed out changeset 9d1e4da287a6 (bug 1629788)
Backed out changeset 23791ccf64dd (bug 1629788)
This commit is contained in:
Bogdan Tara 2020-06-13 13:56:04 +03:00
Родитель ef2c5466dd
Коммит f3d007c8fd
9 изменённых файлов: 156 добавлений и 411 удалений

Просмотреть файл

@ -122,43 +122,28 @@ static AVPixelFormat ChooseVAAPIPixelFormat(AVCodecContext* aCodecContext,
return AV_PIX_FMT_NONE;
}
DMABufSurface::DMABufSurface(WaylandDMABufSurface* aSurface,
FFmpegLibWrapper* aLib)
: mSurface(aSurface),
mLib(aLib),
mAVHWFramesContext(nullptr),
mHWAVBuffer(nullptr) {
VAAPIFrameHolder::VAAPIFrameHolder(FFmpegLibWrapper* aLib,
WaylandDMABufSurface* aSurface,
AVCodecContext* aAVCodecContext,
AVFrame* aAVFrame)
: mLib(aLib),
mSurface(aSurface),
mAVHWFramesContext(mLib->av_buffer_ref(aAVCodecContext->hw_frames_ctx)),
mHWAVBuffer(mLib->av_buffer_ref(aAVFrame->buf[0])) {
FFMPEG_LOG("VAAPIFrameHolder is adding dmabuf surface UID = %d",
mSurface->GetUID());
// Create global refcount object to track mSurface usage over
// gects rendering engine. We can't release it until it's used
// by GL compositor / WebRender.
mSurface->GlobalRefCountCreate();
FFMPEG_LOG("DMABufSurface: creating surface UID = %d", mSurface->GetUID());
}
void DMABufSurface::LockVAAPIData(AVCodecContext* aAVCodecContext,
AVFrame* aAVFrame) {
FFMPEG_LOG("DMABufSurface: VAAPI locking dmabuf surface UID = %d",
VAAPIFrameHolder::~VAAPIFrameHolder() {
FFMPEG_LOG("VAAPIFrameHolder is releasing dmabuf surface UID = %d",
mSurface->GetUID());
if (aAVCodecContext && aAVFrame) {
mAVHWFramesContext = mLib->av_buffer_ref(aAVCodecContext->hw_frames_ctx);
mHWAVBuffer = mLib->av_buffer_ref(aAVFrame->buf[0]);
}
}
void DMABufSurface::ReleaseVAAPIData() {
FFMPEG_LOG("DMABufSurface: VAAPI releasing dmabuf surface UID = %d",
mSurface->GetUID());
if (mHWAVBuffer && mAVHWFramesContext) {
mLib->av_buffer_unref(&mHWAVBuffer);
mLib->av_buffer_unref(&mAVHWFramesContext);
}
mSurface->ReleaseSurface();
}
DMABufSurface::~DMABufSurface() {
FFMPEG_LOG("DMABufSurface: deleting dmabuf surface UID = %d",
mSurface->GetUID());
ReleaseVAAPIData();
mLib->av_buffer_unref(&mHWAVBuffer);
mLib->av_buffer_unref(&mAVHWFramesContext);
}
AVCodec* FFmpegVideoDecoder<LIBAV_VER>::FindVAAPICodec() {
@ -240,6 +225,14 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::InitVAAPIDecoder() {
return NS_ERROR_NOT_AVAILABLE;
}
auto layersBackend = mImageAllocator
? mImageAllocator->GetCompositorBackendType()
: layers::LayersBackend::LAYERS_BASIC;
if (layersBackend != layers::LayersBackend::LAYERS_WR) {
FFMPEG_LOG("VA-API works with WebRender only!");
return NS_ERROR_NOT_AVAILABLE;
}
AVCodec* codec = FindVAAPICodec();
if (!codec) {
FFMPEG_LOG("Couldn't find ffmpeg VA-API decoder");
@ -325,7 +318,6 @@ FFmpegVideoDecoder<LIBAV_VER>::FFmpegVideoDecoder(
mVAAPIDeviceContext(nullptr),
mDisableHardwareDecoding(aDisableHardwareDecoding),
mDisplay(nullptr),
mUseDMABufSurfaces(false),
#endif
mImageAllocator(aAllocator),
mImageContainer(aImageContainer),
@ -335,25 +327,13 @@ FFmpegVideoDecoder<LIBAV_VER>::FFmpegVideoDecoder(
// initialization.
mExtraData = new MediaByteBuffer;
mExtraData->AppendElements(*aConfig.mExtraData);
#ifdef MOZ_WAYLAND_USE_VAAPI
mUseDMABufSurfaces =
gfxPlatformGtk::GetPlatform()->UseWaylandDMABufVideoTextures() &&
mImageAllocator &&
(mImageAllocator->GetCompositorBackendType() ==
layers::LayersBackend::LAYERS_WR);
if (!mUseDMABufSurfaces) {
FFMPEG_LOG("DMA-BUF/VA-API can't be used, WebRender/Wayland is disabled");
}
#endif
}
RefPtr<MediaDataDecoder::InitPromise> FFmpegVideoDecoder<LIBAV_VER>::Init() {
MediaResult rv;
#ifdef MOZ_WAYLAND_USE_VAAPI
if (mUseDMABufSurfaces && !mDisableHardwareDecoding) {
if (!mDisableHardwareDecoding) {
rv = InitVAAPIDecoder();
if (NS_SUCCEEDED(rv)) {
return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
@ -453,8 +433,6 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
}
# ifdef MOZ_WAYLAND_USE_VAAPI
// Release unused VA-API surfaces before avcodec_receive_frame() as
// ffmpeg recycles VASurface for HW decoding.
if (mVAAPIDeviceContext) {
ReleaseUnusedVAAPIFrames();
}
@ -475,19 +453,10 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
MediaResult rv;
# ifdef MOZ_WAYLAND_USE_VAAPI
if (mVAAPIDeviceContext || mUseDMABufSurfaces) {
rv = CreateImageDMABuf(mFrame->pkt_pos, mFrame->pkt_pts,
mFrame->pkt_duration, aResults);
// If VA-API playback failed, just quit. Decoder is going to be restarted
// without VA-API.
// If VA-API is already off, disable DMABufSurfaces and fallback to
// default.
if (NS_FAILED(rv) && !mVAAPIDeviceContext) {
mUseDMABufSurfaces = false;
rv = CreateImage(mFrame->pkt_pos, mFrame->pkt_pts, mFrame->pkt_duration,
aResults);
}
if (mVAAPIDeviceContext) {
MOZ_ASSERT(mFrame->format == AV_PIX_FMT_VAAPI_VLD);
rv = CreateImageVAAPI(mFrame->pkt_pos, mFrame->pkt_pts,
mFrame->pkt_duration, aResults);
} else
# endif
{
@ -676,122 +645,69 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImage(
#ifdef MOZ_WAYLAND_USE_VAAPI
void FFmpegVideoDecoder<LIBAV_VER>::ReleaseUnusedVAAPIFrames() {
int len = mDMABufSurfaces.Length();
for (int i = 0; i < len; i++) {
if (!mDMABufSurfaces[i].IsUsed()) {
mDMABufSurfaces[i].ReleaseVAAPIData();
std::list<UniquePtr<VAAPIFrameHolder>>::iterator holder =
mFrameHolders.begin();
while (holder != mFrameHolders.end()) {
if (!(*holder)->IsUsed()) {
holder = mFrameHolders.erase(holder);
} else {
holder++;
}
}
}
DMABufSurface* FFmpegVideoDecoder<LIBAV_VER>::GetUnusedDMABufSurface() {
int len = mDMABufSurfaces.Length();
for (int i = 0; i < len; i++) {
if (!mDMABufSurfaces[i].IsUsed()) {
return &(mDMABufSurfaces[i]);
}
}
return nullptr;
void FFmpegVideoDecoder<LIBAV_VER>::ReleaseAllVAAPIFrames() {
mFrameHolders.clear();
}
void FFmpegVideoDecoder<LIBAV_VER>::ReleaseDMABufSurfaces() {
mDMABufSurfaces.Clear();
}
MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageVAAPI(
int64_t aOffset, int64_t aPts, int64_t aDuration,
MediaDataDecoder::DecodedData& aResults) {
FFMPEG_LOG("Got one VAAPI frame output with pts=%" PRId64 " dts=%" PRId64
" duration=%" PRId64 " opaque=%" PRId64,
aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque);
bool FFmpegVideoDecoder<LIBAV_VER>::GetVAAPISurfaceDescriptor(
VADRMPRIMESurfaceDescriptor& aVaDesc) {
VADRMPRIMESurfaceDescriptor va_desc;
VASurfaceID surface_id = (VASurfaceID)(uintptr_t)mFrame->data[3];
VAStatus vas = mLib->vaExportSurfaceHandle(
mDisplay, surface_id, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS,
&aVaDesc);
&va_desc);
if (vas != VA_STATUS_SUCCESS) {
return false;
return MediaResult(
NS_ERROR_OUT_OF_MEMORY,
RESULT_DETAIL("Unable to get frame by vaExportSurfaceHandle()"));
}
vas = mLib->vaSyncSurface(mDisplay, surface_id);
if (vas != VA_STATUS_SUCCESS) {
NS_WARNING("vaSyncSurface() failed.");
}
aVaDesc.width = mFrame->width;
aVaDesc.height = mFrame->height;
va_desc.width = mFrame->width;
va_desc.height = mFrame->height;
return true;
}
MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageDMABuf(
int64_t aOffset, int64_t aPts, int64_t aDuration,
MediaDataDecoder::DecodedData& aResults) {
FFMPEG_LOG("DMABUF/VA-API Got one frame output with pts=%" PRId64
"dts=%" PRId64 " duration=%" PRId64 " opaque=%" PRId64,
aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque);
// With SW decode we support only YUV420P format with DMABuf surfaces.
if (!mVAAPIDeviceContext && mCodecContext->pix_fmt != AV_PIX_FMT_YUV420P) {
return MediaResult(
NS_ERROR_NOT_IMPLEMENTED,
RESULT_DETAIL("DMA-BUF textures supports YUV420P format only"));
}
VADRMPRIMESurfaceDescriptor vaDesc;
if (mVAAPIDeviceContext && !GetVAAPISurfaceDescriptor(vaDesc)) {
RefPtr<WaylandDMABufSurfaceNV12> surface =
WaylandDMABufSurfaceNV12::CreateNV12Surface(va_desc);
if (!surface) {
return MediaResult(
NS_ERROR_OUT_OF_MEMORY,
RESULT_DETAIL("Unable to get frame by vaExportSurfaceHandle()"));
RESULT_DETAIL("Unable to allocate WaylandDMABufSurfaceNV12."));
}
RefPtr<WaylandDMABufSurfaceNV12> waylandSurface;
DMABufSurface* surface = GetUnusedDMABufSurface();
if (!surface) {
if (mVAAPIDeviceContext) {
waylandSurface = WaylandDMABufSurfaceNV12::CreateNV12Surface(vaDesc);
} else {
waylandSurface = WaylandDMABufSurfaceNV12::CreateNV12Surface(
mFrame->width, mFrame->height, (void**)mFrame->data,
mFrame->linesize);
}
if (!waylandSurface) {
return MediaResult(
NS_ERROR_OUT_OF_MEMORY,
RESULT_DETAIL("Unable to get WaylandDMABufSurfaceNV12"));
}
# ifdef MOZ_LOGGING
static int uid = 0;
waylandSurface->SetUID(++uid);
FFMPEG_LOG("Created new WaylandDMABufSurface UID = %d", uid);
static int uid = 0;
surface->SetUID(++uid);
FFMPEG_LOG("Created dmabuf UID = %d HW surface %x", uid, surface_id);
# endif
mDMABufSurfaces.AppendElement(DMABufSurface(waylandSurface, mLib));
surface = &(mDMABufSurfaces[mDMABufSurfaces.Length() - 1]);
} else {
waylandSurface = surface->GetWaylandDMABufSurface();
bool ret;
if (mVAAPIDeviceContext) {
ret = waylandSurface->UpdateNV12Data(vaDesc);
} else {
ret = waylandSurface->UpdateNV12Data((void**)mFrame->data,
mFrame->linesize);
}
surface->SetYUVColorSpace(GetFrameColorSpace());
if (!ret) {
return MediaResult(
NS_ERROR_OUT_OF_MEMORY,
RESULT_DETAIL("Unable to upload data to WaylandDMABufSurfaceNV12"));
}
FFMPEG_LOG("Reusing WaylandDMABufSurface UID = %d",
waylandSurface->GetUID());
}
// Store reference to the decoded HW buffer, see VAAPIFrameHolder struct.
auto holder =
MakeUnique<VAAPIFrameHolder>(mLib, surface, mCodecContext, mFrame);
mFrameHolders.push_back(std::move(holder));
if (mVAAPIDeviceContext) {
surface->LockVAAPIData(mCodecContext, mFrame);
}
waylandSurface->SetYUVColorSpace(GetFrameColorSpace());
RefPtr<layers::Image> im =
new layers::WaylandDMABUFSurfaceImage(waylandSurface);
RefPtr<layers::Image> im = new layers::WaylandDMABUFSurfaceImage(surface);
RefPtr<VideoData> vp = VideoData::CreateFromImage(
mInfo.mDisplay, aOffset, TimeUnit::FromMicroseconds(aPts),
@ -842,8 +758,8 @@ AVCodecID FFmpegVideoDecoder<LIBAV_VER>::GetCodecId(
void FFmpegVideoDecoder<LIBAV_VER>::ProcessShutdown() {
#ifdef MOZ_WAYLAND_USE_VAAPI
ReleaseDMABufSurfaces();
if (mVAAPIDeviceContext) {
ReleaseAllVAAPIFrames();
mLib->av_buffer_unref(&mVAAPIDeviceContext);
}
#endif

Просмотреть файл

@ -12,26 +12,12 @@
#include "SimpleMap.h"
#ifdef MOZ_WAYLAND_USE_VAAPI
# include "mozilla/widget/WaylandDMABufSurface.h"
# include "mozilla/LinkedList.h"
# include <list>
#endif
namespace mozilla {
#ifdef MOZ_WAYLAND_USE_VAAPI
// DMABufSurface holds a reference to GPU data with a video frame.
//
// Actual GPU pixel data are stored at WaylandDMABufSurface and
// WaylandDMABufSurfaces is passed to gecko GL rendering pipeline via.
// WaylandDMABUFSurfaceImage.
//
// DMABufSurface can optionally hold VA-API ffmpeg related data to keep
// GPU data locked untill we need them.
//
// DMABufSurface is used for both HW accelerated video decoding (VA-API)
// and ffmpeg SW decoding.
//
// VA-API scenario
//
// When VA-API decoding is running, ffmpeg allocates AVHWFramesContext - a pool
// of "hardware" frames. Every "hardware" frame (VASurface) is backed
// by actual piece of GPU memory which holds the decoded image data.
@ -47,37 +33,20 @@ namespace mozilla {
// Unfortunately there isn't any obvious way how to mark particular VASurface
// as used. The best we can do is to hold a reference to particular AVBuffer
// from decoded AVFrame and AVHWFramesContext which owns the AVBuffer.
//
// FFmpeg SW decoding scenario
//
// When SW ffmpeg decoding is running, DMABufSurface contains only
// a WaylandDMABufSurface reference and VA-API related members are null.
// We own the WaylandDMABufSurface underlying GPU data and we use it for
// repeated rendering of video frames.
//
class DMABufSurface final {
class VAAPIFrameHolder final {
public:
DMABufSurface(WaylandDMABufSurface* aSurface, FFmpegLibWrapper* aLib);
~DMABufSurface();
// Lock VAAPI related data
void LockVAAPIData(AVCodecContext* aAVCodecContext, AVFrame* aAVFrame);
// Release VAAPI related data, DMABufSurface can be reused
// for another frame.
void ReleaseVAAPIData();
VAAPIFrameHolder(FFmpegLibWrapper* aLib, WaylandDMABufSurface* aSurface,
AVCodecContext* aAVCodecContext, AVFrame* aAVFrame);
~VAAPIFrameHolder();
// Check if WaylandDMABufSurface is used by any gecko rendering process
// (WebRender or GL compositor) or by WaylandDMABUFSurfaceImage/VideoData.
bool IsUsed() const { return mSurface->IsGlobalRefSet(); }
const RefPtr<WaylandDMABufSurfaceNV12> GetWaylandDMABufSurface() {
return mSurface->GetAsWaylandDMABufSurfaceNV12();
}
private:
const RefPtr<WaylandDMABufSurface> mSurface;
const FFmpegLibWrapper* mLib;
const RefPtr<WaylandDMABufSurface> mSurface;
AVBufferRef* mAVHWFramesContext;
AVBufferRef* mHWAVBuffer;
};
@ -149,15 +118,11 @@ class FFmpegVideoDecoder<LIBAV_VER>
void InitVAAPICodecContext();
AVCodec* FindVAAPICodec();
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
bool GetVAAPISurfaceDescriptor(VADRMPRIMESurfaceDescriptor& aVaDesc);
MediaResult CreateImageDMABuf(int64_t aOffset, int64_t aPts,
int64_t aDuration,
MediaDataDecoder::DecodedData& aResults);
MediaResult CreateImageVAAPI(int64_t aOffset, int64_t aPts, int64_t aDuration,
MediaDataDecoder::DecodedData& aResults);
void ReleaseUnusedVAAPIFrames();
DMABufSurface* GetUnusedDMABufSurface();
void ReleaseDMABufSurfaces();
void ReleaseAllVAAPIFrames();
#endif
/**
@ -173,8 +138,7 @@ class FFmpegVideoDecoder<LIBAV_VER>
AVBufferRef* mVAAPIDeviceContext;
const bool mDisableHardwareDecoding;
VADisplay mDisplay;
bool mUseDMABufSurfaces;
nsTArray<DMABufSurface> mDMABufSurfaces;
std::list<UniquePtr<VAAPIFrameHolder>> mFrameHolders;
#endif
RefPtr<KnowsCompositor> mImageAllocator;
RefPtr<ImageContainer> mImageContainer;

Просмотреть файл

@ -725,9 +725,6 @@ already_AddRefed<gfx::VsyncSource> gfxPlatformGtk::CreateHardwareVsyncSource() {
bool gfxPlatformGtk::UseWaylandDMABufTextures() {
return IsWaylandDisplay() && nsWaylandDisplay::IsDMABufTexturesEnabled();
}
bool gfxPlatformGtk::UseWaylandDMABufVideoTextures() {
return IsWaylandDisplay() && nsWaylandDisplay::IsDMABufVideoTexturesEnabled();
}
bool gfxPlatformGtk::UseWaylandDMABufWebGL() {
return IsWaylandDisplay() && nsWaylandDisplay::IsDMABufWebGLEnabled();
}

Просмотреть файл

@ -88,7 +88,6 @@ class gfxPlatformGtk final : public gfxPlatform {
#ifdef MOZ_WAYLAND
bool UseWaylandDMABufTextures();
bool UseWaylandDMABufVideoTextures();
bool UseWaylandDMABufWebGL();
bool UseWaylandHardwareVideoDecoding();
#endif

Просмотреть файл

@ -9474,12 +9474,6 @@
value: false
mirror: always
# Use DMABuf for video textures.
- name: widget.wayland-dmabuf-video-textures.enabled
type: RelaxedAtomicBool
value: true
mirror: always
# Use smooth rendering for basic compositor.
- name: widget.wayland-smooth-rendering
type: RelaxedAtomicBool

Просмотреть файл

@ -107,6 +107,7 @@ void WaylandDMABufSurface::GlobalRefCountImport(int aFd) {
}
void WaylandDMABufSurface::GlobalRefCountDelete() {
MOZ_ASSERT(mGlobalRefCountFd);
if (mGlobalRefCountFd) {
GlobalRefRelease();
close(mGlobalRefCountFd);
@ -114,22 +115,6 @@ void WaylandDMABufSurface::GlobalRefCountDelete() {
}
}
void WaylandDMABufSurface::ReleaseDMABuf() {
for (int i = 0; i < mBufferPlaneCount; i++) {
Unmap(i);
if (mDmabufFds[i] >= 0) {
close(mDmabufFds[i]);
mDmabufFds[i] = -1;
}
}
if (mGbmBufferObject[0]) {
nsGbmLib::Destroy(mGbmBufferObject[0]);
mGbmBufferObject[0] = nullptr;
}
}
WaylandDMABufSurface::WaylandDMABufSurface(SurfaceType aSurfaceType)
: mSurfaceType(aSurfaceType),
mBufferModifier(DRM_FORMAT_MOD_INVALID),
@ -137,9 +122,6 @@ WaylandDMABufSurface::WaylandDMABufSurface(SurfaceType aSurfaceType)
mDrmFormats(),
mStrides(),
mOffsets(),
mGbmBufferObject(),
mMappedRegion(),
mMappedRegionStride(),
mSync(0),
mGlobalRefCountFd(0),
mUID(0) {
@ -285,9 +267,12 @@ WaylandDMABufSurfaceRGBA::WaylandDMABufSurfaceRGBA()
mHeight(0),
mGmbFormat(nullptr),
mWLBuffer(nullptr),
mMappedRegion(nullptr),
mMappedRegionStride(0),
mGbmBufferObject(nullptr),
mGbmBufferFlags(0),
mEGLImage(LOCAL_EGL_NO_IMAGE),
mTexture(0),
mGbmBufferFlags(0),
mWLBufferAttached(false),
mFastWLBufferCreation(true) {}
@ -295,16 +280,14 @@ WaylandDMABufSurfaceRGBA::~WaylandDMABufSurfaceRGBA() { ReleaseSurface(); }
bool WaylandDMABufSurfaceRGBA::Create(int aWidth, int aHeight,
int aWaylandDMABufSurfaceFlags) {
nsWaylandDisplay* display = WaylandDisplayGet();
if (!display) {
return false;
}
MOZ_ASSERT(mGbmBufferObject[0] == nullptr, "Already created?");
MOZ_RELEASE_ASSERT(WaylandDisplayGet());
MOZ_ASSERT(mGbmBufferObject == nullptr, "Already created?");
mSurfaceFlags = aWaylandDMABufSurfaceFlags;
mWidth = aWidth;
mHeight = aHeight;
nsWaylandDisplay* display = WaylandDisplayGet();
mGmbFormat = display->GetGbmFormat(mSurfaceFlags & DMABUF_ALPHA);
if (!mGmbFormat) {
// Requested DRM format is not supported.
@ -314,16 +297,16 @@ bool WaylandDMABufSurfaceRGBA::Create(int aWidth, int aHeight,
bool useModifiers = (aWaylandDMABufSurfaceFlags & DMABUF_USE_MODIFIERS) &&
mGmbFormat->mModifiersCount > 0;
if (useModifiers) {
mGbmBufferObject[0] = nsGbmLib::CreateWithModifiers(
mGbmBufferObject = nsGbmLib::CreateWithModifiers(
display->GetGbmDevice(), mWidth, mHeight, mGmbFormat->mFormat,
mGmbFormat->mModifiers, mGmbFormat->mModifiersCount);
if (mGbmBufferObject[0]) {
mBufferModifier = nsGbmLib::GetModifier(mGbmBufferObject[0]);
if (mGbmBufferObject) {
mBufferModifier = nsGbmLib::GetModifier(mGbmBufferObject);
}
}
// Create without modifiers - use plain/linear format.
if (!mGbmBufferObject[0]) {
if (!mGbmBufferObject) {
mGbmBufferFlags = (GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR);
if (mSurfaceFlags & DMABUF_CREATE_WL_BUFFER) {
mGbmBufferFlags |= GBM_BO_USE_RENDERING;
@ -336,19 +319,19 @@ bool WaylandDMABufSurfaceRGBA::Create(int aWidth, int aHeight,
mGbmBufferFlags &= ~GBM_BO_USE_SCANOUT;
}
mGbmBufferObject[0] =
mGbmBufferObject =
nsGbmLib::Create(display->GetGbmDevice(), mWidth, mHeight,
mGmbFormat->mFormat, mGbmBufferFlags);
mBufferModifier = DRM_FORMAT_MOD_INVALID;
}
if (!mGbmBufferObject[0]) {
if (!mGbmBufferObject) {
return false;
}
if (mBufferModifier != DRM_FORMAT_MOD_INVALID) {
mBufferPlaneCount = nsGbmLib::GetPlaneCount(mGbmBufferObject[0]);
mBufferPlaneCount = nsGbmLib::GetPlaneCount(mGbmBufferObject);
if (mBufferPlaneCount > DMABUF_BUFFER_PLANES) {
NS_WARNING("There's too many dmabuf planes!");
ReleaseSurface();
@ -356,20 +339,20 @@ bool WaylandDMABufSurfaceRGBA::Create(int aWidth, int aHeight,
}
for (int i = 0; i < mBufferPlaneCount; i++) {
uint32_t handle = nsGbmLib::GetHandleForPlane(mGbmBufferObject[0], i).u32;
uint32_t handle = nsGbmLib::GetHandleForPlane(mGbmBufferObject, i).u32;
int ret = nsGbmLib::DrmPrimeHandleToFD(display->GetGbmDeviceFd(), handle,
0, &mDmabufFds[i]);
if (ret < 0 || mDmabufFds[i] < 0) {
ReleaseSurface();
return false;
}
mStrides[i] = nsGbmLib::GetStrideForPlane(mGbmBufferObject[0], i);
mOffsets[i] = nsGbmLib::GetOffset(mGbmBufferObject[0], i);
mStrides[i] = nsGbmLib::GetStrideForPlane(mGbmBufferObject, i);
mOffsets[i] = nsGbmLib::GetOffset(mGbmBufferObject, i);
}
} else {
mBufferPlaneCount = 1;
mStrides[0] = nsGbmLib::GetStride(mGbmBufferObject[0]);
mDmabufFds[0] = nsGbmLib::GetFd(mGbmBufferObject[0]);
mStrides[0] = nsGbmLib::GetStride(mGbmBufferObject);
mDmabufFds[0] = nsGbmLib::GetFd(mGbmBufferObject);
if (mDmabufFds[0] < 0) {
ReleaseSurface();
return false;
@ -584,29 +567,41 @@ void WaylandDMABufSurfaceRGBA::ReleaseSurface() {
mWLBuffer = nullptr;
}
ReleaseDMABuf();
for (int i = 0; i < mBufferPlaneCount; i++) {
if (mDmabufFds[i] >= 0) {
close(mDmabufFds[i]);
mDmabufFds[i] = 0;
}
}
if (mGbmBufferObject) {
nsGbmLib::Destroy(mGbmBufferObject);
mGbmBufferObject = nullptr;
}
}
void* WaylandDMABufSurface::MapInternal(uint32_t aX, uint32_t aY,
uint32_t aWidth, uint32_t aHeight,
uint32_t* aStride, int aGbmFlags,
int aPlane) {
NS_ASSERTION(!IsMapped(aPlane), "Already mapped!");
if (!mGbmBufferObject[aPlane]) {
void* WaylandDMABufSurfaceRGBA::MapInternal(uint32_t aX, uint32_t aY,
uint32_t aWidth, uint32_t aHeight,
uint32_t* aStride, int aGbmFlags) {
NS_ASSERTION(!IsMapped(), "Already mapped!");
if (!mGbmBufferObject) {
NS_WARNING(
"We can't map WaylandDMABufSurfaceRGBA without mGbmBufferObject");
return nullptr;
}
mMappedRegionStride[aPlane] = 0;
mMappedRegionData[aPlane] = nullptr;
mMappedRegion[aPlane] = nsGbmLib::Map(
mGbmBufferObject[aPlane], aX, aY, aWidth, aHeight, aGbmFlags,
&mMappedRegionStride[aPlane], &mMappedRegionData[aPlane]);
if (aStride) {
*aStride = mMappedRegionStride[aPlane];
if (mSurfaceFlags & DMABUF_USE_MODIFIERS) {
NS_WARNING("We should not map dmabuf surfaces with modifiers!");
}
return mMappedRegion[aPlane];
mMappedRegionStride = 0;
mMappedRegion =
nsGbmLib::Map(mGbmBufferObject, aX, aY, aWidth, aHeight, aGbmFlags,
&mMappedRegionStride, &mMappedRegionData);
if (aStride) {
*aStride = mMappedRegionStride;
}
return mMappedRegion;
}
void* WaylandDMABufSurfaceRGBA::MapReadOnly(uint32_t aX, uint32_t aY,
@ -630,12 +625,12 @@ void* WaylandDMABufSurfaceRGBA::Map(uint32_t* aStride) {
GBM_BO_TRANSFER_READ_WRITE);
}
void WaylandDMABufSurface::Unmap(int aPlane) {
if (mMappedRegion[aPlane]) {
nsGbmLib::Unmap(mGbmBufferObject[aPlane], mMappedRegionData[aPlane]);
mMappedRegion[aPlane] = nullptr;
mMappedRegionData[aPlane] = nullptr;
mMappedRegionStride[aPlane] = 0;
void WaylandDMABufSurfaceRGBA::Unmap() {
if (mMappedRegion) {
nsGbmLib::Unmap(mGbmBufferObject, mMappedRegionData);
mMappedRegion = nullptr;
mMappedRegionData = nullptr;
mMappedRegionStride = 0;
}
}
@ -712,18 +707,7 @@ already_AddRefed<WaylandDMABufSurfaceNV12>
WaylandDMABufSurfaceNV12::CreateNV12Surface(
const VADRMPRIMESurfaceDescriptor& aDesc) {
RefPtr<WaylandDMABufSurfaceNV12> surf = new WaylandDMABufSurfaceNV12();
if (!surf->UpdateNV12Data(aDesc)) {
return nullptr;
}
return surf.forget();
}
already_AddRefed<WaylandDMABufSurfaceNV12>
WaylandDMABufSurfaceNV12::CreateNV12Surface(int aWidth, int aHeight,
void** aPixelData,
int* aLineSizes) {
RefPtr<WaylandDMABufSurfaceNV12> surf = new WaylandDMABufSurfaceNV12();
if (!surf->Create(aWidth, aHeight, aPixelData, aLineSizes)) {
if (!surf->Create(aDesc)) {
return nullptr;
}
return surf.forget();
@ -743,7 +727,7 @@ WaylandDMABufSurfaceNV12::WaylandDMABufSurfaceNV12()
WaylandDMABufSurfaceNV12::~WaylandDMABufSurfaceNV12() { ReleaseSurface(); }
bool WaylandDMABufSurfaceNV12::UpdateNV12Data(
bool WaylandDMABufSurfaceNV12::Create(
const VADRMPRIMESurfaceDescriptor& aDesc) {
if (aDesc.fourcc != VA_FOURCC_NV12) {
return false;
@ -752,9 +736,6 @@ bool WaylandDMABufSurfaceNV12::UpdateNV12Data(
aDesc.num_objects > DMABUF_BUFFER_PLANES) {
return false;
}
if (mDmabufFds[0] >= 0) {
ReleaseSurface();
}
mSurfaceFormat = gfx::SurfaceFormat::NV12;
mBufferPlaneCount = aDesc.num_layers;
@ -777,89 +758,6 @@ bool WaylandDMABufSurfaceNV12::UpdateNV12Data(
return true;
}
bool WaylandDMABufSurfaceNV12::CreateNV12Plane(nsWaylandDisplay* display,
int aPlane, int aWidth,
int aHeight, int aDrmFormat) {
mWidth[aPlane] = aWidth;
mHeight[aPlane] = aHeight;
mDrmFormats[aPlane] = aDrmFormat;
mGbmBufferObject[aPlane] =
nsGbmLib::Create(display->GetGbmDevice(), aWidth, aHeight, aDrmFormat,
GBM_BO_USE_LINEAR | GBM_BO_USE_TEXTURING);
if (!mGbmBufferObject[aPlane]) {
return false;
}
mStrides[aPlane] = nsGbmLib::GetStride(mGbmBufferObject[aPlane]);
mDmabufFds[aPlane] = nsGbmLib::GetFd(mGbmBufferObject[aPlane]);
return true;
}
bool WaylandDMABufSurfaceNV12::UpdateNV12Data(void** aPixelData,
int* aLineSizes) {
if (aLineSizes[0] != mWidth[0] || aLineSizes[1] != mWidth[1] ||
aLineSizes[2] != mWidth[1]) {
NS_WARNING("WaylandDMABufSurfaceNV12 size does not match!");
return false;
}
auto unmapBuffers = MakeScopeExit([&] {
Unmap(0);
Unmap(1);
});
char* yData = (char*)MapInternal(0, 0, mWidth[0], mHeight[0], nullptr,
GBM_BO_TRANSFER_READ, 0);
if (!yData || mMappedRegionStride[0] != mWidth[0]) {
NS_WARNING("WaylandDMABufSurfaceNV12 plane 1 size stride does not match!");
return false;
}
char* nvData = (char*)MapInternal(0, 0, mWidth[1], mHeight[1], nullptr,
GBM_BO_TRANSFER_READ, 1);
if (!nvData || mMappedRegionStride[1] != mWidth[1] * 2) {
NS_WARNING("WaylandDMABufSurfaceNV12 plane 2 size stride does not match!");
return false;
}
// Copy Y plane
memcpy(yData, aPixelData[0], aLineSizes[0] * mHeight[0]);
// Copy NV planes
char* nSrcPixels = (char*)aPixelData[1];
char* vSrcPixels = (char*)aPixelData[2];
int bufferLen = (aLineSizes[1] + aLineSizes[2]) * (mHeight[1]);
for (int i = 0; i < bufferLen; i += 2) {
*nvData++ = *nSrcPixels++;
*nvData++ = *vSrcPixels++;
}
return true;
}
bool WaylandDMABufSurfaceNV12::Create(int aWidth, int aHeight,
void** aPixelData, int* aLineSizes) {
nsWaylandDisplay* display = WaylandDisplayGet();
if (!display) {
return false;
}
mBufferPlaneCount = 2;
if (!CreateNV12Plane(display, 0, aWidth, aHeight, GBM_FORMAT_R8)) {
return false;
}
if (!CreateNV12Plane(display, 1, aWidth >> 1, aHeight >> 1,
GBM_FORMAT_GR88)) {
return false;
}
return aPixelData != nullptr && aLineSizes != nullptr
? UpdateNV12Data(aPixelData, aLineSizes)
: true;
}
bool WaylandDMABufSurfaceNV12::Create(const SurfaceDescriptor& aDesc) {
ImportSurfaceDescriptor(aDesc);
return true;
@ -1037,5 +935,11 @@ gfx::SurfaceFormat WaylandDMABufSurfaceNV12::GetFormatGL() {
void WaylandDMABufSurfaceNV12::ReleaseSurface() {
ReleaseTextures();
ReleaseDMABuf();
for (int i = 0; i < mBufferPlaneCount; i++) {
if (mDmabufFds[i] >= 0) {
close(mDmabufFds[i]);
mDmabufFds[i] = 0;
}
}
}

Просмотреть файл

@ -39,7 +39,6 @@ typedef enum {
} WaylandDMABufSurfaceFlags;
class WaylandDMABufSurfaceRGBA;
class WaylandDMABufSurfaceNV12;
class WaylandDMABufSurface {
public:
@ -75,15 +74,9 @@ class WaylandDMABufSurface {
SurfaceType GetSurfaceType() { return mSurfaceType; };
virtual uint32_t GetTextureCount() = 0;
bool IsMapped(int aPlane = 0) { return (mMappedRegion[aPlane] != nullptr); };
void Unmap(int aPlane = 0);
virtual WaylandDMABufSurfaceRGBA* GetAsWaylandDMABufSurfaceRGBA() {
return nullptr;
}
virtual WaylandDMABufSurfaceNV12* GetAsWaylandDMABufSurfaceNV12() {
return nullptr;
}
virtual mozilla::gfx::YUVColorSpace GetYUVColorSpace() {
return mozilla::gfx::YUVColorSpace::UNKNOWN;
@ -123,23 +116,16 @@ class WaylandDMABufSurface {
void GlobalRefAdd();
void GlobalRefRelease();
// Release all underlying data.
virtual void ReleaseSurface() = 0;
WaylandDMABufSurface(SurfaceType aSurfaceType);
protected:
virtual bool Create(const mozilla::layers::SurfaceDescriptor& aDesc) = 0;
virtual void ReleaseSurface() = 0;
bool FenceCreate(int aFd);
void GlobalRefCountImport(int aFd);
void GlobalRefCountDelete();
void ReleaseDMABuf();
void* MapInternal(uint32_t aX, uint32_t aY, uint32_t aWidth, uint32_t aHeight,
uint32_t* aStride, int aGbmFlags, int aPlane = 0);
virtual ~WaylandDMABufSurface();
SurfaceType mSurfaceType;
@ -151,11 +137,6 @@ class WaylandDMABufSurface {
uint32_t mStrides[DMABUF_BUFFER_PLANES];
uint32_t mOffsets[DMABUF_BUFFER_PLANES];
struct gbm_bo* mGbmBufferObject[DMABUF_BUFFER_PLANES];
void* mMappedRegion[DMABUF_BUFFER_PLANES];
void* mMappedRegionData[DMABUF_BUFFER_PLANES];
uint32_t mMappedRegionStride[DMABUF_BUFFER_PLANES];
EGLSyncKHR mSync;
RefPtr<mozilla::gl::GLContext> mGL;
@ -175,8 +156,6 @@ class WaylandDMABufSurfaceRGBA : public WaylandDMABufSurface {
bool Resize(int aWidth, int aHeight);
void Clear();
void ReleaseSurface();
bool CopyFrom(class WaylandDMABufSurface* aSourceSurface);
int GetWidth(int aPlane = 0) { return mWidth; };
@ -191,10 +170,10 @@ class WaylandDMABufSurfaceRGBA : public WaylandDMABufSurface {
void* Map(uint32_t aX, uint32_t aY, uint32_t aWidth, uint32_t aHeight,
uint32_t* aStride = nullptr);
void* Map(uint32_t* aStride = nullptr);
void* GetMappedRegion(int aPlane = 0) { return mMappedRegion[aPlane]; };
uint32_t GetMappedRegionStride(int aPlane = 0) {
return mMappedRegionStride[aPlane];
};
void* GetMappedRegion() { return mMappedRegion; };
uint32_t GetMappedRegionStride() { return mMappedRegionStride; };
bool IsMapped() { return (mMappedRegion != nullptr); };
void Unmap();
bool CreateTexture(mozilla::gl::GLContext* aGLContext, int aPlane = 0);
void ReleaseTextures();
@ -216,10 +195,14 @@ class WaylandDMABufSurfaceRGBA : public WaylandDMABufSurface {
bool Create(int aWidth, int aHeight, int aWaylandDMABufSurfaceFlags);
bool Create(const mozilla::layers::SurfaceDescriptor& aDesc);
void ReleaseSurface();
bool CreateWLBuffer();
void ImportSurfaceDescriptor(const mozilla::layers::SurfaceDescriptor& aDesc);
void* MapInternal(uint32_t aX, uint32_t aY, uint32_t aWidth, uint32_t aHeight,
uint32_t* aStride, int aGbmFlags);
private:
int mSurfaceFlags;
@ -228,9 +211,15 @@ class WaylandDMABufSurfaceRGBA : public WaylandDMABufSurface {
mozilla::widget::GbmFormat* mGmbFormat;
wl_buffer* mWLBuffer;
void* mMappedRegion;
void* mMappedRegionData;
uint32_t mMappedRegionStride;
struct gbm_bo* mGbmBufferObject;
uint32_t mGbmBufferFlags;
EGLImageKHR mEGLImage;
GLuint mTexture;
uint32_t mGbmBufferFlags;
bool mWLBufferAttached;
bool mFastWLBufferCreation;
@ -238,16 +227,12 @@ class WaylandDMABufSurfaceRGBA : public WaylandDMABufSurface {
class WaylandDMABufSurfaceNV12 : public WaylandDMABufSurface {
public:
static already_AddRefed<WaylandDMABufSurfaceNV12> CreateNV12Surface(
int aWidth, int aHeight, void** aPixelData = nullptr,
int* aLineSizes = nullptr);
static already_AddRefed<WaylandDMABufSurfaceNV12> CreateNV12Surface(
const VADRMPRIMESurfaceDescriptor& aDesc);
bool Serialize(mozilla::layers::SurfaceDescriptor& aOutDescriptor);
bool Create(const VADRMPRIMESurfaceDescriptor& aDesc);
WaylandDMABufSurfaceNV12* GetAsWaylandDMABufSurfaceNV12() { return this; };
bool Serialize(mozilla::layers::SurfaceDescriptor& aOutDescriptor);
int GetWidth(int aPlane = 0) { return mWidth[aPlane]; }
int GetHeight(int aPlane = 0) { return mHeight[aPlane]; }
@ -256,9 +241,6 @@ class WaylandDMABufSurfaceNV12 : public WaylandDMABufSurface {
bool CreateTexture(mozilla::gl::GLContext* aGLContext, int aPlane = 0);
void ReleaseTextures();
void ReleaseSurface();
GLuint GetTexture(int aPlane = 0) { return mTexture[aPlane]; };
EGLImageKHR GetEGLImage(int aPlane = 0) { return mEGLImage[aPlane]; };
@ -273,16 +255,11 @@ class WaylandDMABufSurfaceNV12 : public WaylandDMABufSurface {
WaylandDMABufSurfaceNV12();
bool UpdateNV12Data(void** aPixelData, int* aLineSizes);
bool UpdateNV12Data(const VADRMPRIMESurfaceDescriptor& aDesc);
private:
~WaylandDMABufSurfaceNV12();
bool Create(const mozilla::layers::SurfaceDescriptor& aDesc);
bool Create(int aWidth, int aHeight, void** aPixelData, int* aLineSizes);
bool CreateNV12Plane(mozilla::widget::nsWaylandDisplay* display, int aPlane,
int aWidth, int aHeight, int aDrmFormat);
void ReleaseSurface();
void ImportSurfaceDescriptor(
const mozilla::layers::SurfaceDescriptorDMABuf& aDesc);

Просмотреть файл

@ -498,7 +498,6 @@ bool nsWaylandDisplay::IsDMABufEnabled() {
!StaticPrefs::widget_wayland_dmabuf_basic_compositor_enabled() &&
!StaticPrefs::widget_wayland_dmabuf_textures_enabled() &&
#endif
!StaticPrefs::widget_wayland_dmabuf_video_textures_enabled() &&
!StaticPrefs::widget_wayland_dmabuf_webgl_enabled() &&
!StaticPrefs::widget_wayland_dmabuf_vaapi_enabled()) {
// Disabled by user, just quit.
@ -536,10 +535,6 @@ bool nsWaylandDisplay::IsDMABufTexturesEnabled() {
bool nsWaylandDisplay::IsDMABufBasicEnabled() { return false; }
bool nsWaylandDisplay::IsDMABufTexturesEnabled() { return false; }
#endif
bool nsWaylandDisplay::IsDMABufVideoTexturesEnabled() {
return IsDMABufEnabled() &&
StaticPrefs::widget_wayland_dmabuf_video_textures_enabled();
}
bool nsWaylandDisplay::IsDMABufWebGLEnabled() {
return IsDMABufEnabled() &&
StaticPrefs::widget_wayland_dmabuf_webgl_enabled();

Просмотреть файл

@ -91,7 +91,6 @@ class nsWaylandDisplay {
static bool IsDMABufEnabled();
static bool IsDMABufBasicEnabled();
static bool IsDMABufTexturesEnabled();
static bool IsDMABufVideoTexturesEnabled();
static bool IsDMABufWebGLEnabled();
static bool IsDMABufVAAPIEnabled();