Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame^] | 1 | #ifndef ANDROID_DVR_SERVICES_DISPLAYD_COMPOSITOR_H_ |
| 2 | #define ANDROID_DVR_SERVICES_DISPLAYD_COMPOSITOR_H_ |
| 3 | |
| 4 | #include <EGL/egl.h> |
| 5 | #include <log/log.h> |
| 6 | #include <utils/StrongPointer.h> |
| 7 | |
| 8 | #include <memory> |
| 9 | #include <mutex> |
| 10 | #include <queue> |
| 11 | #include <vector> |
| 12 | |
| 13 | #include <pdx/file_handle.h> |
| 14 | #include <private/dvr/clock_ns.h> |
| 15 | #include <private/dvr/composite_hmd.h> |
| 16 | #include <private/dvr/display_metrics.h> |
| 17 | #include <private/dvr/distortion_renderer.h> |
| 18 | #include <private/dvr/frame_time_history.h> |
| 19 | #include <private/dvr/ion_buffer.h> |
| 20 | #include <private/dvr/native_buffer.h> |
| 21 | |
| 22 | #include "acquired_buffer.h" |
| 23 | #include "video_compositor.h" |
| 24 | struct DvrPose; |
| 25 | |
| 26 | namespace android { |
| 27 | namespace dvr { |
| 28 | |
| 29 | class Blur; |
| 30 | class BufferConsumer; |
| 31 | class CompositeHmd; |
| 32 | class DebugHudView; |
| 33 | class DisplaySurface; |
| 34 | |
| 35 | // This is a GPU compositor for software EDS and lens warp on buffers provided |
| 36 | // by HardwareComposer. |
| 37 | class Compositor { |
| 38 | public: |
| 39 | Compositor(); |
| 40 | ~Compositor(); |
| 41 | |
| 42 | bool Initialize(const DisplayMetrics& display_metrics); |
| 43 | void UpdateHeadMountMetrics(const HeadMountMetrics& head_mount_metrics); |
| 44 | void Shutdown(); |
| 45 | |
| 46 | // Renders a frame with the latest buffers with EDS and warp applied. |
| 47 | // buffer_fence_fd can be used to get a fence for the rendered frame. It can |
| 48 | // be set to null if the fence isn't needed. |
| 49 | bool DrawFrame(uint32_t target_vsync_count, |
| 50 | pdx::LocalHandle* buffer_fence_fd); |
| 51 | |
| 52 | // Remove all buffers. |
| 53 | void RemoveAllBuffers(); |
| 54 | |
| 55 | // Synchronize compositor layers with in given surfaces. |
| 56 | void UpdateSurfaces( |
| 57 | const std::vector<std::shared_ptr<DisplaySurface>>& surfaces); |
| 58 | |
| 59 | // This must be called for each surface before DrawFrame is called. |
| 60 | void PostBuffer(const std::shared_ptr<DisplaySurface>& surface); |
| 61 | |
| 62 | std::shared_ptr<IonBuffer> GetBuffer() const { |
| 63 | return render_target_[active_render_target_].buffer(); |
| 64 | } |
| 65 | |
| 66 | // Returns the number of layers being rendered by the compositor. |
| 67 | size_t GetLayerCount() const { return layers_.size(); } |
| 68 | |
| 69 | // Returns the source buffer at the given layer index or nullptr if none is |
| 70 | // available. |
| 71 | std::shared_ptr<BufferConsumer> PeekAtLayer(size_t index) const { |
| 72 | if (index >= GetLayerCount()) |
| 73 | return nullptr; |
| 74 | return layers_[index].buffer().buffer(); |
| 75 | } |
| 76 | |
| 77 | // Expensive operation to transfer the pixels of the given layer index into |
| 78 | // unformatted memory and return as a RGBA buffer. |
| 79 | // On success, returns non-zero sized vector and sets width and height. |
| 80 | // On failure, returns empty vector. |
| 81 | std::vector<uint8_t> ReadLayerPixels(size_t index, int* width, int* height); |
| 82 | |
| 83 | // Expensive operation to transfer the pixels of the given buffer into |
| 84 | // unformatted memory and return as a RGBA buffer. |
| 85 | // On success, returns non-zero sized vector. |
| 86 | // On failure, returns empty vector. |
| 87 | std::vector<uint8_t> ReadBufferPixels(const IonBuffer* buffer); |
| 88 | |
| 89 | bool GetLastEdsPose(LateLatchOutput* out_data); |
| 90 | |
| 91 | const HeadMountMetrics& head_mount_metrics() const { |
| 92 | return head_mount_metrics_; |
| 93 | } |
| 94 | |
| 95 | private: |
| 96 | class Texture; |
| 97 | class RenderPoseBufferObject; |
| 98 | |
| 99 | // A rendered frame from an application. |
| 100 | class AppFrame { |
| 101 | public: |
| 102 | AppFrame(); |
| 103 | ~AppFrame(); |
| 104 | |
| 105 | AppFrame(AppFrame&& other) = default; |
| 106 | AppFrame& operator=(AppFrame&&) = default; |
| 107 | |
| 108 | // Gets a GL texture object for the current buffer. The resulting texture |
| 109 | // object will be cached for future calls. Returns a pointer for temporary |
| 110 | // access - not meant to hold on to. |
| 111 | const Texture* GetGlTextureId(EGLDisplay display, int index); |
| 112 | |
| 113 | bool operator<(const AppFrame& rhs) const { |
| 114 | return z_order_ < rhs.z_order_; |
| 115 | } |
| 116 | int z_order() const { return z_order_; } |
| 117 | // Return true if this surface z order has been changed. |
| 118 | bool UpdateSurface(const std::shared_ptr<DisplaySurface>& surface); |
| 119 | void UpdateVideoMeshSurface(const std::shared_ptr<DisplaySurface>& surface); |
| 120 | void ResetBlurrers(); |
| 121 | void AddBlurrer(Blur* blurrer); |
| 122 | |
| 123 | const AcquiredBuffer& buffer() const { return buffer_; } |
| 124 | int surface_id() const { return surface_id_; } |
| 125 | float blur() const { return blur_; } |
| 126 | bool vertical_flip() const { return vertical_flip_; } |
| 127 | bool enable_cac() const { return enable_cac_; } |
| 128 | size_t blurrer_count() const { return blurrers_.size(); } |
| 129 | Blur* blurrer(size_t i) { |
| 130 | return blurrers_.size() < i ? nullptr : blurrers_[i].get(); |
| 131 | } |
| 132 | uint32_t render_buffer_index() const { return render_buffer_index_; } |
| 133 | const RenderPoseBufferObject* render_pose_buffer_object() const { |
| 134 | return render_pose_buffer_object_.get(); |
| 135 | } |
| 136 | |
| 137 | template <class A> |
| 138 | void ForEachVideoCompositor(A action) const { |
| 139 | for (auto& c : video_compositors_) { |
| 140 | action(c); |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | private: |
| 145 | int surface_id_; |
| 146 | float blur_; |
| 147 | int z_order_; |
| 148 | bool vertical_flip_; |
| 149 | bool enable_cac_; |
| 150 | std::vector<std::unique_ptr<Blur>> blurrers_; |
| 151 | AcquiredBuffer buffer_; |
| 152 | std::vector<std::shared_ptr<Texture>> textures_; |
| 153 | uint32_t render_buffer_index_; |
| 154 | std::unique_ptr<RenderPoseBufferObject> render_pose_buffer_object_; |
| 155 | |
| 156 | // Active video mesh compositors |
| 157 | std::vector<std::shared_ptr<VideoCompositor>> video_compositors_; |
| 158 | |
| 159 | AppFrame(const AppFrame& other) = delete; |
| 160 | AppFrame& operator=(const AppFrame&) = delete; |
| 161 | }; |
| 162 | |
| 163 | class RenderTarget { |
| 164 | public: |
| 165 | RenderTarget(); |
| 166 | ~RenderTarget(); |
| 167 | |
| 168 | void Initialize(int width, int height); |
| 169 | void Destroy(); |
| 170 | void BindFramebuffer(); |
| 171 | void DiscardColorAttachment(); |
| 172 | |
| 173 | std::shared_ptr<IonBuffer> buffer() const { return buffer_; } |
| 174 | |
| 175 | private: |
| 176 | std::shared_ptr<IonBuffer> buffer_; |
| 177 | android::sp<NativeBuffer> native_buffer_; |
| 178 | |
| 179 | GLuint buffer_texture_id_; |
| 180 | GLuint buffer_framebuffer_id_; |
| 181 | EGLImageKHR buffer_image_; |
| 182 | }; |
| 183 | |
| 184 | Compositor(const Compositor&) = delete; |
| 185 | void operator=(const Compositor&) = delete; |
| 186 | |
| 187 | bool InitializeEGL(); |
| 188 | |
| 189 | void UpdateHudToggle(); |
| 190 | void PrintStatsHud(); |
| 191 | void CheckAndUpdateHeadMountMetrics(bool force_update); |
| 192 | |
| 193 | RenderTarget& GetRenderTarget() { |
| 194 | return render_target_[active_render_target_]; |
| 195 | } |
| 196 | |
| 197 | void SetNextRenderTarget() { |
| 198 | active_render_target_ = (active_render_target_ + 1) & 1; |
| 199 | } |
| 200 | |
| 201 | std::vector<AppFrame> layers_; |
| 202 | |
| 203 | DisplayMetrics display_metrics_; |
| 204 | HeadMountMetrics head_mount_metrics_; |
| 205 | |
| 206 | EGLDisplay display_; |
| 207 | EGLConfig config_; |
| 208 | EGLSurface surface_; |
| 209 | EGLContext context_; |
| 210 | int active_render_target_; |
| 211 | RenderTarget render_target_[2]; |
| 212 | bool is_render_direct_; |
| 213 | |
| 214 | // FBO for compute shader. |
| 215 | GLuint compute_fbo_; |
| 216 | GLuint compute_fbo_texture_; |
| 217 | |
| 218 | std::unique_ptr<DebugHudView> debug_hud_; |
| 219 | |
| 220 | // EDS: |
| 221 | std::unique_ptr<CompositeHmd> composite_hmd_; |
| 222 | bool hmd_metrics_requires_update_; |
| 223 | std::unique_ptr<DistortionRenderer> eds_renderer_; |
| 224 | |
| 225 | bool eds_pose_capture_enabled_; |
| 226 | std::mutex mutex_; |
| 227 | LateLatchOutput eds_pose_capture_; |
| 228 | }; |
| 229 | |
| 230 | } // namespace dvr |
| 231 | } // namespace android |
| 232 | |
| 233 | #endif // ANDROID_DVR_SERVICES_DISPLAYD_COMPOSITOR_H_ |