1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "GLcommon/GLBackgroundLoader.h"
18
19 #include "GLcommon/GLEScontext.h"
20 #include "GLcommon/SaveableTexture.h"
21 #include "aemu/base/system/System.h"
22
23 #include <EGL/eglext.h>
24 #include <GLES2/gl2.h>
25
26 EGLContext s_context = EGL_NO_CONTEXT;
27 EGLSurface s_surface = EGL_NO_SURFACE;
28
main()29 intptr_t GLBackgroundLoader::main() {
30 #if SNAPSHOT_PROFILE > 1
31 const auto start = get_uptime_ms();
32 printf("Starting GL background loading at %" PRIu64 " ms\n", start);
33 #endif
34
35 if (s_context == EGL_NO_CONTEXT) {
36 if (!m_eglIface.createAndBindAuxiliaryContext(&s_context, &s_surface)) {
37 return 0;
38 }
39 } else {
40 // In unit tests, we might have torn down EGL. Check for stale
41 // context and surface, and recreate them if that happened.
42 if (!m_eglIface.bindAuxiliaryContext(s_context, s_surface)) {
43 printf("GLBackgroundLoader::%s auxiliary context gone, create a new one\n", __func__);
44 m_eglIface.createAndBindAuxiliaryContext(&s_context, &s_surface);
45 }
46 }
47
48 for (const auto& it : m_textureMap) {
49 if (m_interrupted.load(std::memory_order_relaxed)) break;
50
51 // Acquire the texture loader for each load; bail
52 // in case something else happened to interrupt loading.
53 auto ptr = m_textureLoaderWPtr.lock();
54 if (!ptr) {
55 break;
56 }
57
58 const SaveableTexturePtr& saveable = it.second;
59 if (saveable) {
60 m_glesIface.restoreTexture(saveable.get());
61 // allow other threads to run for a while
62 ptr.reset();
63 android::base::sleepMs(
64 m_loadDelayMs.load(std::memory_order_relaxed));
65 }
66 }
67
68 m_textureMap.clear();
69
70 m_eglIface.unbindAuxiliaryContext();
71
72 #if SNAPSHOT_PROFILE > 1
73 const auto end = get_uptime_ms();
74 printf("Finished GL background loading at %" PRIu64 " ms (%d ms total)\n",
75 end, int(end - start));
76 #endif
77
78 return 0;
79 }
80
wait(intptr_t * exitStatus)81 bool GLBackgroundLoader::wait(intptr_t* exitStatus) {
82 m_loadDelayMs.store(0, std::memory_order_relaxed);
83 return Thread::wait();
84 }
85
interrupt()86 void GLBackgroundLoader::interrupt() {
87 m_interrupted.store(true, std::memory_order_relaxed);
88 }
89