1 // Copyright 2022 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expresso or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "RenderThreadInfoGl.h"
16
17 #include <unordered_set>
18
19 #include "FrameBuffer.h"
20 #include "OpenGLESDispatch/EGLDispatch.h"
21 #include "OpenGLESDispatch/GLESv1Dispatch.h"
22 #include "OpenGLESDispatch/GLESv2Dispatch.h"
23 #include "aemu/base/synchronization/Lock.h"
24 #include "aemu/base/containers/Lookup.h"
25 #include "aemu/base/files/StreamSerializing.h"
26 #include "host-common/GfxstreamFatalError.h"
27
28 namespace gfxstream {
29 namespace gl {
30
31 using android::base::AutoLock;
32 using android::base::Lock;
33 using android::base::Stream;
34 using emugl::ABORT_REASON_OTHER;
35 using emugl::FatalError;
36
37 static thread_local RenderThreadInfoGl* tlThreadInfo = nullptr;
38
RenderThreadInfoGl()39 RenderThreadInfoGl::RenderThreadInfoGl() {
40 m_glDec.initGL(gles1_dispatch_get_proc_func, nullptr);
41 m_gl2Dec.initGL(gles2_dispatch_get_proc_func, nullptr);
42
43 if (tlThreadInfo != nullptr) {
44 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
45 << "Attempted to set thread local GL render thread info twice.";
46 }
47 tlThreadInfo = this;
48 }
49
~RenderThreadInfoGl()50 RenderThreadInfoGl::~RenderThreadInfoGl() {
51 tlThreadInfo = nullptr;
52 }
53
get()54 RenderThreadInfoGl* RenderThreadInfoGl::get() { return tlThreadInfo; }
55
onSave(Stream * stream)56 void RenderThreadInfoGl::onSave(Stream* stream) {
57 if (currContext) {
58 stream->putBe32(currContext->getHndl());
59 } else {
60 stream->putBe32(0);
61 }
62 if (currDrawSurf) {
63 stream->putBe32(currDrawSurf->getHndl());
64 } else {
65 stream->putBe32(0);
66 }
67 if (currReadSurf) {
68 stream->putBe32(currReadSurf->getHndl());
69 } else {
70 stream->putBe32(0);
71 }
72
73 saveCollection(stream, m_contextSet, [](Stream* stream, HandleType val) {
74 stream->putBe32(val);
75 });
76 saveCollection(stream, m_windowSet, [](Stream* stream, HandleType val) {
77 stream->putBe32(val);
78 });
79
80 stream->putBe64(m_puid);
81
82 // No need to associate render threads with sync threads
83 // if there is a global sync thread. This is only needed
84 // to maintain backward compatibility with snapshot file format.
85 // (Used to be: stream->putBe64(syncThreadAlias))
86 stream->putBe64(0);
87 }
88
onLoad(Stream * stream)89 bool RenderThreadInfoGl::onLoad(Stream* stream) {
90 FrameBuffer* fb = FrameBuffer::getFB();
91 assert(fb);
92 HandleType ctxHndl = stream->getBe32();
93 HandleType drawSurf = stream->getBe32();
94 HandleType readSurf = stream->getBe32();
95 currContextHandleFromLoad = ctxHndl;
96 currDrawSurfHandleFromLoad = drawSurf;
97 currReadSurfHandleFromLoad = readSurf;
98
99 fb->lock();
100 currContext = fb->getContext_locked(ctxHndl);
101 currDrawSurf = fb->getWindowSurface_locked(drawSurf);
102 currReadSurf = fb->getWindowSurface_locked(readSurf);
103 fb->unlock();
104
105 loadCollection(stream, &m_contextSet, [](Stream* stream) {
106 return stream->getBe32();
107 });
108 loadCollection(stream, &m_windowSet, [](Stream* stream) {
109 return stream->getBe32();
110 });
111
112 m_puid = stream->getBe64();
113
114 // (Used to be: syncThreadAlias = stream->getBe64())
115 stream->getBe64();
116
117 return true;
118 }
119
postLoadRefreshCurrentContextSurfacePtrs()120 void RenderThreadInfoGl::postLoadRefreshCurrentContextSurfacePtrs() {
121 FrameBuffer* fb = FrameBuffer::getFB();
122 assert(fb);
123
124 fb->lock();
125 currContext = fb->getContext_locked(currContextHandleFromLoad);
126 currDrawSurf = fb->getWindowSurface_locked(currDrawSurfHandleFromLoad);
127 currReadSurf = fb->getWindowSurface_locked(currReadSurfHandleFromLoad);
128 fb->unlock();
129
130 const HandleType ctx = currContext ? currContext->getHndl() : 0;
131 const HandleType draw = currDrawSurf ? currDrawSurf->getHndl() : 0;
132 const HandleType read = currReadSurf ? currReadSurf->getHndl() : 0;
133 fb->bindContext(ctx, draw, read);
134 }
135
136 } // namespace gl
137 } // namespace gfxstream