Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #include "EGLUtils.h"
6 :
7 : #include "GLContextEGL.h"
8 :
9 : namespace mozilla {
10 : namespace gl {
11 :
12 : bool
13 0 : DoesEGLContextSupportSharingWithEGLImage(GLContext* gl)
14 : {
15 0 : return sEGLLibrary.HasKHRImageBase() &&
16 0 : sEGLLibrary.HasKHRImageTexture2D() &&
17 0 : gl->IsExtensionSupported(GLContext::OES_EGL_image);
18 : }
19 :
20 : EGLImage
21 0 : CreateEGLImage(GLContext* gl, GLuint tex)
22 : {
23 0 : MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));
24 :
25 0 : EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
26 0 : EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
27 0 : EGLImage image = sEGLLibrary.fCreateImage(EGL_DISPLAY(),
28 : eglContext,
29 : LOCAL_EGL_GL_TEXTURE_2D,
30 : clientBuffer,
31 0 : nullptr);
32 0 : return image;
33 : }
34 :
35 : ////////////////////////////////////////////////////////////////////////
36 : // EGLImageWrapper
37 :
38 : /*static*/ EGLImageWrapper*
39 0 : EGLImageWrapper::Create(GLContext* gl, GLuint tex)
40 : {
41 0 : MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));
42 :
43 0 : GLLibraryEGL& library = sEGLLibrary;
44 0 : EGLDisplay display = EGL_DISPLAY();
45 0 : EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
46 0 : EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
47 : EGLImage image = library.fCreateImage(display,
48 : eglContext,
49 : LOCAL_EGL_GL_TEXTURE_2D,
50 : clientBuffer,
51 0 : nullptr);
52 0 : if (!image) {
53 : #ifdef DEBUG
54 0 : printf_stderr("Could not create EGL images: ERROR (0x%04x)\n",
55 0 : sEGLLibrary.fGetError());
56 : #endif
57 0 : return nullptr;
58 : }
59 :
60 0 : return new EGLImageWrapper(library, display, image);
61 : }
62 :
63 0 : EGLImageWrapper::~EGLImageWrapper()
64 : {
65 0 : mLibrary.fDestroyImage(mDisplay, mImage);
66 0 : }
67 :
68 : bool
69 0 : EGLImageWrapper::FenceSync(GLContext* gl)
70 : {
71 0 : MOZ_ASSERT(!mSync);
72 :
73 0 : if (mLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync)) {
74 0 : mSync = mLibrary.fCreateSync(mDisplay,
75 : LOCAL_EGL_SYNC_FENCE,
76 : nullptr);
77 : // We need to flush to make sure the sync object enters the command stream;
78 : // we can't use EGL_SYNC_FLUSH_COMMANDS_BIT at wait time, because the wait
79 : // happens on a different thread/context.
80 0 : gl->fFlush();
81 : }
82 :
83 0 : if (!mSync) {
84 : // we failed to create one, so just do a finish
85 0 : gl->fFinish();
86 : }
87 :
88 0 : return true;
89 : }
90 :
91 : bool
92 0 : EGLImageWrapper::ClientWaitSync()
93 : {
94 0 : if (!mSync) {
95 : // if we have no sync object, then we did a Finish() earlier
96 0 : return true;
97 : }
98 :
99 : // wait at most 1 second; this should really be never/rarely hit
100 0 : const uint64_t ns_per_ms = 1000 * 1000;
101 0 : EGLTime timeout = 1000 * ns_per_ms;
102 :
103 0 : EGLint result = mLibrary.fClientWaitSync(mDisplay,
104 : mSync,
105 : 0,
106 0 : timeout);
107 0 : mLibrary.fDestroySync(mDisplay, mSync);
108 0 : mSync = nullptr;
109 :
110 0 : return result == LOCAL_EGL_CONDITION_SATISFIED;
111 : }
112 :
113 : } // namespace gl
114 : } // namespace mozilla
|