1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // #define LOG_NDEBUG 0
18 #define LOG_TAG "EglDisplayContext"
19 #define EGL_EGLEXT_PROTOTYPES
20 #define GL_GLEXT_PROTOTYPES
21
22 #include "EglDisplayContext.h"
23
24 #include "EGL/egl.h"
25 #include "EglDisplayContext.h"
26 #include "EglFramebuffer.h"
27 #include "log/log.h"
28
29 namespace android {
30 namespace companion {
31 namespace virtualcamera {
32
EglDisplayContext(std::shared_ptr<ANativeWindow> nativeWindow)33 EglDisplayContext::EglDisplayContext(std::shared_ptr<ANativeWindow> nativeWindow)
34 : mEglDisplay(EGL_NO_DISPLAY),
35 mEglSurface(EGL_NO_SURFACE),
36 mEglContext(EGL_NO_CONTEXT),
37 mEglConfig(nullptr) {
38 EGLBoolean result;
39
40 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
41 if (mEglDisplay == EGL_NO_DISPLAY) {
42 ALOGE("eglGetDisplay failed: %#x", eglGetError());
43 return;
44 }
45
46 EGLint majorVersion, minorVersion;
47 result = eglInitialize(mEglDisplay, &majorVersion, &minorVersion);
48 if (result != EGL_TRUE) {
49 ALOGE("eglInitialize failed: %#x", eglGetError());
50 return;
51 }
52 ALOGV("Initialized EGL v%d.%d", majorVersion, minorVersion);
53
54 EGLint numConfigs = 0;
55 EGLint configAttribs[] = {
56 EGL_SURFACE_TYPE,
57 nativeWindow == nullptr ? EGL_PBUFFER_BIT : EGL_WINDOW_BIT,
58 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE,
59 8, EGL_BLUE_SIZE, 8,
60 // no alpha
61 EGL_NONE};
62
63 result =
64 eglChooseConfig(mEglDisplay, configAttribs, &mEglConfig, 1, &numConfigs);
65 if (result != EGL_TRUE) {
66 ALOGE("eglChooseConfig error: %#x", eglGetError());
67 return;
68 }
69
70 EGLint contextAttribs[] = {EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_NONE};
71 mEglContext =
72 eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, contextAttribs);
73 if (mEglContext == EGL_NO_CONTEXT) {
74 ALOGE("eglCreateContext error: %#x", eglGetError());
75 return;
76 }
77
78 if (nativeWindow != nullptr) {
79 mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig,
80 nativeWindow.get(), NULL);
81 if (mEglSurface == EGL_NO_SURFACE) {
82 ALOGE("eglCreateWindowSurface error: %#x", eglGetError());
83 }
84 }
85
86 if (!makeCurrent()) {
87 ALOGE(
88 "Failed to set newly initialized EGLContext and EGLDisplay connection "
89 "as current.");
90 } else {
91 ALOGV("EGL successfully initialized.");
92 }
93 }
94
~EglDisplayContext()95 EglDisplayContext::~EglDisplayContext() {
96 eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
97 if (mEglSurface != EGL_NO_SURFACE) {
98 eglDestroySurface(mEglDisplay, mEglSurface);
99 }
100 if (mEglContext != EGL_NO_CONTEXT) {
101 eglDestroyContext(mEglDisplay, mEglContext);
102 }
103 if (mEglDisplay != EGL_NO_DISPLAY) {
104 eglTerminate(mEglDisplay);
105 }
106 }
107
getEglDisplay() const108 EGLDisplay EglDisplayContext::getEglDisplay() const {
109 return mEglDisplay;
110 }
111
isInitialized() const112 bool EglDisplayContext::isInitialized() const {
113 return mEglContext != EGL_NO_CONTEXT && mEglDisplay != EGL_NO_DISPLAY;
114 }
115
swapBuffers() const116 void EglDisplayContext::swapBuffers() const {
117 if (mEglSurface != EGL_NO_SURFACE) {
118 eglSwapBuffers(mEglDisplay, mEglSurface);
119 }
120 }
121
makeCurrent()122 bool EglDisplayContext::makeCurrent() {
123 if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
124 ALOGE("eglMakeCurrent failed: %#x", eglGetError());
125 return false;
126 }
127 return true;
128 }
129
130 } // namespace virtualcamera
131 } // namespace companion
132 } // namespace android
133