1 /* 2 * Copyright (C) 2017 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 #pragma once 17 18 #include <EGL/egl.h> 19 #include <GLES/gl.h> 20 #include <GLES3/gl3.h> 21 #include <vulkan/vulkan.h> 22 23 #include <functional> 24 #include <future> 25 #include <optional> 26 #include <vector> 27 28 #include "DisplayVk.h" 29 #include "Hwc2.h" 30 #include "PostCommands.h" 31 #include "base/Compiler.h" 32 #include "base/Lock.h" 33 #include "base/MessageChannel.h" 34 #include "host-common/window_agent.h" 35 36 class ColorBuffer; 37 class FrameBuffer; 38 struct RenderThreadInfo; 39 40 class PostWorker { 41 public: 42 using BindSubwinCallback = std::function<bool(void)>; 43 44 PostWorker(BindSubwinCallback&& cb, bool mainThreadPostingOnly, EGLContext eglContext, 45 EGLSurface eglSurface, DisplayVk*); 46 ~PostWorker(); 47 48 // post: posts the next color buffer. 49 // Assumes framebuffer lock is held. 50 void post(ColorBuffer* cb); 51 52 // viewport: (re)initializes viewport dimensions. 53 // Assumes framebuffer lock is held. 54 // This is called whenever the subwindow needs a refresh 55 // (FrameBuffer::setupSubWindow). 56 void viewport(int width, int height); 57 58 // compose: compse the layers into final framebuffer. The callback will be 59 // called when the CPU side job completes. The passed in future in the 60 // callback will be completed when the GPU opereation completes. 61 void compose(ComposeDevice* p, uint32_t bufferSize, 62 std::shared_ptr<Post::ComposeCallback>); 63 64 // compose: compse the layers into final framebuffer, version 2. The 65 // callback will be called when the CPU side job completes. The passed in 66 // future in the callback will be completed when the GPU opereation 67 // completes. 68 void compose(ComposeDevice_v2* p, uint32_t bufferSize, 69 std::shared_ptr<Post::ComposeCallback>); 70 71 // clear: blanks out emulator display when refreshing the subwindow 72 // if there is no last posted color buffer to show yet. 73 void clear(); 74 75 void screenshot(ColorBuffer* cb, int screenwidth, int screenheight, 76 GLenum format, GLenum type, int skinRotation, void* pixels); 77 78 private: 79 // Impl versions of the above, so we can run it from separate threads 80 void postImpl(ColorBuffer* cb); 81 void viewportImpl(int width, int height); 82 void composeImpl(const ComposeDevice* p); 83 std::shared_future<void> composev2Impl(const ComposeDevice_v2* p); 84 void clearImpl(); 85 86 // Subwindow binding 87 void bind(); 88 void unbind(); 89 90 void glesComposeLayer(ComposeLayer* l, uint32_t w, uint32_t h); 91 void fillMultiDisplayPostStruct(ComposeLayer* l, hwc_rect_t displayArea, 92 hwc_frect_t cropArea, 93 hwc_transform_t transform); 94 95 // If m_mainThreadPostingOnly is true, schedule the task to UI thread by 96 // using m_runOnUiThread. Otherwise, execute the task on the current thread. 97 void runTask(std::packaged_task<void()>); 98 99 private: 100 using UiThreadRunner = std::function<void(UiUpdateFunc, void*, bool)>; 101 struct PostArgs { 102 ColorBuffer* postCb; 103 int width; 104 int height; 105 std::vector<char> composeBuffer; 106 }; 107 108 FrameBuffer* mFb; 109 110 std::function<bool(void)> mBindSubwin; 111 112 bool m_needsToRebindWindow = true; 113 int m_viewportWidth = 0; 114 int m_viewportHeight = 0; 115 GLuint m_composeFbo = 0; 116 117 bool m_mainThreadPostingOnly = false; 118 UiThreadRunner m_runOnUiThread = 0; 119 EGLContext mContext = EGL_NO_CONTEXT; 120 121 // The implementation for Vulkan native swapchain. Only initialized when 122 // useVulkan is set when calling FrameBuffer::initialize(). PostWorker 123 // doesn't take the ownership of this DisplayVk object. 124 DisplayVk* const m_displayVk; 125 // With Vulkan swapchain, compose also means to post to the WSI surface. 126 // In this case, don't do anything in the subsequent resource flush. 127 std::optional<uint32_t> m_lastVkComposeColorBuffer = std::nullopt; 128 std::unordered_map<uint32_t, std::shared_future<void>> m_composeTargetToComposeFuture; 129 130 bool isComposeTargetReady(uint32_t targetHandle); 131 132 DISALLOW_COPY_AND_ASSIGN(PostWorker); 133 }; 134