// // Copyright 2018 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // #include "libANGLE/renderer/gl/egl/ContextEGL.h" #include "libANGLE/renderer/gl/FramebufferGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h" namespace rx { ContextEGL::ContextEGL(const gl::State &state, gl::ErrorSet *errorSet, const std::shared_ptr &renderer, RobustnessVideoMemoryPurgeStatus robustnessVideoMemoryPurgeStatus) : ContextGL(state, errorSet, renderer, robustnessVideoMemoryPurgeStatus), mRendererEGL(renderer) {} ContextEGL::~ContextEGL() {} angle::Result ContextEGL::onMakeCurrent(const gl::Context *context) { // If this context is wrapping an external native context, save state from // that external context when first making this context current. if (!mIsCurrent && context->isExternal()) { // TODO: The following is done if saveAndRestoreState() until chrome is switched to using // glAcquireExternalContextANGLE and drops usage of EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE. // After that, this code can be removed. http://anglebug.com/5509 if (context->saveAndRestoreState()) { acquireExternalContext(context); } } mIsCurrent = true; return ContextGL::onMakeCurrent(context); } void ContextEGL::acquireExternalContext(const gl::Context *context) { ASSERT(context->isExternal()); if (!mExtState) { mExtState = std::make_unique(); const auto &caps = getCaps(); mExtState->textureBindings.resize(static_cast(caps.maxCombinedTextureImageUnits)); } getStateManager()->syncFromNativeContext(getNativeExtensions(), mExtState.get()); // Use current FBO as the default framebuffer when the external context is current. // First save the current ID of the default framebuffer to restore in // onUnMakeCurrent(). gl::Framebuffer *framebuffer = mState.getDefaultFramebuffer(); auto framebufferGL = GetImplAs(framebuffer); mPrevDefaultFramebufferID = framebufferGL->getFramebufferID(); framebufferGL->updateDefaultFramebufferID(mExtState->framebufferBinding); } angle::Result ContextEGL::onUnMakeCurrent(const gl::Context *context) { mIsCurrent = false; if (context->isExternal() && context->saveAndRestoreState()) { releaseExternalContext(context); } return ContextGL::onUnMakeCurrent(context); } void ContextEGL::releaseExternalContext(const gl::Context *context) { ASSERT(context->isExternal()); ASSERT(mExtState); getStateManager()->restoreNativeContext(getNativeExtensions(), mExtState.get()); // If the default framebuffer exists, update its ID (note that there can // be multiple consecutive onUnMakeCurrent() calls in destruction, and // the default FBO will have been unset by the first one). gl::Framebuffer *framebuffer = mState.getDefaultFramebuffer(); if (framebuffer) { auto framebufferGL = GetImplAs(framebuffer); framebufferGL->updateDefaultFramebufferID(mPrevDefaultFramebufferID); } } EGLContext ContextEGL::getContext() const { return mRendererEGL->getContext(); } } // namespace rx