|
Packit |
f0b94e |
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit |
f0b94e |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit |
f0b94e |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#include "EGLUtils.h"
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#include "GLContextEGL.h"
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
namespace mozilla {
|
|
Packit |
f0b94e |
namespace gl {
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool DoesEGLContextSupportSharingWithEGLImage(GLContext* gl) {
|
|
Packit |
f0b94e |
return sEGLLibrary.HasKHRImageBase() && sEGLLibrary.HasKHRImageTexture2D() &&
|
|
Packit |
f0b94e |
gl->IsExtensionSupported(GLContext::OES_EGL_image);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
EGLImage CreateEGLImage(GLContext* gl, GLuint tex) {
|
|
Packit |
f0b94e |
MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
|
|
Packit |
f0b94e |
EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
|
|
Packit |
f0b94e |
EGLImage image =
|
|
Packit |
f0b94e |
sEGLLibrary.fCreateImage(EGL_DISPLAY(), eglContext,
|
|
Packit |
f0b94e |
LOCAL_EGL_GL_TEXTURE_2D, clientBuffer, nullptr);
|
|
Packit |
f0b94e |
return image;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
////////////////////////////////////////////////////////////////////////
|
|
Packit |
f0b94e |
// EGLImageWrapper
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*static*/ EGLImageWrapper* EGLImageWrapper::Create(GLContext* gl, GLuint tex) {
|
|
Packit |
f0b94e |
MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
GLLibraryEGL& library = sEGLLibrary;
|
|
Packit |
f0b94e |
EGLDisplay display = EGL_DISPLAY();
|
|
Packit |
f0b94e |
EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
|
|
Packit |
f0b94e |
EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
|
|
Packit |
f0b94e |
EGLImage image = library.fCreateImage(
|
|
Packit |
f0b94e |
display, eglContext, LOCAL_EGL_GL_TEXTURE_2D, clientBuffer, nullptr);
|
|
Packit |
f0b94e |
if (!image) {
|
|
Packit |
f0b94e |
#ifdef DEBUG
|
|
Packit |
f0b94e |
printf_stderr("Could not create EGL images: ERROR (0x%04x)\n",
|
|
Packit |
f0b94e |
sEGLLibrary.fGetError());
|
|
Packit |
f0b94e |
#endif
|
|
Packit |
f0b94e |
return nullptr;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return new EGLImageWrapper(library, display, image);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
EGLImageWrapper::~EGLImageWrapper() {
|
|
Packit |
f0b94e |
mLibrary.fDestroyImage(mDisplay, mImage);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool EGLImageWrapper::FenceSync(GLContext* gl) {
|
|
Packit |
f0b94e |
MOZ_ASSERT(!mSync);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (mLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync)) {
|
|
Packit |
f0b94e |
mSync = mLibrary.fCreateSync(mDisplay, LOCAL_EGL_SYNC_FENCE, nullptr);
|
|
Packit |
f0b94e |
// We need to flush to make sure the sync object enters the command stream;
|
|
Packit |
f0b94e |
// we can't use EGL_SYNC_FLUSH_COMMANDS_BIT at wait time, because the wait
|
|
Packit |
f0b94e |
// happens on a different thread/context.
|
|
Packit |
f0b94e |
gl->fFlush();
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (!mSync) {
|
|
Packit |
f0b94e |
// we failed to create one, so just do a finish
|
|
Packit |
f0b94e |
gl->fFinish();
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return true;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool EGLImageWrapper::ClientWaitSync() {
|
|
Packit |
f0b94e |
if (!mSync) {
|
|
Packit |
f0b94e |
// if we have no sync object, then we did a Finish() earlier
|
|
Packit |
f0b94e |
return true;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// wait at most 1 second; this should really be never/rarely hit
|
|
Packit |
f0b94e |
const uint64_t ns_per_ms = 1000 * 1000;
|
|
Packit |
f0b94e |
EGLTime timeout = 1000 * ns_per_ms;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
EGLint result = mLibrary.fClientWaitSync(mDisplay, mSync, 0, timeout);
|
|
Packit |
f0b94e |
mLibrary.fDestroySync(mDisplay, mSync);
|
|
Packit |
f0b94e |
mSync = nullptr;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return result == LOCAL_EGL_CONDITION_SATISFIED;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
} // namespace gl
|
|
Packit |
f0b94e |
} // namespace mozilla
|