1 //
2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "libANGLE/renderer/gl/egl/ContextEGL.h"
8 
9 #include "libANGLE/renderer/gl/FramebufferGL.h"
10 #include "libANGLE/renderer/gl/StateManagerGL.h"
11 
12 namespace rx
13 {
14 
ContextEGL(const gl::State & state,gl::ErrorSet * errorSet,const std::shared_ptr<RendererEGL> & renderer,RobustnessVideoMemoryPurgeStatus robustnessVideoMemoryPurgeStatus)15 ContextEGL::ContextEGL(const gl::State &state,
16                        gl::ErrorSet *errorSet,
17                        const std::shared_ptr<RendererEGL> &renderer,
18                        RobustnessVideoMemoryPurgeStatus robustnessVideoMemoryPurgeStatus)
19     : ContextGL(state, errorSet, renderer, robustnessVideoMemoryPurgeStatus), mRendererEGL(renderer)
20 {}
21 
~ContextEGL()22 ContextEGL::~ContextEGL() {}
23 
onMakeCurrent(const gl::Context * context)24 angle::Result ContextEGL::onMakeCurrent(const gl::Context *context)
25 {
26     // If this context is wrapping an external native context, save state from
27     // that external context when first making this context current.
28     if (!mIsCurrent && context->isExternal())
29     {
30         // TODO: The following is done if saveAndRestoreState() until chrome is switched to using
31         // glAcquireExternalContextANGLE and drops usage of EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE.
32         // After that, this code can be removed.  http://anglebug.com/5509
33         if (context->saveAndRestoreState())
34         {
35             acquireExternalContext(context);
36         }
37     }
38     mIsCurrent = true;
39     return ContextGL::onMakeCurrent(context);
40 }
41 
acquireExternalContext(const gl::Context * context)42 void ContextEGL::acquireExternalContext(const gl::Context *context)
43 {
44     ASSERT(context->isExternal());
45 
46     if (!mExtState)
47     {
48         mExtState        = std::make_unique<ExternalContextState>();
49         const auto &caps = getCaps();
50         mExtState->textureBindings.resize(static_cast<size_t>(caps.maxCombinedTextureImageUnits));
51     }
52 
53     getStateManager()->syncFromNativeContext(getNativeExtensions(), mExtState.get());
54 
55     // Use current FBO as the default framebuffer when the external context is current.
56     // First save the current ID of the default framebuffer to restore in
57     // onUnMakeCurrent().
58     gl::Framebuffer *framebuffer = mState.getDefaultFramebuffer();
59     auto framebufferGL           = GetImplAs<FramebufferGL>(framebuffer);
60     mPrevDefaultFramebufferID    = framebufferGL->getFramebufferID();
61     framebufferGL->updateDefaultFramebufferID(mExtState->framebufferBinding);
62 }
63 
onUnMakeCurrent(const gl::Context * context)64 angle::Result ContextEGL::onUnMakeCurrent(const gl::Context *context)
65 {
66     mIsCurrent = false;
67 
68     if (context->isExternal() && context->saveAndRestoreState())
69     {
70         releaseExternalContext(context);
71     }
72 
73     return ContextGL::onUnMakeCurrent(context);
74 }
75 
releaseExternalContext(const gl::Context * context)76 void ContextEGL::releaseExternalContext(const gl::Context *context)
77 {
78     ASSERT(context->isExternal());
79     ASSERT(mExtState);
80 
81     getStateManager()->restoreNativeContext(getNativeExtensions(), mExtState.get());
82 
83     // If the default framebuffer exists, update its ID (note that there can
84     // be multiple consecutive onUnMakeCurrent() calls in destruction, and
85     // the default FBO will have been unset by the first one).
86     gl::Framebuffer *framebuffer = mState.getDefaultFramebuffer();
87     if (framebuffer)
88     {
89         auto framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
90         framebufferGL->updateDefaultFramebufferID(mPrevDefaultFramebufferID);
91     }
92 }
93 
getContext() const94 EGLContext ContextEGL::getContext() const
95 {
96     return mRendererEGL->getContext();
97 }
98 
99 }  // namespace rx
100