/* * 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 "base/System.h" #include #include 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); }