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