blob: be26d310b4dbd4c1b1b5a0f84c495cc6c66103ca [file] [log] [blame]
#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_