1 /* 2 * Copyright 2018 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 #pragma once 18 19 #include <condition_variable> 20 #include <memory> 21 #include <mutex> 22 #include <queue> 23 #include <thread> 24 25 #include <EGL/egl.h> 26 27 #include "Thread.h" 28 29 #include "WorkerThread.h" 30 31 namespace samples { 32 33 class Settings; 34 35 class Renderer { 36 // Allows construction with std::unique_ptr from a static method, but disallows construction 37 // outside of the class since no one else can construct a ConstructorTag 38 struct ConstructorTag { 39 }; 40 41 public: Renderer(ConstructorTag)42 explicit Renderer(ConstructorTag) {} 43 44 static Renderer *getInstance(); 45 46 // Sets the active window to render into 47 // Takes ownership of window and will release its reference 48 void setWindow(ANativeWindow *window, int32_t width, int32_t height); 49 50 void start(); 51 52 void stop(); 53 54 float getAverageFps(); 55 56 void requestDraw(); 57 58 void setWorkload(int load); 59 60 private: 61 class ThreadState { 62 public: 63 ThreadState(); 64 65 ~ThreadState(); 66 67 void onSettingsChanged(const Settings *); 68 69 void clearSurface(); 70 71 bool configHasAttribute(EGLint attribute, EGLint value); 72 73 EGLBoolean makeCurrent(EGLSurface surface); 74 75 EGLDisplay display = EGL_NO_DISPLAY; 76 EGLConfig config = static_cast<EGLConfig>(0); 77 EGLSurface surface = EGL_NO_SURFACE; 78 EGLContext context = EGL_NO_CONTEXT; 79 80 bool isStarted = false; 81 82 std::chrono::time_point<std::chrono::steady_clock> lastUpdate = std::chrono::steady_clock::now(); 83 float x = 0.0f; 84 float velocity = 1.6f; 85 86 std::chrono::nanoseconds refreshPeriod = std::chrono::nanoseconds{0}; 87 int64_t swapIntervalNS = 0; 88 int32_t width = 0; 89 int32_t height = 0; 90 }; 91 92 void draw(ThreadState *threadState); 93 void calculateFps(); 94 95 WorkerThread<ThreadState> mWorkerThread = {"Renderer", Affinity::Odd}; 96 97 class HotPocketState { 98 public: 99 void onSettingsChanged(const Settings *); 100 101 bool isEnabled = false; 102 bool isStarted = false; 103 }; 104 105 WorkerThread<HotPocketState> mHotPocketThread = {"HotPocket", Affinity::Even}; 106 107 void spin(); 108 109 float averageFps = -1.0f; 110 111 int mWorkload = 0; 112 }; 113 114 } // namespace samples 115