blob: 4266a40694a133e303759849355b57d6d3a2be98 [file] [log] [blame]
#ifndef ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_
#define ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_
#include <log/log.h>
#include <hardware/gralloc.h>
#include <hardware/hardware.h>
#include <hardware/hwcomposer2.h>
#include <private/dvr/buffer_hub_client.h>
#include <private/dvr/sync_util.h>
#include <array>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <thread>
#include <tuple>
#include <vector>
#include <pdx/file_handle.h>
#include <private/dvr/buffer_hub_client.h>
#include <private/dvr/frame_time_history.h>
#include <private/dvr/sync_util.h>
#include "acquired_buffer.h"
#include "compositor.h"
#include "display_surface.h"
#include "DisplayHardware/ComposerHal.h"
// Hardware composer HAL doesn't define HWC_TRANSFORM_NONE as of this writing.
#ifndef HWC_TRANSFORM_NONE
#define HWC_TRANSFORM_NONE static_cast<hwc_transform_t>(0)
#endif
namespace android {
namespace dvr {
// Basic display metrics for physical displays. Dimensions and densities are
// relative to the physical display orientation, which may be different from the
// logical display orientation exposed to applications.
struct HWCDisplayMetrics {
int width;
int height;
struct {
int x;
int y;
} dpi;
int vsync_period_ns;
};
// Layer represents the connection between a hardware composer layer and the
// source supplying buffers for the layer's contents.
class Layer {
public:
Layer();
// Sets the hardware composer layer and display metrics that this Layer should
// use each Prepare cycle. This class does not own either of these pointers,
// which MUST remain valid for its lifetime. This method MUST be called once
// in the life of the instance before any other method is valid to call.
void Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics);
// Releases any shared pointers and fence handles held by this instance.
void Reset();
// Sets up the layer to use a display surface as its content source. The Layer
// will automatically handle ACQUIRE/RELEASE phases for the surface's buffer
// train every frame.
//
// |blending| receives HWC_BLENDING_* values.
// |transform| receives HWC_TRANSFORM_* values.
// |composition_type| receives either HWC_FRAMEBUFFER for most layers or
// HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
// |index| is the index of this surface in the DisplaySurface array.
void Setup(const std::shared_ptr<DisplaySurface>& surface,
hwc2_blend_mode_t blending, hwc_transform_t transform,
hwc2_composition_t composition_type, size_t index);
// Sets up the layer to use a direct buffer as its content source. No special
// handling of the buffer is performed; responsibility for updating or
// changing the buffer each frame is on the caller.
//
// |blending| receives HWC_BLENDING_* values.
// |transform| receives HWC_TRANSFORM_* values.
// |composition_type| receives either HWC_FRAMEBUFFER for most layers or
// HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
void Setup(const std::shared_ptr<IonBuffer>& buffer,
hwc2_blend_mode_t blending, hwc_transform_t transform,
hwc2_composition_t composition_type, size_t z_order);
// Layers that use a direct IonBuffer should call this each frame to update
// which buffer will be used for the next PostLayers.
void UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer);
// Sets up the hardware composer layer for the next frame. When the layer is
// associated with a display surface, this method automatically ACQUIRES a new
// buffer if one is available.
void Prepare();
// After calling prepare, if this frame is to be dropped instead of passing
// along to the HWC, call Drop to close the contained fence(s).
void Drop();
// Performs fence bookkeeping after the frame has been posted to hardware
// composer.
void Finish(int release_fence_fd);
// Sets the blending for the layer. |blending| receives HWC_BLENDING_* values.
void SetBlending(hwc2_blend_mode_t blending);
// Sets the Z-order of this layer
void SetZOrderIndex(int surface_index);
// Gets the current IonBuffer associated with this layer. Ownership of the
// buffer DOES NOT pass to the caller and the pointer is not guaranteed to
// remain valid across calls to Layer::Setup(), Layer::Prepare(), or
// Layer::Reset(). YOU HAVE BEEN WARNED.
IonBuffer* GetBuffer();
hwc2_composition_t GetCompositionType() const { return composition_type_; }
hwc2_layer_t GetLayerHandle() const { return hardware_composer_layer_; }
bool UsesDirectBuffer() const { return direct_buffer_ != nullptr; }
bool IsLayerSetup() const {
return direct_buffer_ != nullptr || surface_ != nullptr;
}
// Applies all of the settings to this layer using the hwc functions
void UpdateLayerSettings();
int GetSurfaceId() const {
if (surface_ != nullptr) {
return surface_->surface_id();
} else {
return -1;
}
}
private:
void CommonLayerSetup();
Hwc2::Composer* hwc2_hidl_;
// Original display surface array index for tracking purposes.
size_t surface_index_;
// The hardware composer layer and metrics to use during the prepare cycle.
hwc2_layer_t hardware_composer_layer_;
HWCDisplayMetrics* display_metrics_;
// Layer properties used to setup the hardware composer layer during the
// Prepare phase.
hwc2_blend_mode_t blending_;
hwc_transform_t transform_;
hwc2_composition_t composition_type_;
// These two members are mutually exclusive. When direct_buffer_ is set the
// Layer gets its contents directly from that buffer; when surface_ is set the
// Layer gets it contents from the surface's buffer train.
std::shared_ptr<IonBuffer> direct_buffer_;
std::shared_ptr<DisplaySurface> surface_;
// State when associated with a display surface.
AcquiredBuffer acquired_buffer_;
pdx::LocalHandle release_fence_;
pdx::LocalHandle acquire_fence_fd_;
bool surface_rect_functions_applied_;
Layer(const Layer&) = delete;
void operator=(const Layer&) = delete;
};
// HardwareComposer encapsulates the hardware composer HAL, exposing a
// simplified API to post buffers to the display.
class HardwareComposer {
public:
// Type for vsync callback.
using VSyncCallback = std::function<void(int, int64_t, int64_t, uint32_t)>;
// Since there is no universal way to query the number of hardware layers,
// just set it to 4 for now.
static constexpr int kMaxHardwareLayers = 4;
HardwareComposer();
HardwareComposer(Hwc2::Composer* hidl);
~HardwareComposer();
bool Suspend();
bool Resume();
bool IsSuspended() const { return pause_post_thread_; }
// Get the HMD display metrics for the current display.
DisplayMetrics GetHmdDisplayMetrics() const;
int32_t GetDisplayAttribute(hwc2_display_t display, hwc2_config_t config,
hwc2_attribute_t attributes,
int32_t* out_value) const;
int32_t GetDisplayMetrics(hwc2_display_t display, hwc2_config_t config,
HWCDisplayMetrics* out_metrics) const;
void Dump(char* buffer, uint32_t* out_size);
void SetVSyncCallback(VSyncCallback callback);
// Metrics of the logical display, which is always landscape.
int DisplayWidth() const { return display_metrics_.width; }
int DisplayHeight() const { return display_metrics_.height; }
HWCDisplayMetrics display_metrics() const { return display_metrics_; }
// Metrics of the native display, which depends on the specific hardware
// implementation of the display.
HWCDisplayMetrics native_display_metrics() const {
return native_display_metrics_;
}
std::shared_ptr<IonBuffer> framebuffer_target() const {
return framebuffer_target_;
}
// Set the display surface stack to compose to the display each frame.
int SetDisplaySurfaces(std::vector<std::shared_ptr<DisplaySurface>> surfaces);
Compositor* GetCompositor() { return &compositor_; }
private:
int32_t EnableVsync(bool enabled);
class ComposerCallback : public Hwc2::IComposerCallback {
public:
ComposerCallback() {}
hardware::Return<void> onHotplug(Hwc2::Display /*display*/,
Connection /*connected*/) override {
// TODO(skiazyk): depending on how the server is implemented, we might
// have to set it up to synchronize with receiving this event, as it can
// potentially be a critical event for setting up state within the
// hwc2 module. That is, we (technically) should not call any other hwc
// methods until this method has been called after registering the
// callbacks.
return hardware::Void();
}
hardware::Return<void> onRefresh(Hwc2::Display /*display*/) override {
return hardware::Void();
}
hardware::Return<void> onVsync(Hwc2::Display /*display*/,
int64_t /*timestamp*/) override {
return hardware::Void();
}
};
int32_t Validate(hwc2_display_t display);
int32_t Present(hwc2_display_t display);
void SetBacklightBrightness(int brightness);
void PostLayers(bool is_geometry_changed);
void PostThread();
int ReadWaitPPState();
int BlockUntilVSync();
int ReadVSyncTimestamp(int64_t* timestamp);
int WaitForVSync(int64_t* timestamp);
int SleepUntil(int64_t wakeup_timestamp);
bool IsFramePendingInDriver() { return ReadWaitPPState() == 1; }
// Returns true if the layer config changed, false otherwise
bool UpdateLayerConfig(
std::vector<std::shared_ptr<DisplaySurface>>* compositor_surfaces);
void PostCompositorBuffers(
const std::vector<std::shared_ptr<DisplaySurface>>& compositor_surfaces);
void UpdateDisplayState();
struct FrameTimeMeasurementRecord {
int64_t start_time;
pdx::LocalHandle fence;
FrameTimeMeasurementRecord(FrameTimeMeasurementRecord&&) = default;
FrameTimeMeasurementRecord& operator=(FrameTimeMeasurementRecord&&) =
default;
FrameTimeMeasurementRecord(const FrameTimeMeasurementRecord&) = delete;
FrameTimeMeasurementRecord& operator=(const FrameTimeMeasurementRecord&) =
delete;
};
void UpdateFrameTimeHistory(std::vector<FrameTimeMeasurementRecord>* backlog,
int backlog_max,
FenceInfoBuffer* fence_info_buffer,
FrameTimeHistory* history);
// Returns true if the frame finished rendering, false otherwise. If the frame
// finished the frame end time is stored in timestamp. Doesn't block.
bool CheckFrameFinished(int frame_fence_fd,
FenceInfoBuffer* fence_info_buffer,
int64_t* timestamp);
void HandlePendingScreenshots();
void PausePostThread();
// Hardware composer HAL device.
std::unique_ptr<Hwc2::Composer> hwc2_hidl_;
sp<ComposerCallback> callbacks_;
// Display metrics of the physical display.
HWCDisplayMetrics native_display_metrics_;
// Display metrics of the logical display, adjusted so that orientation is
// landscape.
HWCDisplayMetrics display_metrics_;
// Transform required to get from native to logical display orientation.
hwc_transform_t display_transform_;
// Buffer for the background layer required by hardware composer.
std::shared_ptr<IonBuffer> framebuffer_target_;
// Protects access to the display surfaces and logical layers.
std::mutex layer_mutex_;
// Active display surfaces configured by the display manager.
std::vector<std::shared_ptr<DisplaySurface>> display_surfaces_;
std::vector<std::shared_ptr<DisplaySurface>> added_display_surfaces_;
bool display_surfaces_updated_;
bool hardware_layers_need_update_;
// Layer array for handling buffer flow into hardware composer layers.
// Note that the first array is the actual storage for the layer objects,
// and the latter is an array of pointers, which can be freely re-arranged
// without messing up the underlying objects.
std::array<Layer, kMaxHardwareLayers> layer_storage_;
std::array<Layer*, kMaxHardwareLayers> layers_;
size_t active_layer_count_;
// Set by the Post thread to the index of the GPU compositing output
// buffer in the layers_ array.
Layer* gpu_layer_;
// Handler to hook vsync events outside of this class.
VSyncCallback vsync_callback_;
// Thread and condition for managing the layer posting thread. This thread
// wakes up a short time before vsync to hand buffers to post processing and
// the results to hardware composer.
std::thread post_thread_;
// Control variables to control the state of the post thread
pdx::LocalHandle terminate_post_thread_event_fd_;
bool pause_post_thread_;
std::mutex thread_pause_mutex_;
std::condition_variable thread_pause_semaphore_;
// Backlight LED brightness sysfs node.
pdx::LocalHandle backlight_brightness_fd_;
// Primary display vsync event sysfs node.
pdx::LocalHandle primary_display_vsync_event_fd_;
// Primary display wait_pingpong state sysfs node.
pdx::LocalHandle primary_display_wait_pp_fd_;
// VSync sleep timerfd.
pdx::LocalHandle vsync_sleep_timer_fd_;
// The timestamp of the last vsync.
int64_t last_vsync_timestamp_;
// Vsync count since display on.
uint32_t vsync_count_;
// Counter tracking the number of skipped frames.
int frame_skip_count_;
// After construction, only accessed on post_thread_.
Compositor compositor_;
// Fd array for tracking retire fences that are returned by hwc. This allows
// us to detect when the display driver begins queuing frames.
std::vector<pdx::LocalHandle> retire_fence_fds_;
// Pose client for frame count notifications. Pose client predicts poses
// out to display frame boundaries, so we need to tell it about vsyncs.
DvrPose* pose_client_;
static void HwcRefresh(hwc2_callback_data_t data, hwc2_display_t display);
static void HwcVSync(hwc2_callback_data_t data, hwc2_display_t display,
int64_t timestamp);
static void HwcHotplug(hwc2_callback_data_t callbackData,
hwc2_display_t display, hwc2_connection_t connected);
HardwareComposer(const HardwareComposer&) = delete;
void operator=(const HardwareComposer&) = delete;
};
} // namespace dvr
} // namespace android
#endif // ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_