279 lines
9.6 KiB
Diff
279 lines
9.6 KiB
Diff
diff --git a/widget/gtk/DMABufSurface.h b/widget/gtk/DMABufSurface.h
|
|
--- a/widget/gtk/DMABufSurface.h
|
|
+++ b/widget/gtk/DMABufSurface.h
|
|
@@ -173,13 +173,13 @@
|
|
SurfaceType mSurfaceType;
|
|
uint64_t mBufferModifiers[DMABUF_BUFFER_PLANES];
|
|
|
|
int mBufferPlaneCount;
|
|
int mDmabufFds[DMABUF_BUFFER_PLANES];
|
|
- uint32_t mDrmFormats[DMABUF_BUFFER_PLANES];
|
|
- uint32_t mStrides[DMABUF_BUFFER_PLANES];
|
|
- uint32_t mOffsets[DMABUF_BUFFER_PLANES];
|
|
+ int32_t mDrmFormats[DMABUF_BUFFER_PLANES];
|
|
+ int32_t mStrides[DMABUF_BUFFER_PLANES];
|
|
+ int32_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];
|
|
@@ -198,10 +198,14 @@
|
|
class DMABufSurfaceRGBA : public DMABufSurface {
|
|
public:
|
|
static already_AddRefed<DMABufSurfaceRGBA> CreateDMABufSurface(
|
|
int aWidth, int aHeight, int aDMABufSurfaceFlags);
|
|
|
|
+ static already_AddRefed<DMABufSurface> CreateDMABufSurface(
|
|
+ mozilla::gl::GLContext* aGLContext, const EGLImageKHR aEGLImage,
|
|
+ int aWidth, int aHeight);
|
|
+
|
|
bool Serialize(mozilla::layers::SurfaceDescriptor& aOutDescriptor);
|
|
|
|
DMABufSurfaceRGBA* GetAsDMABufSurfaceRGBA() { return this; }
|
|
|
|
void Clear();
|
|
@@ -247,10 +251,12 @@
|
|
private:
|
|
~DMABufSurfaceRGBA();
|
|
|
|
bool Create(int aWidth, int aHeight, int aDMABufSurfaceFlags);
|
|
bool Create(const mozilla::layers::SurfaceDescriptor& aDesc);
|
|
+ bool Create(mozilla::gl::GLContext* aGLContext, const EGLImageKHR aEGLImage,
|
|
+ int aWidth, int aHeight);
|
|
|
|
bool ImportSurfaceDescriptor(const mozilla::layers::SurfaceDescriptor& aDesc);
|
|
|
|
bool OpenFileDescriptorForPlane(const mozilla::MutexAutoLock& aProofOfLock,
|
|
int aPlane);
|
|
diff --git a/widget/gtk/DMABufSurface.cpp b/widget/gtk/DMABufSurface.cpp
|
|
--- a/widget/gtk/DMABufSurface.cpp
|
|
+++ b/widget/gtk/DMABufSurface.cpp
|
|
@@ -204,10 +204,12 @@
|
|
}
|
|
}
|
|
|
|
void DMABufSurface::FenceSet() {
|
|
if (!mGL || !mGL->MakeCurrent()) {
|
|
+ MOZ_DIAGNOSTIC_ASSERT(mGL,
|
|
+ "DMABufSurface::FenceSet(): missing GL context!");
|
|
return;
|
|
}
|
|
const auto& gle = gl::GLContextEGL::Cast(mGL);
|
|
const auto& egl = gle->mEgl;
|
|
|
|
@@ -228,21 +230,23 @@
|
|
mGL->fFinish();
|
|
}
|
|
|
|
void DMABufSurface::FenceWait() {
|
|
if (!mGL || mSyncFd < 0) {
|
|
+ MOZ_DIAGNOSTIC_ASSERT(mGL,
|
|
+ "DMABufSurface::FenceWait() missing GL context!");
|
|
return;
|
|
}
|
|
|
|
const auto& gle = gl::GLContextEGL::Cast(mGL);
|
|
const auto& egl = gle->mEgl;
|
|
|
|
const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID, mSyncFd,
|
|
LOCAL_EGL_NONE};
|
|
EGLSync sync = egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
|
|
if (!sync) {
|
|
- MOZ_ASSERT(false, "Failed to create GLFence!");
|
|
+ MOZ_ASSERT(false, "DMABufSurface::FenceWait(): Failed to create GLFence!");
|
|
// We failed to create GLFence so clear mSyncFd to avoid another try.
|
|
close(mSyncFd);
|
|
mSyncFd = -1;
|
|
return;
|
|
}
|
|
@@ -338,17 +342,18 @@
|
|
mGmbFormat = GetDMABufDevice()->GetGbmFormat(mSurfaceFlags & DMABUF_ALPHA);
|
|
if (!mGmbFormat) {
|
|
// Requested DRM format is not supported.
|
|
return false;
|
|
}
|
|
+ mDrmFormats[0] = mGmbFormat->mFormat;
|
|
|
|
bool useModifiers = (aDMABufSurfaceFlags & DMABUF_USE_MODIFIERS) &&
|
|
mGmbFormat->mModifiersCount > 0;
|
|
if (useModifiers) {
|
|
LOGDMABUF((" Creating with modifiers\n"));
|
|
mGbmBufferObject[0] = nsGbmLib::CreateWithModifiers(
|
|
- GetDMABufDevice()->GetGbmDevice(), mWidth, mHeight, mGmbFormat->mFormat,
|
|
+ GetDMABufDevice()->GetGbmDevice(), mWidth, mHeight, mDrmFormats[0],
|
|
mGmbFormat->mModifiers, mGmbFormat->mModifiersCount);
|
|
if (mGbmBufferObject[0]) {
|
|
mBufferModifiers[0] = nsGbmLib::GetModifier(mGbmBufferObject[0]);
|
|
}
|
|
}
|
|
@@ -356,11 +361,11 @@
|
|
if (!mGbmBufferObject[0]) {
|
|
LOGDMABUF((" Creating without modifiers\n"));
|
|
mGbmBufferFlags = GBM_BO_USE_LINEAR;
|
|
mGbmBufferObject[0] =
|
|
nsGbmLib::Create(GetDMABufDevice()->GetGbmDevice(), mWidth, mHeight,
|
|
- mGmbFormat->mFormat, mGbmBufferFlags);
|
|
+ mDrmFormats[0], mGbmBufferFlags);
|
|
mBufferModifiers[0] = DRM_FORMAT_MOD_INVALID;
|
|
}
|
|
|
|
if (!mGbmBufferObject[0]) {
|
|
LOGDMABUF((" Failed to create GbmBufferObject\n"));
|
|
@@ -386,22 +391,51 @@
|
|
|
|
LOGDMABUF((" Success\n"));
|
|
return true;
|
|
}
|
|
|
|
+bool DMABufSurfaceRGBA::Create(mozilla::gl::GLContext* aGLContext,
|
|
+ const EGLImageKHR aEGLImage, int aWidth,
|
|
+ int aHeight) {
|
|
+ LOGDMABUF(("DMABufSurfaceRGBA::Create() from EGLImage UID = %d\n", mUID));
|
|
+ if (!aGLContext) {
|
|
+ return false;
|
|
+ }
|
|
+ const auto& gle = gl::GLContextEGL::Cast(aGLContext);
|
|
+ const auto& egl = gle->mEgl;
|
|
+
|
|
+ mGL = aGLContext;
|
|
+ mWidth = aWidth;
|
|
+ mHeight = aHeight;
|
|
+ mEGLImage = aEGLImage;
|
|
+ if (!egl->fExportDMABUFImageQuery(mEGLImage, mDrmFormats, &mBufferPlaneCount,
|
|
+ mBufferModifiers)) {
|
|
+ LOGDMABUF((" ExportDMABUFImageQueryMESA failed, quit\n"));
|
|
+ return false;
|
|
+ }
|
|
+ if (mBufferPlaneCount > DMABUF_BUFFER_PLANES) {
|
|
+ LOGDMABUF((" wrong plane count %d, quit\n", mBufferPlaneCount));
|
|
+ return false;
|
|
+ }
|
|
+ if (!egl->fExportDMABUFImage(mEGLImage, mDmabufFds, mStrides, mOffsets)) {
|
|
+ LOGDMABUF((" ExportDMABUFImageMESA failed, quit\n"));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ LOGDMABUF((" imported size %d x %d format %x planes %d", mWidth, mHeight,
|
|
+ mDrmFormats[0], mBufferPlaneCount));
|
|
+ return true;
|
|
+}
|
|
+
|
|
bool DMABufSurfaceRGBA::ImportSurfaceDescriptor(
|
|
const SurfaceDescriptor& aDesc) {
|
|
const SurfaceDescriptorDMABuf& desc = aDesc.get_SurfaceDescriptorDMABuf();
|
|
|
|
mWidth = desc.width()[0];
|
|
mHeight = desc.height()[0];
|
|
mBufferModifiers[0] = desc.modifier()[0];
|
|
- if (mBufferModifiers[0] != DRM_FORMAT_MOD_INVALID) {
|
|
- mGmbFormat = GetDMABufDevice()->GetExactGbmFormat(desc.format()[0]);
|
|
- } else {
|
|
- mDrmFormats[0] = desc.format()[0];
|
|
- }
|
|
+ mDrmFormats[0] = desc.format()[0];
|
|
mBufferPlaneCount = desc.fds().Length();
|
|
mGbmBufferFlags = desc.flags();
|
|
MOZ_RELEASE_ASSERT(mBufferPlaneCount <= DMABUF_BUFFER_PLANES);
|
|
mUID = desc.uid();
|
|
|
|
@@ -431,10 +465,12 @@
|
|
|
|
if (desc.refCount().Length() > 0) {
|
|
GlobalRefCountImport(desc.refCount()[0].ClonePlatformHandle().release());
|
|
}
|
|
|
|
+ LOGDMABUF((" imported size %d x %d format %x planes %d", mWidth, mHeight,
|
|
+ mDrmFormats[0], mBufferPlaneCount));
|
|
return true;
|
|
}
|
|
|
|
bool DMABufSurfaceRGBA::Create(const SurfaceDescriptor& aDesc) {
|
|
return ImportSurfaceDescriptor(aDesc);
|
|
@@ -460,11 +496,11 @@
|
|
return false;
|
|
}
|
|
|
|
width.AppendElement(mWidth);
|
|
height.AppendElement(mHeight);
|
|
- format.AppendElement(mGmbFormat->mFormat);
|
|
+ format.AppendElement(mDrmFormats[0]);
|
|
modifiers.AppendElement(mBufferModifiers[0]);
|
|
for (int i = 0; i < mBufferPlaneCount; i++) {
|
|
fds.AppendElement(ipc::FileDescriptor(mDmabufFds[i]));
|
|
strides.AppendElement(mStrides[i]);
|
|
offsets.AppendElement(mOffsets[i]);
|
|
@@ -486,23 +522,20 @@
|
|
fenceFDs, mUID, refCountFDs);
|
|
return true;
|
|
}
|
|
|
|
bool DMABufSurfaceRGBA::CreateTexture(GLContext* aGLContext, int aPlane) {
|
|
+ LOGDMABUF(("DMABufSurfaceRGBA::CreateTexture() UID %d\n", mUID));
|
|
MOZ_ASSERT(!mEGLImage && !mTexture, "EGLImage is already created!");
|
|
|
|
nsTArray<EGLint> attribs;
|
|
attribs.AppendElement(LOCAL_EGL_WIDTH);
|
|
attribs.AppendElement(mWidth);
|
|
attribs.AppendElement(LOCAL_EGL_HEIGHT);
|
|
attribs.AppendElement(mHeight);
|
|
attribs.AppendElement(LOCAL_EGL_LINUX_DRM_FOURCC_EXT);
|
|
- if (mGmbFormat) {
|
|
- attribs.AppendElement(mGmbFormat->mFormat);
|
|
- } else {
|
|
- attribs.AppendElement(mDrmFormats[0]);
|
|
- }
|
|
+ attribs.AppendElement(mDrmFormats[0]);
|
|
#define ADD_PLANE_ATTRIBS(plane_idx) \
|
|
{ \
|
|
attribs.AppendElement(LOCAL_EGL_DMA_BUF_PLANE##plane_idx##_FD_EXT); \
|
|
attribs.AppendElement(mDmabufFds[plane_idx]); \
|
|
attribs.AppendElement(LOCAL_EGL_DMA_BUF_PLANE##plane_idx##_OFFSET_EXT); \
|
|
@@ -560,10 +593,11 @@
|
|
|
|
return true;
|
|
}
|
|
|
|
void DMABufSurfaceRGBA::ReleaseTextures() {
|
|
+ LOGDMABUF(("DMABufSurfaceRGBA::ReleaseTextures() UID %d\n", mUID));
|
|
FenceDelete();
|
|
|
|
if (!mTexture) {
|
|
return;
|
|
}
|
|
@@ -618,11 +652,11 @@
|
|
zwp_linux_buffer_params_v1_add(params, mDmabufFds[0], 0, mOffsets[0],
|
|
mStrides[0], mBufferModifiers[0] >> 32,
|
|
mBufferModifiers[0] & 0xffffffff);
|
|
|
|
mWlBuffer = zwp_linux_buffer_params_v1_create_immed(
|
|
- params, GetWidth(), GetHeight(), mGmbFormat->mFormat, 0);
|
|
+ params, GetWidth(), GetHeight(), mDrmFormats[0], 0);
|
|
|
|
CloseFileDescriptors(lockFD);
|
|
|
|
return mWlBuffer != nullptr;
|
|
}
|
|
@@ -806,10 +840,20 @@
|
|
return nullptr;
|
|
}
|
|
return surf.forget();
|
|
}
|
|
|
|
+already_AddRefed<DMABufSurface> DMABufSurfaceRGBA::CreateDMABufSurface(
|
|
+ mozilla::gl::GLContext* aGLContext, const EGLImageKHR aEGLImage, int aWidth,
|
|
+ int aHeight) {
|
|
+ RefPtr<DMABufSurfaceRGBA> surf = new DMABufSurfaceRGBA();
|
|
+ if (!surf->Create(aGLContext, aEGLImage, aWidth, aHeight)) {
|
|
+ return nullptr;
|
|
+ }
|
|
+ return surf.forget();
|
|
+}
|
|
+
|
|
already_AddRefed<DMABufSurfaceYUV> DMABufSurfaceYUV::CreateYUVSurface(
|
|
const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight) {
|
|
RefPtr<DMABufSurfaceYUV> surf = new DMABufSurfaceYUV();
|
|
LOGDMABUF(("DMABufSurfaceYUV::CreateYUVSurface() UID %d from desc\n",
|
|
surf->GetUID()));
|
|
|