| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #include "EmulatedEglContext.h" |
| |
| #include <assert.h> |
| |
| #include "GLESVersionDetector.h" |
| #include "OpenGLESDispatch/EGLDispatch.h" |
| #include "OpenGLESDispatch/GLESv1Dispatch.h" |
| #include "aemu/base/containers/SmallVector.h" |
| #include "host-common/feature_control.h" |
| #include "host-common/logging.h" |
| #include "host-common/misc.h" |
| |
| namespace gfxstream { |
| namespace gl { |
| |
| std::unique_ptr<EmulatedEglContext> EmulatedEglContext::create( |
| EGLDisplay display, |
| EGLConfig config, |
| EGLContext sharedContext, |
| HandleType hndl, |
| GLESApi version) { |
| return createImpl(display, config, sharedContext, hndl, version, nullptr); |
| } |
| |
| std::unique_ptr<EmulatedEglContext> EmulatedEglContext::createImpl( |
| EGLDisplay display, |
| EGLConfig config, |
| EGLContext sharedContext, |
| HandleType hndl, |
| GLESApi version, |
| android::base::Stream* stream) { |
| GLESApi clientVersion = version; |
| int majorVersion = clientVersion; |
| int minorVersion = 0; |
| |
| if (version == GLESApi_3_0) { |
| majorVersion = 3; |
| minorVersion = 0; |
| } else if (version == GLESApi_3_1) { |
| majorVersion = 3; |
| minorVersion = 1; |
| } |
| |
| android::base::SmallFixedVector<EGLint, 7> contextAttribs = { |
| EGL_CONTEXT_CLIENT_VERSION, majorVersion, |
| EGL_CONTEXT_MINOR_VERSION_KHR, minorVersion, |
| }; |
| |
| if (shouldEnableCoreProfile()) { |
| contextAttribs.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR); |
| contextAttribs.push_back(EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR); |
| } |
| |
| contextAttribs.push_back(EGL_NONE); |
| |
| EGLContext context; |
| if (stream && s_egl.eglLoadContext) { |
| context = s_egl.eglLoadContext(display, &contextAttribs[0], stream); |
| } else { |
| context = s_egl.eglCreateContext( |
| display, config, sharedContext, &contextAttribs[0]); |
| } |
| if (context == EGL_NO_CONTEXT) { |
| ERR("Failed to create context (EGL_NO_CONTEXT result)"); |
| return nullptr; |
| } |
| |
| return std::unique_ptr<EmulatedEglContext>( |
| new EmulatedEglContext(display, context, hndl, clientVersion, nullptr)); |
| } |
| |
| EmulatedEglContext::EmulatedEglContext(EGLDisplay display, |
| EGLContext context, |
| HandleType hndl, |
| GLESApi version, |
| void* emulatedGLES1Context) : |
| mDisplay(display), |
| mContext(context), |
| mHndl(hndl), |
| mVersion(version), |
| mContextData() { } |
| |
| EmulatedEglContext::~EmulatedEglContext() { |
| if (mContext != EGL_NO_CONTEXT) { |
| s_egl.eglDestroyContext(mDisplay, mContext); |
| } |
| } |
| |
| void EmulatedEglContext::onSave(android::base::Stream* stream) { |
| stream->putBe32(mHndl); |
| stream->putBe32(static_cast<uint32_t>(mVersion)); |
| assert(s_egl.eglCreateContext); |
| if (s_egl.eglSaveContext) { |
| s_egl.eglSaveContext(mDisplay, mContext, static_cast<EGLStreamKHR>(stream)); |
| } |
| } |
| |
| std::unique_ptr<EmulatedEglContext> EmulatedEglContext::onLoad( |
| android::base::Stream* stream, |
| EGLDisplay display) { |
| HandleType hndl = static_cast<HandleType>(stream->getBe32()); |
| GLESApi version = static_cast<GLESApi>(stream->getBe32()); |
| |
| return createImpl(display, (EGLConfig)0, EGL_NO_CONTEXT, hndl, version, |
| stream); |
| } |
| |
| GLESApi EmulatedEglContext::clientVersion() const { |
| return mVersion; |
| } |
| |
| } // namespace gl |
| } // namespace gfxstream |