blob: 70da25b6af18a8582b36d9cf6f7cf7e2519c7803 [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
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
29namespace android {
30namespace companion {
31namespace virtualcamera {
32
Jan Sebechlebsky288900f2024-05-24 14:47:54 +020033EglDisplayContext::EglDisplayContext(std::shared_ptr<ANativeWindow> nativeWindow)
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010034 : mEglDisplay(EGL_NO_DISPLAY),
Jan Sebechlebsky288900f2024-05-24 14:47:54 +020035 mEglSurface(EGL_NO_SURFACE),
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010036 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[] = {
Jan Sebechlebsky288900f2024-05-24 14:47:54 +020056 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,
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010060 // 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
Jan Sebechlebsky288900f2024-05-24 14:47:54 +020078 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
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010086 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
95EglDisplayContext::~EglDisplayContext() {
Jan Sebechlebsky4f74d392024-06-13 14:51:54 +020096 eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
Jan Sebechlebsky288900f2024-05-24 14:47:54 +020097 if (mEglSurface != EGL_NO_SURFACE) {
98 eglDestroySurface(mEglDisplay, mEglSurface);
99 }
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100100 if (mEglContext != EGL_NO_CONTEXT) {
101 eglDestroyContext(mEglDisplay, mEglContext);
102 }
Jan Sebechlebsky4f74d392024-06-13 14:51:54 +0200103 if (mEglDisplay != EGL_NO_DISPLAY) {
104 eglTerminate(mEglDisplay);
105 }
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100106}
107
108EGLDisplay EglDisplayContext::getEglDisplay() const {
109 return mEglDisplay;
110}
111
112bool EglDisplayContext::isInitialized() const {
113 return mEglContext != EGL_NO_CONTEXT && mEglDisplay != EGL_NO_DISPLAY;
114}
115
Jan Sebechlebsky288900f2024-05-24 14:47:54 +0200116void EglDisplayContext::swapBuffers() const {
117 if (mEglSurface != EGL_NO_SURFACE) {
118 eglSwapBuffers(mEglDisplay, mEglSurface);
119 }
120}
121
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100122bool EglDisplayContext::makeCurrent() {
Jan Sebechlebsky288900f2024-05-24 14:47:54 +0200123 if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100124 ALOGE("eglMakeCurrent failed: %#x", eglGetError());
125 return false;
126 }
127 return true;
128}
129
130} // namespace virtualcamera
131} // namespace companion
132} // namespace android