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