blob: e13de34b99e1304067d81460609f39769f524885 [file] [log] [blame]
/*
* 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);
}