1 // Copyright (C) 2018 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #include "OpenGLESDispatch/GLESv2Dispatch.h" 18 #include "RenderContext.h" 19 #include "base/Compiler.h" 20 #include "FenceSync.h" 21 #include "Hwc2.h" 22 23 #include <cinttypes> 24 #include <functional> 25 #include <memory> 26 27 class FrameBuffer; 28 class OSWindow; 29 struct RenderThreadInfo; 30 31 namespace emugl { 32 33 // Determines whether the host GPU should be used. 34 bool shouldUseHostGpu(); 35 36 // Determines whether the test will use a Window. 37 bool shouldUseWindow(); 38 39 // Creates or adjusts a persistent test window. 40 // On some systems, test window creation can fail (such as when on a headless server). 41 // In that case, this function will return nullptr. 42 OSWindow* createOrGetTestWindow(int xoffset, int yoffset, int width, int height); 43 44 45 class ColorBufferQueue; 46 // Creates a window (or runs headless) to be used in a sample app. 47 class SampleApplication { 48 public: 49 SampleApplication(int windowWidth = 256, int windowHeight = 256, 50 int refreshRate = 60, GLESApi glVersion = GLESApi_3_0, 51 bool compose = false); 52 ~SampleApplication(); 53 54 // A basic draw loop that works similar to most simple 55 // GL apps that run on desktop. 56 // 57 // Per frame: 58 // 59 // a single GL context for drawing, 60 // a color buffer to blit, 61 // and a call to post that color buffer. 62 void rebind(); 63 void drawLoop(); 64 65 // A more complex loop that uses 3 separate contexts 66 // to simulate what goes on in Android: 67 // 68 // Per frame 69 // 70 // a GL 'app' context for drawing, 71 // a SurfaceFlinger context for rendering the "Layer", 72 // and a HWC context for posting. 73 void surfaceFlingerComposerLoop(); 74 75 // TODO: 76 // void HWC2Loop(); 77 78 // Just initialize, draw, and swap buffers once. 79 void drawOnce(); 80 81 private: 82 void drawWorkerWithCompose(ColorBufferQueue& app2sfQueue, ColorBufferQueue& sf2appQueue); 83 void drawWorker(ColorBufferQueue& app2sfQueue, ColorBufferQueue& sf2appQueue, 84 ColorBufferQueue& sf2hwcQueue, ColorBufferQueue& hwc2sfQueue); 85 FenceSync* getFenceSync(); 86 87 protected: 88 virtual void initialize() = 0; 89 virtual void draw() = 0; 90 91 virtual const GLESv2Dispatch* getGlDispatch(); 92 93 int mWidth = 256; 94 int mHeight = 256; 95 int mRefreshRate = 60; 96 97 bool mUseSubWindow = false; 98 OSWindow* mWindow = nullptr; 99 std::unique_ptr<FrameBuffer> mFb = {}; 100 std::unique_ptr<RenderThreadInfo> mRenderThreadInfo = {}; 101 102 int mXOffset= 400; 103 int mYOffset= 400; 104 105 unsigned int mColorBuffer = 0; 106 unsigned int mSurface = 0; 107 unsigned int mContext = 0; 108 109 bool mIsCompose = false; 110 uint32_t mTargetCb = 0; 111 112 DISALLOW_COPY_ASSIGN_AND_MOVE(SampleApplication); 113 }; 114 115 } // namespace emugl 116