Implement fencing
cover Implement fencing
This series removes the old thread-based synchronization utilities and replaces them with fences.
It has been tested on various platforms, including etnaviv/freedreno/virgl.
Robert Foss (5):
drm_hwcomposer: Add support for IN_FENCE_FD property to DrmPlane
drm_hwcomposer: Submit in-fence to DRM
drm_hwcomposer: Add FENCE_OUT_PTR property to DrmCrtc
drm_hwcomposer: Add GetCrtcCount function
drm_hwcomposer: Add out-fence support
Sean Paul (1):
drm_hwcomposer: Remove threading
Android.mk | 3 - drmcomposition.cpp | 166 -------------------------------- drmcomposition.h | 79 --------------- drmcompositor.cpp | 106 -------------------- drmcompositor.h | 56 ----------- drmcompositorworker.h | 41 -------- drmcrtc.cpp | 10 ++ drmcrtc.h | 2 + drmdisplaycomposition.cpp | 1 + drmdisplaycomposition.h | 19 ++++ drmdisplaycompositor.cpp | 240 +++++++++------------------------------------- drmdisplaycompositor.h | 36 +------ drmeventlistener.cpp | 3 + drmhwctwo.cpp | 15 +-- drmplane.cpp | 8 ++ drmplane.h | 2 + drmresources.cpp | 58 +---------- drmresources.h | 6 +- glworker.cpp | 52 +++++++++- glworker.h | 10 ++ 20 files changed, 163 insertions(+), 750 deletions(-) delete mode 100644 drmcomposition.cpp delete mode 100644 drmcomposition.h delete mode 100644 drmcompositor.cpp delete mode 100644 drmcompositor.h delete mode 100644 drmcompositorworker.h
Signature · 6 lines
2.11.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 1/6 drm_hwcomposer: Remove threading
From: Sean Paul <[email protected]>
Since HWC2 doesn't require the use of threads to implement correct synchronization, remove some of these threads.
--- Android.mk | 3 - drmcomposition.cpp | 166 ---------------------------------------- drmcomposition.h | 79 ------------------- drmcompositor.cpp | 106 -------------------------- drmcompositor.h | 56 -------------- drmcompositorworker.h | 41 ---------- drmdisplaycomposition.cpp | 1 + drmdisplaycomposition.h | 10 +++ drmdisplaycompositor.cpp | 189 ++++------------------------------------------ drmdisplaycompositor.h | 36 +-------- drmeventlistener.cpp | 3 + drmhwctwo.cpp | 6 +- drmresources.cpp | 54 +------------ drmresources.h | 5 -- glworker.cpp | 52 +++++++++++-- glworker.h | 10 +++ 16 files changed, 93 insertions(+), 724 deletions(-) delete mode 100644 drmcomposition.cpp delete mode 100644 drmcomposition.h delete mode 100644 drmcompositor.cpp delete mode 100644 drmcompositor.h delete mode 100644 drmcompositorworker.h
Android.mk +0 -3
@@ -57,9 +57,6 @@ LOCAL_C_INCLUDES := \ LOCAL_SRC_FILES := \ autolock.cpp \ drmresources.cpp \ - drmcomposition.cpp \ - drmcompositor.cpp \ - drmcompositorworker.cpp \ drmconnector.cpp \ drmcrtc.cpp \ drmdisplaycomposition.cpp \
drmcomposition.cpp deleted +0 -166
166 lines not on this page · raw message
drmcomposition.h deleted +0 -79
79 lines not on this page · raw message
drmcompositor.cpp deleted +0 -106
106 lines not on this page · raw message
drmcompositor.h deleted +0 -56
56 lines not on this page · raw message
drmcompositorworker.h deleted +0 -41
41 lines not on this page · raw message
drmdisplaycomposition.cpp +1 -0
@@ -17,6 +17,7 @@ #define LOG_TAG "hwc-drm-display-composition" #include "drmdisplaycomposition.h" +#include "drmdisplaycompositor.h" #include "drmcrtc.h" #include "drmplane.h" #include "drmresources.h"
drmdisplaycomposition.h +10 -0
@@ -42,6 +42,16 @@ enum DrmCompositionType { DRM_COMPOSITION_TYPE_MODESET, }; +struct DrmCompositionDisplayLayersMap { +int display; + bool geometry_changed = true; + std::vector<DrmHwcLayer> layers; + + DrmCompositionDisplayLayersMap() = default; + DrmCompositionDisplayLayersMap(DrmCompositionDisplayLayersMap &&rhs) = + default; +}; +struct DrmCompositionRegion { DrmHwcRect<int> frame; std::vector<size_t> source_layers;
drmdisplaycompositor.cpp +15 -174
260 lines not on this page · raw message
drmdisplaycompositor.h +3 -33
@@ -18,14 +18,12 @@#define ANDROID_DRM_DISPLAY_COMPOSITOR_H_ #include "drmhwcomposer.h" -#include "drmcomposition.h" -#include "drmcompositorworker.h" +#include "drmdisplaycomposition.h" #include "drmframebuffer.h" #include "separate_rects.h" #include <pthread.h> #include <memory> -#include <queue> #include <sstream> #include <tuple>
@@ -89,42 +87,18 @@ class DrmDisplayCompositor {int Init (DrmResources *drm,int display); std::unique_ptr<DrmDisplayComposition> CreateComposition() const; - int QueueComposition(std::unique_ptr<DrmDisplayComposition> composition); + int ApplyComposition(std::unique_ptr<DrmDisplayComposition> composition);int Composite ();int SquashAll (); void Dump(std::ostringstream *out) const; std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution(); - bool HaveQueuedComposites() const; -SquashState *squash_state () {return &squash_state_; } private: -struct FrameState { - std::unique_ptr<DrmDisplayComposition> composition; - int status = 0; - }; - - class FrameWorker : public Worker { - public: -FrameWorker (DrmDisplayCompositor *compositor); - ~FrameWorker() override; - -int Init (); - void QueueFrame(std::unique_ptr<DrmDisplayComposition> composition, -int status); - - protected: - void Routine() override; - - private: -DrmDisplayCompositor *compositor_; - std::queue<FrameState> frame_queue_; - }; - struct ModeState { bool needs_modeset = false; DrmMode mode;
@@ -158,10 +132,6 @@ class DrmDisplayCompositor {DrmResources *drm_;int display_; -DrmCompositorWorker worker_; -FrameWorker frame_worker_; - - std::queue<std::unique_ptr<DrmDisplayComposition>> composite_queue_; std::unique_ptr<DrmDisplayComposition> active_composition_;bool initialized_;
@@ -178,7 +148,7 @@ class DrmDisplayCompositor {int squash_framebuffer_index_;DrmFramebuffer squash_framebuffers_[2 ]; -// mutable since we need to acquire in HaveQueuedComposites +// mutable since we need to acquire in Dump() mutable pthread_mutex_t lock_;// State tracking progress since our last Dump(). These are mutable since
drmeventlistener.cpp +3 -0
@@ -20,10 +20,13 @@ #include "drmresources.h" #include <assert.h> +#include <errno.h> #include <linux/netlink.h> #include <sys/socket.h> #include <cutils/log.h> +#include <hardware/hardware.h> +#include <hardware/hwcomposer.h> #include <xf86drm.h> namespace android {
drmhwctwo.cpp +3 -3
@@ -557,7 +557,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { i = overlay_planes.erase(i); } - ret = compositor_.QueueComposition(std::move(composition)); + ret = compositor_.ApplyComposition(std::move(composition)); if (ret) { ALOGE("Failed to apply the frame composition ret=%d", ret); return HWC2::Error::BadParameter;
@@ -593,7 +593,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) { compositor_.CreateComposition(); composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); int ret = composition->SetDisplayMode(*mode); - ret = compositor_.QueueComposition(std::move(composition)); + ret = compositor_.ApplyComposition(std::move(composition)); if (ret) { ALOGE("Failed to queue dpms composition on %d", ret); return HWC2::Error::BadConfig;
@@ -673,7 +673,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) { compositor_.CreateComposition(); composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); composition->SetDpmsMode(dpms_value); - int ret = compositor_.QueueComposition(std::move(composition)); + int ret = compositor_.ApplyComposition(std::move(composition)); if (ret) { ALOGE("Failed to apply the dpms composition ret=%d", ret); return HWC2::Error::BadParameter;
drmresources.cpp +1 -53
72 lines not on this page · raw message
drmresources.h +0 -5
@@ -17,7 +17,6 @@#ifndef ANDROID_DRM_H_ #define ANDROID_DRM_H_ -#include "drmcompositor.h" #include "drmconnector.h" #include "drmcrtc.h" #include "drmencoder.h"
@@ -58,7 +57,6 @@ class DrmResources {DrmConnector *GetConnectorForDisplay (int display) const;DrmCrtc *GetCrtcForDisplay (int display) const;DrmPlane *GetPlane (uint32_t id) const; -DrmCompositor *compositor ();DrmEventListener *event_listener (); int GetPlaneProperty(const DrmPlane &plane, const char *prop_name,
@@ -69,8 +67,6 @@ class DrmResources { DrmProperty *property);uint32_t next_mode_id (); - int SetDisplayActiveMode(int display, const DrmMode &mode); -int SetDpmsMode (int display,uint64_t mode);int CreatePropertyBlob (void *data,size_t length,uint32_t *blob_id);int DestroyPropertyBlob (uint32_t blob_id);
@@ -89,7 +85,6 @@ class DrmResources { std::vector<std::unique_ptr<DrmEncoder>> encoders_; std::vector<std::unique_ptr<DrmCrtc>> crtcs_; std::vector<std::unique_ptr<DrmPlane>> planes_; -DrmCompositor compositor_;DrmEventListener event_listener_; std::pair<uint32_t, uint32_t> min_resolution_;
glworker.cpp +47 -5
95 lines not on this page · raw message
glworker.h +10 -0
@@ -64,6 +64,16 @@ class GLWorkerCompositor {bool Promote (); }; +struct { + EGLDisplay saved_egl_display = EGL_NO_DISPLAY; + EGLContext saved_egl_ctx = EGL_NO_CONTEXT; + EGLSurface saved_egl_read = EGL_NO_SURFACE; + EGLSurface saved_egl_draw = EGL_NO_SURFACE; + } private_; + +int BeginContext (); +int EndContext (); +CachedFramebuffer *FindCachedFramebuffer ( const sp<GraphicBuffer> &framebuffer); CachedFramebuffer *PrepareAndCacheFramebuffer(
Signature · 6 lines
2.11.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 2/6 drm_hwcomposer: Add support for IN_FENCE_FD property to DrmPlane
In reply to Robert FossAdd support for the IN_FENCE_FD property to DrmPlane.
--- drmplane.cpp | 8 ++++++++ drmplane.h | 2 ++ 2 files changed, 10 insertions(+)
drmplane.cpp +8 -0
@@ -126,6 +126,10 @@ int DrmPlane::Init() { if (ret) ALOGI("Could not get alpha property"); + ret = drm_->GetPlaneProperty(*this, "IN_FENCE_FD", &in_fence_fd_property_); + if (ret) + ALOGI("Could not get IN_FENCE_FD property"); + return 0; }
@@ -188,4 +192,8 @@ const DrmProperty &DrmPlane::rotation_property() const { const DrmProperty &DrmPlane::alpha_property() const { return alpha_property_; } + +const DrmProperty &DrmPlane::in_fence_fd_property() const { + return in_fence_fd_property_; +} }
drmplane.h +2 -0
@@ -54,6 +54,7 @@ class DrmPlane { const DrmProperty &src_h_property() const; const DrmProperty &rotation_property() const; const DrmProperty &alpha_property() const; + const DrmProperty &in_fence_fd_property() const; private: DrmResources *drm_;
@@ -75,6 +76,7 @@ class DrmPlane {DrmProperty src_h_property_;DrmProperty rotation_property_;DrmProperty alpha_property_; +DrmProperty in_fence_fd_property_; }; }
Signature · 6 lines
2.11.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 3/6 drm_hwcomposer: Submit in-fence to DRM
In reply to Robert FossAdd support for in-fences through the IN_FENCE_FD property. In-fences signal when their associated buffer may be read by DRM/KMS.
--- drmdisplaycompositor.cpp | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-)
drmdisplaycompositor.cpp +16 -19
@@ -529,6 +529,7 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, std::vector<size_t> &source_layers = comp_plane.source_layers(); int fb_id = -1; + int fence_fd = -1; DrmHwcRect<int> display_frame; DrmHwcRect<float> source_crop; uint64_t rotation = 0;
@@ -547,30 +548,12 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, break; } DrmHwcLayer &layer = layers[source_layers.front()]; - if (!test_only && layer.acquire_fence.get() >= 0) { - int acquire_fence = layer.acquire_fence.get(); - int total_fence_timeout = 0; - for (int i = 0; i < kAcquireWaitTries; ++i) { - int fence_timeout = kAcquireWaitTimeoutMs * (1 << i); - total_fence_timeout += fence_timeout; - ret = sync_wait(acquire_fence, fence_timeout); - if (ret) - ALOGW("Acquire fence %d wait %d failed (%d). Total time %d", - acquire_fence, i, ret, total_fence_timeout); - else - break; - } - if (ret) { - ALOGE("Failed to wait for acquire %d/%d", acquire_fence, ret); - break; - } - layer.acquire_fence.Close(); - } if (!layer.buffer) { ALOGE("Expected a valid framebuffer for pset"); break; } fb_id = layer.buffer->fb_id; + fence_fd = layer.acquire_fence.get(); display_frame = layer.display_frame; source_crop = layer.source_crop; if (layer.blending == DrmHwcBlending::kPreMult)
@@ -587,7 +570,21 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, rotation |= 1 << DRM_ROTATE_180; else if (layer.transform & DrmHwcTransform::kRotate270) rotation |= 1 << DRM_ROTATE_270; + + if (fence_fd != -1) { + int prop_id = plane->in_fence_fd_property().id(); + if (prop_id == 0) { + ALOGE("Failed to get IN_FENCE_FD property id"); + break; + } + ret = drmModeAtomicAddProperty(pset, plane->id(), prop_id, fence_fd); + if (ret < 0) { + ALOGE("Failed to add IN_FENCE_FD property to pset: %d", ret); + break; + } + } } + // Disable the plane if there's no framebuffer if (fb_id < 0) { ret = drmModeAtomicAddProperty(pset, plane->id(),
Signature · 6 lines
2.11.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 4/6 drm_hwcomposer: Add FENCE_OUT_PTR property to DrmCrtc
In reply to Robert FossAdd support for handling the FENCE_OUT_PTR property to DrmCrtc
--- drmcrtc.cpp | 10 ++++++++++ drmcrtc.h | 2 ++ 2 files changed, 12 insertions(+)
drmcrtc.cpp +10 -0
@@ -51,6 +51,12 @@ int DrmCrtc::Init() { ALOGE("Failed to get MODE_ID property"); return ret; } + + ret = drm_->GetCrtcProperty(*this, "OUT_FENCE_PTR", &out_fence_ptr_property_); + if (ret) { + ALOGE("Failed to get OUT_FENCE_PTR property"); + return ret; + } return 0; }
@@ -81,4 +87,8 @@ const DrmProperty &DrmCrtc::active_property() const { const DrmProperty &DrmCrtc::mode_property() const { return mode_property_; } + +const DrmProperty &DrmCrtc::out_fence_ptr_property() const { + return out_fence_ptr_property_; +} }
drmcrtc.h +2 -0
@@ -45,6 +45,7 @@ class DrmCrtc { const DrmProperty &active_property() const; const DrmProperty &mode_property() const; + const DrmProperty &out_fence_ptr_property() const; private: DrmResources *drm_;
@@ -63,6 +64,7 @@ class DrmCrtc {DrmProperty active_property_;DrmProperty mode_property_; +DrmProperty out_fence_ptr_property_; }; }
Signature · 6 lines
2.11.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 5/6 drm_hwcomposer: Add GetCrtcCount function
In reply to Robert FossThis GetCrtrcCount helper functions enables convenient fetching of the number of Crtcs from DrmResources.
--- drmresources.cpp | 4 ++++ drmresources.h | 1 + 2 files changed, 5 insertions(+)
drmresources.cpp +4 -0
@@ -241,6 +241,10 @@ DrmPlane *DrmResources::GetPlane(uint32_t id) const { return NULL; } +uint32_t DrmResources::GetCrtcCount() const { + return (uint32_t) crtcs_.size(); +} + uint32_t DrmResources::next_mode_id() { return ++mode_id_; }
drmresources.h +1 -0
@@ -66,6 +66,7 @@ class DrmResources { int GetConnectorProperty(const DrmConnector &connector, const char *prop_name,DrmProperty *property); + uint32_t GetCrtcCount() const; uint32_t next_mode_id(); int CreatePropertyBlob(void *data, size_t length, uint32_t *blob_id);
Signature · 6 lines
2.11.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 6/6 drm_hwcomposer: Add out-fence support
In reply to Robert FossAdd support for out-fences through the OUT_FENCE_PTR property. Out-fences signal when their associated buffer may be read by a device.
--- drmdisplaycomposition.h | 9 +++++++++ drmdisplaycompositor.cpp | 16 ++++++++++++++++ drmhwctwo.cpp | 9 ++------- 3 files changed, 27 insertions(+), 7 deletions(-)
drmdisplaycomposition.h +9 -0
@@ -189,6 +189,14 @@ class DrmDisplayComposition {return planner_; } +int take_out_fence () { +return out_fence_.Release (); + } + +void set_out_fence (int out_fence) { + out_fence_.Set (dup (out_fence)); + } + void Dump(std::ostringstream *out) const; private:
@@ -215,6 +223,7 @@ class DrmDisplayComposition {int timeline_current_ =0 ;int timeline_squash_done_ =0 ;int timeline_pre_comp_done_ =0 ; +UniqueFd out_fence_ =-1 ;bool geometry_changed_; std::vector<DrmHwcLayer> layers_;
drmdisplaycompositor.cpp +16 -0
@@ -492,6 +492,7 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, display_comp->composition_planes(); std::vector<DrmCompositionRegion> &pre_comp_regions = display_comp->pre_comp_regions(); + uint64_t out_fences[drm_->GetCrtcCount()]; DrmConnector *connector = drm_->GetConnectorForDisplay(display_); if (!connector) {
@@ -510,6 +511,16 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, return -ENOMEM; } + if (crtc->out_fence_ptr_property().id() != 0) { + ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->out_fence_ptr_property().id(), + (uint64_t) &out_fences[0]); + if (ret < 0) { + ALOGE("Failed to add OUT_FENCE_PTR property to pset: %d", ret); + drmModeAtomicFree(pset); + return ret; + } + } + if (mode_.needs_modeset) { ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->mode_property().id(), mode_.blob_id) < 0 ||
@@ -708,6 +719,11 @@ out: mode_.needs_modeset = false; } + if (crtc->out_fence_ptr_property().id()) { + display_comp->set_out_fence((int) out_fences[crtc->pipe()]); + close((int) out_fences[crtc->pipe()]); + } + return ret; }
drmhwctwo.cpp +2 -7
@@ -557,19 +557,14 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { i = overlay_planes.erase(i); } + AddFenceToRetireFence(composition->take_out_fence()); + ret = compositor_.ApplyComposition(std::move(composition)); if (ret) { ALOGE("Failed to apply the frame composition ret=%d", ret); return HWC2::Error::BadParameter; } - // Now that the release fences have been generated by the compositor, make - // sure they're managed properly - for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) { - l.second->manage_release_fence(); - AddFenceToRetireFence(l.second->release_fence()); - } - // The retire fence returned here is for the last frame, so return it and // promote the next retire fence *retire_fence = retire_fence_.Release();
Signature · 6 lines
2.11.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel