DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Header

Mercurial (409f3966645a)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
/* 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 "EGLUtils.h"

#include "GLContextEGL.h"
#include "GLLibraryEGL.h"

namespace mozilla {
namespace gl {

bool
DoesEGLContextSupportSharingWithEGLImage(GLContext* gl)
{
    auto* egl = gl::GLLibraryEGL::Get();

    return egl->HasKHRImageBase() &&
           egl->HasKHRImageTexture2D() &&
           gl->IsExtensionSupported(GLContext::OES_EGL_image);
}

EGLImage
CreateEGLImage(GLContext* gl, GLuint tex)
{
    MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));

    auto* egl = gl::GLLibraryEGL::Get();

    EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
    EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
    EGLImage image = egl->fCreateImage(EGL_DISPLAY(),
                                       eglContext,
                                       LOCAL_EGL_GL_TEXTURE_2D,
                                       clientBuffer,
                                       nullptr);
    return image;
}

////////////////////////////////////////////////////////////////////////
// EGLImageWrapper

/*static*/ EGLImageWrapper*
EGLImageWrapper::Create(GLContext* gl, GLuint tex)
{
    MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));

    auto* egl = gl::GLLibraryEGL::Get();

    EGLDisplay display = EGL_DISPLAY();
    EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
    EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
    EGLImage image = egl->fCreateImage(display,
                                       eglContext,
                                       LOCAL_EGL_GL_TEXTURE_2D,
                                       clientBuffer,
                                       nullptr);
    if (!image) {
#ifdef DEBUG
        printf_stderr("Could not create EGL images: ERROR (0x%04x)\n",
                      egl->fGetError());
#endif
        return nullptr;
    }

    return new EGLImageWrapper(egl, display, image);
}

EGLImageWrapper::EGLImageWrapper(GLLibraryEGL* library,
                                 EGLDisplay display,
                                 EGLImage image)
    : mLibrary(library)
    , mDisplay(display)
    , mImage(image)
    , mSync(0)
{
    MOZ_ASSERT(mImage);
}

EGLImageWrapper::~EGLImageWrapper()
{
    mLibrary->fDestroyImage(mDisplay, mImage);
}

bool
EGLImageWrapper::FenceSync(GLContext* gl)
{
    MOZ_ASSERT(!mSync);

    if (mLibrary->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync)) {
        mSync = mLibrary->fCreateSync(mDisplay,
                                      LOCAL_EGL_SYNC_FENCE,
                                      nullptr);
        // We need to flush to make sure the sync object enters the command stream;
        // we can't use EGL_SYNC_FLUSH_COMMANDS_BIT at wait time, because the wait
        // happens on a different thread/context.
        gl->fFlush();
    }

    if (!mSync) {
        // we failed to create one, so just do a finish
        gl->fFinish();
    }

    return true;
}

bool
EGLImageWrapper::ClientWaitSync()
{
    if (!mSync) {
        // if we have no sync object, then we did a Finish() earlier
        return true;
    }

    // wait at most 1 second; this should really be never/rarely hit
    const uint64_t ns_per_ms = 1000 * 1000;
    EGLTime timeout = 1000 * ns_per_ms;

    EGLint result = mLibrary->fClientWaitSync(mDisplay,
                                              mSync,
                                              0,
                                              timeout);
    mLibrary->fDestroySync(mDisplay, mSync);
    mSync = nullptr;

    return result == LOCAL_EGL_CONDITION_SATISFIED;
}

} // namespace gl
} // namespace mozilla