• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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