| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "GLcommon/GLBackgroundLoader.h" |
| |
| #include "GLcommon/GLEScontext.h" |
| #include "GLcommon/SaveableTexture.h" |
| #include "aemu/base/system/System.h" |
| |
| #include <EGL/eglext.h> |
| #include <GLES2/gl2.h> |
| |
| EGLContext s_context = EGL_NO_CONTEXT; |
| EGLSurface s_surface = EGL_NO_SURFACE; |
| |
| intptr_t GLBackgroundLoader::main() { |
| #if SNAPSHOT_PROFILE > 1 |
| const auto start = get_uptime_ms(); |
| printf("Starting GL background loading at %" PRIu64 " ms\n", start); |
| #endif |
| |
| if (s_context == EGL_NO_CONTEXT) { |
| if (!m_eglIface.createAndBindAuxiliaryContext(&s_context, &s_surface)) { |
| return 0; |
| } |
| } else { |
| // In unit tests, we might have torn down EGL. Check for stale |
| // context and surface, and recreate them if that happened. |
| if (!m_eglIface.bindAuxiliaryContext(s_context, s_surface)) { |
| printf("GLBackgroundLoader::%s auxiliary context gone, create a new one\n", __func__); |
| m_eglIface.createAndBindAuxiliaryContext(&s_context, &s_surface); |
| } |
| } |
| |
| for (const auto& it : m_textureMap) { |
| if (m_interrupted.load(std::memory_order_relaxed)) break; |
| |
| // Acquire the texture loader for each load; bail |
| // in case something else happened to interrupt loading. |
| auto ptr = m_textureLoaderWPtr.lock(); |
| if (!ptr) { |
| break; |
| } |
| |
| const SaveableTexturePtr& saveable = it.second; |
| if (saveable) { |
| m_glesIface.restoreTexture(saveable.get()); |
| // allow other threads to run for a while |
| ptr.reset(); |
| android::base::sleepMs( |
| m_loadDelayMs.load(std::memory_order_relaxed)); |
| } |
| } |
| |
| m_textureMap.clear(); |
| |
| m_eglIface.unbindAuxiliaryContext(); |
| |
| #if SNAPSHOT_PROFILE > 1 |
| const auto end = get_uptime_ms(); |
| printf("Finished GL background loading at %" PRIu64 " ms (%d ms total)\n", |
| end, int(end - start)); |
| #endif |
| |
| return 0; |
| } |
| |
| bool GLBackgroundLoader::wait(intptr_t* exitStatus) { |
| m_loadDelayMs.store(0, std::memory_order_relaxed); |
| return Thread::wait(); |
| } |
| |
| void GLBackgroundLoader::interrupt() { |
| m_interrupted.store(true, std::memory_order_relaxed); |
| } |