Add libvrflinger for use in SurfaceFlinger
A separate CL uses this code from SurfaceFlinger.
Bug: None
Test: Manually ran modified SurfaceFlinger
Change-Id: I34588df1365588c0a0265e1e2325e3dd5516206a
diff --git a/libs/vr/libvrflinger/compositor.h b/libs/vr/libvrflinger/compositor.h
new file mode 100644
index 0000000..be26d31
--- /dev/null
+++ b/libs/vr/libvrflinger/compositor.h
@@ -0,0 +1,233 @@
+#ifndef ANDROID_DVR_SERVICES_DISPLAYD_COMPOSITOR_H_
+#define ANDROID_DVR_SERVICES_DISPLAYD_COMPOSITOR_H_
+
+#include <EGL/egl.h>
+#include <log/log.h>
+#include <utils/StrongPointer.h>
+
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <vector>
+
+#include <pdx/file_handle.h>
+#include <private/dvr/clock_ns.h>
+#include <private/dvr/composite_hmd.h>
+#include <private/dvr/display_metrics.h>
+#include <private/dvr/distortion_renderer.h>
+#include <private/dvr/frame_time_history.h>
+#include <private/dvr/ion_buffer.h>
+#include <private/dvr/native_buffer.h>
+
+#include "acquired_buffer.h"
+#include "video_compositor.h"
+struct DvrPose;
+
+namespace android {
+namespace dvr {
+
+class Blur;
+class BufferConsumer;
+class CompositeHmd;
+class DebugHudView;
+class DisplaySurface;
+
+// This is a GPU compositor for software EDS and lens warp on buffers provided
+// by HardwareComposer.
+class Compositor {
+ public:
+ Compositor();
+ ~Compositor();
+
+ bool Initialize(const DisplayMetrics& display_metrics);
+ void UpdateHeadMountMetrics(const HeadMountMetrics& head_mount_metrics);
+ void Shutdown();
+
+ // Renders a frame with the latest buffers with EDS and warp applied.
+ // buffer_fence_fd can be used to get a fence for the rendered frame. It can
+ // be set to null if the fence isn't needed.
+ bool DrawFrame(uint32_t target_vsync_count,
+ pdx::LocalHandle* buffer_fence_fd);
+
+ // Remove all buffers.
+ void RemoveAllBuffers();
+
+ // Synchronize compositor layers with in given surfaces.
+ void UpdateSurfaces(
+ const std::vector<std::shared_ptr<DisplaySurface>>& surfaces);
+
+ // This must be called for each surface before DrawFrame is called.
+ void PostBuffer(const std::shared_ptr<DisplaySurface>& surface);
+
+ std::shared_ptr<IonBuffer> GetBuffer() const {
+ return render_target_[active_render_target_].buffer();
+ }
+
+ // Returns the number of layers being rendered by the compositor.
+ size_t GetLayerCount() const { return layers_.size(); }
+
+ // Returns the source buffer at the given layer index or nullptr if none is
+ // available.
+ std::shared_ptr<BufferConsumer> PeekAtLayer(size_t index) const {
+ if (index >= GetLayerCount())
+ return nullptr;
+ return layers_[index].buffer().buffer();
+ }
+
+ // Expensive operation to transfer the pixels of the given layer index into
+ // unformatted memory and return as a RGBA buffer.
+ // On success, returns non-zero sized vector and sets width and height.
+ // On failure, returns empty vector.
+ std::vector<uint8_t> ReadLayerPixels(size_t index, int* width, int* height);
+
+ // Expensive operation to transfer the pixels of the given buffer into
+ // unformatted memory and return as a RGBA buffer.
+ // On success, returns non-zero sized vector.
+ // On failure, returns empty vector.
+ std::vector<uint8_t> ReadBufferPixels(const IonBuffer* buffer);
+
+ bool GetLastEdsPose(LateLatchOutput* out_data);
+
+ const HeadMountMetrics& head_mount_metrics() const {
+ return head_mount_metrics_;
+ }
+
+ private:
+ class Texture;
+ class RenderPoseBufferObject;
+
+ // A rendered frame from an application.
+ class AppFrame {
+ public:
+ AppFrame();
+ ~AppFrame();
+
+ AppFrame(AppFrame&& other) = default;
+ AppFrame& operator=(AppFrame&&) = default;
+
+ // Gets a GL texture object for the current buffer. The resulting texture
+ // object will be cached for future calls. Returns a pointer for temporary
+ // access - not meant to hold on to.
+ const Texture* GetGlTextureId(EGLDisplay display, int index);
+
+ bool operator<(const AppFrame& rhs) const {
+ return z_order_ < rhs.z_order_;
+ }
+ int z_order() const { return z_order_; }
+ // Return true if this surface z order has been changed.
+ bool UpdateSurface(const std::shared_ptr<DisplaySurface>& surface);
+ void UpdateVideoMeshSurface(const std::shared_ptr<DisplaySurface>& surface);
+ void ResetBlurrers();
+ void AddBlurrer(Blur* blurrer);
+
+ const AcquiredBuffer& buffer() const { return buffer_; }
+ int surface_id() const { return surface_id_; }
+ float blur() const { return blur_; }
+ bool vertical_flip() const { return vertical_flip_; }
+ bool enable_cac() const { return enable_cac_; }
+ size_t blurrer_count() const { return blurrers_.size(); }
+ Blur* blurrer(size_t i) {
+ return blurrers_.size() < i ? nullptr : blurrers_[i].get();
+ }
+ uint32_t render_buffer_index() const { return render_buffer_index_; }
+ const RenderPoseBufferObject* render_pose_buffer_object() const {
+ return render_pose_buffer_object_.get();
+ }
+
+ template <class A>
+ void ForEachVideoCompositor(A action) const {
+ for (auto& c : video_compositors_) {
+ action(c);
+ }
+ }
+
+ private:
+ int surface_id_;
+ float blur_;
+ int z_order_;
+ bool vertical_flip_;
+ bool enable_cac_;
+ std::vector<std::unique_ptr<Blur>> blurrers_;
+ AcquiredBuffer buffer_;
+ std::vector<std::shared_ptr<Texture>> textures_;
+ uint32_t render_buffer_index_;
+ std::unique_ptr<RenderPoseBufferObject> render_pose_buffer_object_;
+
+ // Active video mesh compositors
+ std::vector<std::shared_ptr<VideoCompositor>> video_compositors_;
+
+ AppFrame(const AppFrame& other) = delete;
+ AppFrame& operator=(const AppFrame&) = delete;
+ };
+
+ class RenderTarget {
+ public:
+ RenderTarget();
+ ~RenderTarget();
+
+ void Initialize(int width, int height);
+ void Destroy();
+ void BindFramebuffer();
+ void DiscardColorAttachment();
+
+ std::shared_ptr<IonBuffer> buffer() const { return buffer_; }
+
+ private:
+ std::shared_ptr<IonBuffer> buffer_;
+ android::sp<NativeBuffer> native_buffer_;
+
+ GLuint buffer_texture_id_;
+ GLuint buffer_framebuffer_id_;
+ EGLImageKHR buffer_image_;
+ };
+
+ Compositor(const Compositor&) = delete;
+ void operator=(const Compositor&) = delete;
+
+ bool InitializeEGL();
+
+ void UpdateHudToggle();
+ void PrintStatsHud();
+ void CheckAndUpdateHeadMountMetrics(bool force_update);
+
+ RenderTarget& GetRenderTarget() {
+ return render_target_[active_render_target_];
+ }
+
+ void SetNextRenderTarget() {
+ active_render_target_ = (active_render_target_ + 1) & 1;
+ }
+
+ std::vector<AppFrame> layers_;
+
+ DisplayMetrics display_metrics_;
+ HeadMountMetrics head_mount_metrics_;
+
+ EGLDisplay display_;
+ EGLConfig config_;
+ EGLSurface surface_;
+ EGLContext context_;
+ int active_render_target_;
+ RenderTarget render_target_[2];
+ bool is_render_direct_;
+
+ // FBO for compute shader.
+ GLuint compute_fbo_;
+ GLuint compute_fbo_texture_;
+
+ std::unique_ptr<DebugHudView> debug_hud_;
+
+ // EDS:
+ std::unique_ptr<CompositeHmd> composite_hmd_;
+ bool hmd_metrics_requires_update_;
+ std::unique_ptr<DistortionRenderer> eds_renderer_;
+
+ bool eds_pose_capture_enabled_;
+ std::mutex mutex_;
+ LateLatchOutput eds_pose_capture_;
+};
+
+} // namespace dvr
+} // namespace android
+
+#endif // ANDROID_DVR_SERVICES_DISPLAYD_COMPOSITOR_H_