From 79cf9ef931362ea18a4352ae019176971f492cf1 Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Tue, 14 May 2019 21:37:47 +0800 Subject: [PATCH 01/20] Check if hwc is drm master by default in initialization Use the method drmAuthMagic to check if hwc is already DRM master or not. Change-Id: I1931017e1223ae550c52816e6b2a64c74bdf9190 Tests: Work well on celadon with kernel 4.19.19 Tracked-On: None Signed-off-by: Shaofeng Tang --- common/core/gpudevice.cpp | 3 ++- wsi/displaymanager.h | 2 ++ wsi/drm/drmdisplaymanager.cpp | 22 ++++++++++++++++++++++ wsi/drm/drmdisplaymanager.h | 2 ++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/common/core/gpudevice.cpp b/common/core/gpudevice.cpp index 7ceaf516..d125b6ac 100644 --- a/common/core/gpudevice.cpp +++ b/common/core/gpudevice.cpp @@ -81,7 +81,8 @@ bool GpuDevice::Initialize() { ETRACE("Failed to open %s", HWC_LOCK_FILE); // HWC should become drm master and start to commit. // if hwc.lock is not available - display_manager_->setDrmMaster(true); + if (!display_manager_->IsDrmMasterByDefault()) + display_manager_->setDrmMaster(true); ResetAllDisplayCommit(true); } diff --git a/wsi/displaymanager.h b/wsi/displaymanager.h index 3ed0542d..98eff225 100644 --- a/wsi/displaymanager.h +++ b/wsi/displaymanager.h @@ -53,6 +53,8 @@ class DisplayManager { // manager until ForceRefresh is called. virtual void IgnoreUpdates() = 0; + virtual bool IsDrmMasterByDefault() = 0; + virtual void setDrmMaster(bool must_set) = 0; virtual void DropDrmMaster() = 0; diff --git a/wsi/drm/drmdisplaymanager.cpp b/wsi/drm/drmdisplaymanager.cpp index c4c11993..62f874d0 100644 --- a/wsi/drm/drmdisplaymanager.cpp +++ b/wsi/drm/drmdisplaymanager.cpp @@ -444,6 +444,28 @@ void DrmDisplayManager::IgnoreUpdates() { } } +bool DrmDisplayManager::IsDrmMasterByDefault() { + spin_lock_.lock(); + if (drm_master_) { + spin_lock_.unlock(); + return drm_master_; + } + drm_magic_t magic = 0; + int ret = 0; + ret = drmGetMagic(fd_, &magic); + if (ret) + ETRACE("Failed to call drmGetMagic : %s", PRINTERROR()); + else { + ret = drmAuthMagic(fd_, magic); + if (ret) + ETRACE("Failed to call drmAuthMagic : %s", PRINTERROR()); + else + drm_master_ = true; + } + spin_lock_.unlock(); + return drm_master_; +} + void DrmDisplayManager::setDrmMaster(bool must_set) { spin_lock_.lock(); if (drm_master_) { diff --git a/wsi/drm/drmdisplaymanager.h b/wsi/drm/drmdisplaymanager.h index 1b95f519..0ae6cf18 100644 --- a/wsi/drm/drmdisplaymanager.h +++ b/wsi/drm/drmdisplaymanager.h @@ -71,6 +71,8 @@ class DrmDisplayManager : public HWCThread, public DisplayManager { void IgnoreUpdates() override; + bool IsDrmMasterByDefault() override; + void setDrmMaster(bool must_set) override; void DropDrmMaster() override; From fb2f4a797d669da2eb989dea8fb8209db1599ec7 Mon Sep 17 00:00:00 2001 From: "Yuanzhe, Liu" Date: Thu, 16 May 2019 15:21:01 +0800 Subject: [PATCH 02/20] Fix klocwork issue in GFX Domain Add a null checking before dereferencing the pointer. Test: Compile successful Change-Id: Ib5e295b2d1f3416ab99f1a0fabf76013d7f8e002 Tracked-On: https://jira.devtools.intel.com/browse/OAM-80450 Sighed-off-by: Yuanzhe, Liu --- wsi/drm/drmdisplaymanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsi/drm/drmdisplaymanager.cpp b/wsi/drm/drmdisplaymanager.cpp index 62f874d0..b21bf00f 100644 --- a/wsi/drm/drmdisplaymanager.cpp +++ b/wsi/drm/drmdisplaymanager.cpp @@ -75,7 +75,7 @@ bool DrmDisplayManager::Initialize() { } ScopedDrmResourcesPtr res(drmModeGetResources(fd_)); - if (res->count_crtcs == 0) + if (res && res->count_crtcs == 0) return false; for (int32_t i = 0; i < res->count_crtcs; ++i) { From af1d39adad10beb69bf7bf7fbbf2089c46e99eec Mon Sep 17 00:00:00 2001 From: "Yang, Dong" Date: Mon, 6 May 2019 14:03:22 +0800 Subject: [PATCH 03/20] use glFlush to replace eglCreateSyncKHR For performance purpose Change-Id: I152d3838003e2b4efddc2418057e42e49fc0bb8f Tracked-On: https://jira.devtools.intel.com/browse/OAM-76069 Signed-off-by: Yang, Dong Signed-off-by: Lin Johnson --- common/compositor/gl/egloffscreencontext.cpp | 30 +++++++++++--------- common/compositor/gl/egloffscreencontext.h | 2 +- common/compositor/gl/glrenderer.cpp | 2 +- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/common/compositor/gl/egloffscreencontext.cpp b/common/compositor/gl/egloffscreencontext.cpp index 5bbd6e1c..f46c5f99 100644 --- a/common/compositor/gl/egloffscreencontext.cpp +++ b/common/compositor/gl/egloffscreencontext.cpp @@ -87,23 +87,27 @@ bool EGLOffScreenContext::MakeCurrent() { return true; } -EGLint EGLOffScreenContext::GetSyncFD() { +EGLint EGLOffScreenContext::GetSyncFD(bool onScreen) { EGLint sync_fd = -1; - EGLSyncKHR egl_sync = - eglCreateSyncKHR(egl_display_, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); - if (egl_sync == EGL_NO_SYNC_KHR) { - ETRACE("Failed to make sync object."); - return -1; - } + if (onScreen) + glFlush(); + else { + EGLSyncKHR egl_sync = + eglCreateSyncKHR(egl_display_, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); + if (egl_sync == EGL_NO_SYNC_KHR) { + ETRACE("Failed to make sync object."); + return -1; + } - sync_fd = eglDupNativeFenceFDANDROID(egl_display_, egl_sync); - if (sync_fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { - ETRACE("Failed to duplicate native fence object."); - sync_fd = -1; - } + sync_fd = eglDupNativeFenceFDANDROID(egl_display_, egl_sync); + if (sync_fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { + ETRACE("Failed to duplicate native fence object."); + sync_fd = -1; + } - eglDestroySyncKHR(egl_display_, egl_sync); + eglDestroySyncKHR(egl_display_, egl_sync); + } return sync_fd; } diff --git a/common/compositor/gl/egloffscreencontext.h b/common/compositor/gl/egloffscreencontext.h index 464a3214..7ad1d3ce 100644 --- a/common/compositor/gl/egloffscreencontext.h +++ b/common/compositor/gl/egloffscreencontext.h @@ -28,7 +28,7 @@ class EGLOffScreenContext { bool Init(); - EGLint GetSyncFD(); + EGLint GetSyncFD(bool onScreen); EGLDisplay GetDisplay() const { return egl_display_; diff --git a/common/compositor/gl/glrenderer.cpp b/common/compositor/gl/glrenderer.cpp index 7ada3d04..160f256f 100644 --- a/common/compositor/gl/glrenderer.cpp +++ b/common/compositor/gl/glrenderer.cpp @@ -173,7 +173,7 @@ bool GLRenderer::Draw(const std::vector &render_states, glDisable(GL_SCISSOR_TEST); if (!disable_explicit_sync_) - surface->SetNativeFence(context_.GetSyncFD()); + surface->SetNativeFence(context_.GetSyncFD(surface->IsOnScreen())); surface->ResetDamage(); #ifdef COMPOSITOR_TRACING From 76505de89850c6de64b74836d748bfe0405c4d51 Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Mon, 20 May 2019 10:47:07 +0800 Subject: [PATCH 04/20] Trace timestamp for first commit after DRM-Master is reset Print the timestamp for commiting the first frame after DRM-Master is reset Change-Id: I394916e7abf225539e3842dcce813373543ba1d6 Tests: Work well with KMSCube Tracked-On: https://jira.devtools.intel.com/browse/OAM-79556 Signed-off-by: Shaofeng Tang --- common/core/gpudevice.cpp | 10 ++++++++++ common/display/displayqueue.cpp | 17 +++++++++++++++-- common/display/displayqueue.h | 7 +++++++ public/gpudevice.h | 2 ++ public/nativedisplay.h | 3 +++ wsi/drm/drmdisplay.cpp | 5 ++++- wsi/drm/drmdisplay.h | 2 ++ 7 files changed, 43 insertions(+), 3 deletions(-) diff --git a/common/core/gpudevice.cpp b/common/core/gpudevice.cpp index d125b6ac..59c3d25e 100644 --- a/common/core/gpudevice.cpp +++ b/common/core/gpudevice.cpp @@ -130,6 +130,15 @@ bool GpuDevice::EnableDRMCommit(bool enable, uint32_t display_id) { return ret; } +void GpuDevice::MarkDisplayForFirstCommit() { + size_t size = total_displays_.size(); + for (size_t i = 0; i < size; i++) { + if (total_displays_.at(i)->IsConnected()) { + total_displays_.at(i)->MarkFirstCommit(); + } + } +} + bool GpuDevice::ResetDrmMaster(bool drop_master) { bool ret = true; if (drop_master) { @@ -149,6 +158,7 @@ bool GpuDevice::ResetDrmMaster(bool drop_master) { // In case of setDrmMaster or the lock file is not exist. // Re-set DRM Master true. display_manager_->setDrmMaster(false); + MarkDisplayForFirstCommit(); ResetAllDisplayCommit(true); DisableWatch(); diff --git a/common/display/displayqueue.cpp b/common/display/displayqueue.cpp index 011027eb..0ca19a1a 100644 --- a/common/display/displayqueue.cpp +++ b/common/display/displayqueue.cpp @@ -19,7 +19,7 @@ #include #include #include - +#include #include #include "displayplanemanager.h" @@ -639,6 +639,14 @@ void DisplayQueue::InitializeOverlayLayers( } } +void DisplayQueue::TraceFirstCommit() { + struct timeval te; + gettimeofday(&te, NULL); // get current time + long long milliseconds = + te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds + ITRACE("First frame is Committed at %lld.", milliseconds); +} + bool DisplayQueue::QueueUpdate(std::vector& source_layers, int32_t* retire_fence, bool* ignore_clone_update, PixelUploaderCallback* call_back, @@ -899,10 +907,15 @@ bool DisplayQueue::QueueUpdate(std::vector& source_layers, int32_t fence = 0; bool fence_released = false; - if (!IsIgnoreUpdates()) + if (!IsIgnoreUpdates()) { composition_passed = display_->Commit( current_composition_planes, previous_plane_state_, disable_explictsync, kms_fence_, &fence, &fence_released); + if (first_commit_) { + TraceFirstCommit(); + first_commit_ = false; + } + } if (fence_released) { kms_fence_ = 0; diff --git a/common/display/displayqueue.h b/common/display/displayqueue.h index cfadabc1..1223ca01 100644 --- a/common/display/displayqueue.h +++ b/common/display/displayqueue.h @@ -104,6 +104,10 @@ class DisplayQueue { void UpdateScalingRatio(uint32_t primary_width, uint32_t primary_height, uint32_t display_width, uint32_t display_height); + void MarkFirstCommit() { + first_commit_ = true; + } + void SetCloneMode(bool cloned); void RotateDisplay(HWCRotation rotation); @@ -353,9 +357,12 @@ class DisplayQueue { bool& has_video_layer, bool& has_cursor_layer, bool& re_validate_commit, bool& idle_frame); + void TraceFirstCommit(); + Compositor compositor_; uint32_t gpu_fd_; uint32_t brightness_; + bool first_commit_ = false; float color_transform_matrix_[16]; HWCColorTransform color_transform_hint_; uint32_t contrast_; diff --git a/public/gpudevice.h b/public/gpudevice.h index b8ff7d40..9d113d22 100644 --- a/public/gpudevice.h +++ b/public/gpudevice.h @@ -117,6 +117,8 @@ class GpuDevice : public HWCThread { void ResetAllDisplayCommit(bool enable); + void MarkDisplayForFirstCommit(); + enum InitializationType { kUnInitialized = 0, // Nothing Initialized. kInitialized = 1 << 1 // Everything Initialized diff --git a/public/nativedisplay.h b/public/nativedisplay.h index c43bcf92..bad3251c 100644 --- a/public/nativedisplay.h +++ b/public/nativedisplay.h @@ -428,6 +428,9 @@ class NativeDisplay { return false; } + virtual void MarkFirstCommit() { + } + protected: friend class PhysicalDisplay; friend class GpuDevice; diff --git a/wsi/drm/drmdisplay.cpp b/wsi/drm/drmdisplay.cpp index a98e89fa..252951fb 100644 --- a/wsi/drm/drmdisplay.cpp +++ b/wsi/drm/drmdisplay.cpp @@ -77,6 +77,10 @@ bool DrmDisplay::InitializeDisplay() { return true; } +void DrmDisplay::MarkFirstCommit() { + display_queue_->MarkFirstCommit(); +} + std::vector DrmDisplay::FindExtendedBlocksForTag(uint8_t *edid, uint8_t block_tag) { int current_block; @@ -588,7 +592,6 @@ bool DrmDisplay::CommitFrame( DrmPlane *plane = static_cast(comp_plane.GetDisplayPlane()); if (plane->InUse()) continue; - plane->Disable(pset); } diff --git a/wsi/drm/drmdisplay.h b/wsi/drm/drmdisplay.h index d02cb3eb..181b3e9e 100644 --- a/wsi/drm/drmdisplay.h +++ b/wsi/drm/drmdisplay.h @@ -129,6 +129,8 @@ class DrmDisplay : public PhysicalDisplay { return planes_updated_; } + void MarkFirstCommit() override; + private: void ShutDownPipe(); void GetDrmObjectPropertyValue(const char *name, From a693f6d66fa842b6ae17009759e0c1d94663525a Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Sat, 18 May 2019 13:23:49 +0800 Subject: [PATCH 05/20] Disable all not-in-used plane once DRM Master is reset Disable all not-in-used planed once DRM Master is reset. To avoid that some surface will is committed by other APP are remained. Change-Id: Ia2b28303ea0eaa6deda46e6d3a8d7a04674ea394 Tests: Work well with Kmscube testing APP. Tracked-On: None Signed-off-by: Shaofeng Tang --- common/display/displayplanemanager.cpp | 10 ++++++++++ common/display/displayplanemanager.h | 2 ++ common/display/displayqueue.cpp | 16 ++++------------ common/display/displayqueue.h | 9 ++------- wsi/drm/drmdisplay.cpp | 22 +++++++++++++++++----- wsi/drm/drmdisplay.h | 7 ++++++- wsi/drm/drmplane.h | 3 +-- 7 files changed, 42 insertions(+), 27 deletions(-) diff --git a/common/display/displayplanemanager.cpp b/common/display/displayplanemanager.cpp index 5104c66d..2d678e10 100644 --- a/common/display/displayplanemanager.cpp +++ b/common/display/displayplanemanager.cpp @@ -19,6 +19,7 @@ #include "displayplanemanager.h" #include "displayplane.h" +#include "drm/drmplane.h" #include "factory.h" #include "hwctrace.h" #include "nativesurface.h" @@ -67,6 +68,15 @@ bool DisplayPlaneManager::Initialize(uint32_t width, uint32_t height) { return status; } +void DisplayPlaneManager::ResetPlanes(drmModeAtomicReqPtr pset) { + for (auto j = overlay_planes_.begin(); j < overlay_planes_.end(); j++) { + if (!j->get()->InUse()) { + DrmPlane *drmplane = (DrmPlane *)(j->get()); + drmplane->Disable(pset); + } + } +} + bool DisplayPlaneManager::ValidateLayers( std::vector &layers, int add_index, bool disable_overlay, bool *commit_checked, bool *re_validation_needed, diff --git a/common/display/displayplanemanager.h b/common/display/displayplanemanager.h index a25fd2ee..a20144b5 100644 --- a/common/display/displayplanemanager.h +++ b/common/display/displayplanemanager.h @@ -122,6 +122,8 @@ class DisplayPlaneManager { void ReleaseUnreservedPlanes(std::vector &reserved_planes); + void ResetPlanes(drmModeAtomicReqPtr pset); + private: DisplayPlaneState *GetLastUsedOverlay(DisplayPlaneStateList &composition); bool FallbacktoGPU(DisplayPlane *target_plane, OverlayLayer *layer, diff --git a/common/display/displayqueue.cpp b/common/display/displayqueue.cpp index 0ca19a1a..36758e25 100644 --- a/common/display/displayqueue.cpp +++ b/common/display/displayqueue.cpp @@ -639,14 +639,6 @@ void DisplayQueue::InitializeOverlayLayers( } } -void DisplayQueue::TraceFirstCommit() { - struct timeval te; - gettimeofday(&te, NULL); // get current time - long long milliseconds = - te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds - ITRACE("First frame is Committed at %lld.", milliseconds); -} - bool DisplayQueue::QueueUpdate(std::vector& source_layers, int32_t* retire_fence, bool* ignore_clone_update, PixelUploaderCallback* call_back, @@ -911,10 +903,6 @@ bool DisplayQueue::QueueUpdate(std::vector& source_layers, composition_passed = display_->Commit( current_composition_planes, previous_plane_state_, disable_explictsync, kms_fence_, &fence, &fence_released); - if (first_commit_) { - TraceFirstCommit(); - first_commit_ = false; - } } if (fence_released) { @@ -1261,6 +1249,10 @@ void DisplayQueue::SetCloneMode(bool cloned) { clone_rendered_ = false; } +void DisplayQueue::ResetPlanes(drmModeAtomicReqPtr pset) { + display_plane_manager_->ResetPlanes(pset); +} + void DisplayQueue::IgnoreUpdates() { idle_tracker_.idle_frames_ = 0; idle_tracker_.state_ = FrameStateTracker::kIgnoreUpdates; diff --git a/common/display/displayqueue.h b/common/display/displayqueue.h index 1223ca01..e6aaaae5 100644 --- a/common/display/displayqueue.h +++ b/common/display/displayqueue.h @@ -104,16 +104,14 @@ class DisplayQueue { void UpdateScalingRatio(uint32_t primary_width, uint32_t primary_height, uint32_t display_width, uint32_t display_height); - void MarkFirstCommit() { - first_commit_ = true; - } - void SetCloneMode(bool cloned); void RotateDisplay(HWCRotation rotation); void IgnoreUpdates(); + void ResetPlanes(drmModeAtomicReqPtr pset); + void PresentClonedCommit(DisplayQueue* queue); const DisplayPlaneStateList& GetCurrentCompositionPlanes() const { @@ -357,12 +355,9 @@ class DisplayQueue { bool& has_video_layer, bool& has_cursor_layer, bool& re_validate_commit, bool& idle_frame); - void TraceFirstCommit(); - Compositor compositor_; uint32_t gpu_fd_; uint32_t brightness_; - bool first_commit_ = false; float color_transform_matrix_[16]; HWCColorTransform color_transform_hint_; uint32_t contrast_; diff --git a/wsi/drm/drmdisplay.cpp b/wsi/drm/drmdisplay.cpp index 252951fb..5c034242 100644 --- a/wsi/drm/drmdisplay.cpp +++ b/wsi/drm/drmdisplay.cpp @@ -16,6 +16,7 @@ #include "drmdisplay.h" +#include #include #include #include @@ -77,10 +78,6 @@ bool DrmDisplay::InitializeDisplay() { return true; } -void DrmDisplay::MarkFirstCommit() { - display_queue_->MarkFirstCommit(); -} - std::vector DrmDisplay::FindExtendedBlocksForTag(uint8_t *edid, uint8_t block_tag) { int current_block; @@ -492,6 +489,14 @@ bool DrmDisplay::ContainConnector(const uint32_t connector_id) { return (connector_ == connector_id); } +void DrmDisplay::TraceFirstCommit() { + struct timeval te; + gettimeofday(&te, NULL); // get current time + long long milliseconds = + te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds + ITRACE("First frame is Committed at %lld.", milliseconds); +} + bool DrmDisplay::Commit( const DisplayPlaneStateList &composition_planes, const DisplayPlaneStateList &previous_composition_planes, @@ -510,6 +515,10 @@ bool DrmDisplay::Commit( return false; } + // Disable not-in-used plane once DRM master is reset + if (first_commit_) + display_queue_->ResetPlanes(pset.get()); + if (display_state_ & kNeedsModeset) { if (!ApplyPendingModeset(pset.get())) { ETRACE("Failed to Modeset."); @@ -541,7 +550,10 @@ bool DrmDisplay::Commit( *commit_fence = 0; } #endif - + if (first_commit_) { + TraceFirstCommit(); + first_commit_ = false; + } return true; } diff --git a/wsi/drm/drmdisplay.h b/wsi/drm/drmdisplay.h index 181b3e9e..e96e0923 100644 --- a/wsi/drm/drmdisplay.h +++ b/wsi/drm/drmdisplay.h @@ -129,7 +129,9 @@ class DrmDisplay : public PhysicalDisplay { return planes_updated_; } - void MarkFirstCommit() override; + void MarkFirstCommit() override { + first_commit_ = true; + } private: void ShutDownPipe(); @@ -164,6 +166,8 @@ class DrmDisplay : public PhysicalDisplay { uint8_t block_tag); void DrmConnectorGetDCIP3Support(const ScopedDrmObjectPropertyPtr &props); + void TraceFirstCommit(); + uint32_t crtc_id_ = 0; uint32_t mmWidth_ = 0; uint32_t mmHeight_ = 0; @@ -190,6 +194,7 @@ class DrmDisplay : public PhysicalDisplay { int64_t broadcastrgb_automatic_ = -1; uint32_t flags_ = DRM_MODE_ATOMIC_ALLOW_MODESET; bool planes_updated_ = false; + bool first_commit_ = false; HWCContentProtection current_protection_support_ = HWCContentProtection::kUnSupported; HWCContentProtection desired_protection_support_ = diff --git a/wsi/drm/drmplane.h b/wsi/drm/drmplane.h index 52c0b342..3a3d07ef 100644 --- a/wsi/drm/drmplane.h +++ b/wsi/drm/drmplane.h @@ -22,12 +22,11 @@ #include -#include - #include #include "displayplane.h" #include "drmbuffer.h" +#include "drmscopedtypes.h" namespace hwcomposer { From d9dff961aab7717c65e44e4aab8281638c539446 Mon Sep 17 00:00:00 2001 From: Wan Shuang Date: Tue, 21 May 2019 14:34:41 +0800 Subject: [PATCH 06/20] Fixed the black stripe issue during video playback control bar popup Let HWC validate layers if visible layers changed from last frame and initialize instances and their linkage of DisplayPlaneState object and OverlayPlane object properly. Change-Id: I3b6eba2ecec2ef8f3a06db50f8faea070d998604 Tests: Video playback control bar pop up without black flicker Tracked-On: https://jira.devtools.intel.com/browse/OAM-72226 Signed-off-by: Wan Shuang --- common/display/displayplanemanager.cpp | 9 ++++++++- common/display/displayqueue.cpp | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/common/display/displayplanemanager.cpp b/common/display/displayplanemanager.cpp index 2d678e10..e661ac95 100644 --- a/common/display/displayplanemanager.cpp +++ b/common/display/displayplanemanager.cpp @@ -238,8 +238,15 @@ bool DisplayPlaneManager::ValidateLayers( validate_final_layers = !(last_plane.GetOffScreenTarget()); ResetPlaneTarget(last_plane, commit_planes.back()); + } else { + // Plane separation is needed + if (!layer->IsSolidColor() && !layer->IsVideoLayer()) { + // Current plane is not the video layer and not the solid + // color layer as well. Initialize the DisplayPlaneState + // object and link it with OverlayPlane object. + ResetPlaneTarget(last_plane, commit_planes.back()); + } } - break; } else { if (composition.empty()) { diff --git a/common/display/displayqueue.cpp b/common/display/displayqueue.cpp index 36758e25..abf978d5 100644 --- a/common/display/displayqueue.cpp +++ b/common/display/displayqueue.cpp @@ -686,6 +686,11 @@ bool DisplayQueue::QueueUpdate(std::vector& source_layers, } } + if (previous_size != size) { + // Validate layers if visible layers changed from last frame. + validate_layers = true; + } + if (idle_frame) { if ((add_index != -1) || (remove_index != -1) || re_validate_commit) { idle_frame = false; From 21d4fac4f92c46bf2b6fa321e1e126f6ce62ebeb Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Mon, 27 May 2019 20:41:23 +0800 Subject: [PATCH 07/20] Update rendering area when surface_damage is empty When surface_damage is empty, it mean the layer is not changed. the rendering area must be set as empty to avoid re-render a unchanged layer. Test: Work well for benchmark T-Rex and Manhattan. Change-Id: I8abee7408b1338617d85e7af6696e42375e7d788 Tracked-On: https://jira.devtools.intel.com/browse/OAM-80208 Signed-off-by: Shaofeng Tang --- common/core/hwclayer.cpp | 58 +++++++--------------------------------- os/android/iahwc2.cpp | 9 +++---- 2 files changed, 13 insertions(+), 54 deletions(-) diff --git a/common/core/hwclayer.cpp b/common/core/hwclayer.cpp index c2771935..1d7c26d4 100644 --- a/common/core/hwclayer.cpp +++ b/common/core/hwclayer.cpp @@ -106,21 +106,20 @@ void HwcLayer::SetDisplayFrame(const HwcRect& display_frame, void HwcLayer::SetSurfaceDamage(const HwcRegion& surface_damage) { uint32_t rects = surface_damage.size(); state_ |= kLayerContentChanged; + state_ |= kSurfaceDamageChanged; HwcRect rect; ResetRectToRegion(surface_damage, rect); if (rects == 1) { if ((rect.top == 0) && (rect.bottom == 0) && (rect.left == 0) && (rect.right == 0)) { state_ &= ~kLayerContentChanged; - state_ &= ~kSurfaceDamageChanged; UpdateRenderingDamage(rect, rect, true); surface_damage_.reset(); return; - } else { - state_ |= kSurfaceDamageChanged; } } else if (rects == 0) { rect = display_frame_; + // damage is assigned with display_frame, no need to transform state_ &= ~kSurfaceDamageChanged; } @@ -265,51 +264,12 @@ void HwcLayer::SufaceDamageTransfrom() { translated_damage.top = translated_damage.top * ratioh + 0.5; translated_damage.bottom = translated_damage.bottom * ratioh + 0.5; - if (transform_ == hwcomposer::HWCTransform::kTransform270) { - ox = display_frame_.left; - oy = display_frame_.bottom; - current_rendering_damage_.left = ox + translated_damage.top; - current_rendering_damage_.top = oy - translated_damage.right; - current_rendering_damage_.right = ox + translated_damage.bottom; - current_rendering_damage_.bottom = oy - translated_damage.left; - } else if (transform_ == hwcomposer::HWCTransform::kTransform180) { - ox = display_frame_.right; - oy = display_frame_.bottom; - current_rendering_damage_.left = ox - translated_damage.right; - current_rendering_damage_.top = oy - translated_damage.bottom; - current_rendering_damage_.right = ox - translated_damage.left; - current_rendering_damage_.bottom = oy - translated_damage.top; - } else if (transform_ & hwcomposer::HWCTransform::kTransform90) { - if (transform_ & hwcomposer::HWCTransform::kReflectX) { - ox = display_frame_.left; - oy = display_frame_.top; - current_rendering_damage_.left = ox + translated_damage.top; - current_rendering_damage_.top = oy + translated_damage.left; - current_rendering_damage_.right = ox + translated_damage.bottom; - current_rendering_damage_.bottom = oy + translated_damage.right; - } else if (transform_ & hwcomposer::HWCTransform::kReflectY) { - ox = display_frame_.right; - oy = display_frame_.bottom; - current_rendering_damage_.left = ox - translated_damage.bottom; - current_rendering_damage_.top = oy - translated_damage.right; - current_rendering_damage_.right = ox - translated_damage.top; - current_rendering_damage_.bottom = oy - translated_damage.left; - } else { - ox = display_frame_.right; - oy = display_frame_.top; - current_rendering_damage_.left = ox - translated_damage.bottom; - current_rendering_damage_.top = oy + translated_damage.left; - current_rendering_damage_.right = ox - translated_damage.top; - current_rendering_damage_.bottom = oy + translated_damage.right; - } - } else if (transform_ == 0) { - ox = display_frame_.left; - oy = display_frame_.top; - current_rendering_damage_.left = ox + translated_damage.left; - current_rendering_damage_.top = oy + translated_damage.top; - current_rendering_damage_.right = ox + translated_damage.right; - current_rendering_damage_.bottom = oy + translated_damage.bottom; - } + ox = display_frame_.left; + oy = display_frame_.top; + current_rendering_damage_.left = ox + translated_damage.left; + current_rendering_damage_.top = oy + translated_damage.top; + current_rendering_damage_.right = ox + translated_damage.right; + current_rendering_damage_.bottom = oy + translated_damage.bottom; #ifdef RECT_DAMAGE_TRACING IRECTDAMAGETRACE( "Re-calucated current_rendering_damage_ (LTWH): %d, %d, %d, %d", @@ -317,6 +277,8 @@ void HwcLayer::SufaceDamageTransfrom() { (current_rendering_damage_.right - current_rendering_damage_.left), (current_rendering_damage_.bottom - current_rendering_damage_.top)); #endif + } else { + current_rendering_damage_ = translated_damage; } } diff --git a/os/android/iahwc2.cpp b/os/android/iahwc2.cpp index bae818b1..02fe3d22 100644 --- a/os/android/iahwc2.cpp +++ b/os/android/iahwc2.cpp @@ -949,12 +949,9 @@ HWC2::Error IAHWC2::Hwc2Layer::SetLayerSurfaceDamage(hwc_region_t damage) { hwcomposer::HwcRegion hwc_region; for (size_t rect = 0; rect < num_rects; ++rect) { - if (!(damage.rects[rect].left == 0 && damage.rects[rect].top == 0 && - damage.rects[rect].right == 0 && damage.rects[rect].bottom == 0)) { - hwc_region.emplace_back(damage.rects[rect].left, damage.rects[rect].top, - damage.rects[rect].right, - damage.rects[rect].bottom); - } + hwc_region.emplace_back(damage.rects[rect].left, damage.rects[rect].top, + damage.rects[rect].right, + damage.rects[rect].bottom); } hwc_layer_.SetSurfaceDamage(hwc_region); From 99f93523b5d0ecb6f1a25cf9c23ef05068af48e4 Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Mon, 13 May 2019 21:00:13 +0800 Subject: [PATCH 08/20] Calculate surface_damage rotate in overlaylayer with plane_transform_ plane_transform_ is verified in Overlaylayer with plane rotate and hwclayer rotate. surface damage should be calculated according to plane_transform_. A special case for rotate_180, the damage should not be changed. this commit is fix the rotate issue which is reproduced by the commit bc2b7b5fd370b4490241bd36f704e79aa5b3dcb5 Remain issue: On rotate 180, cursor location is shown incorrectly. Change-Id: I6a6117823228f3a7c77e0f028e676a7be1399d89 Tests: Work well on extend mode with rotate_90, 180 and 270 Tracked-On: https://jira.devtools.intel.com/browse/OAM-80208 Signed-off-by: Shaofeng Tang --- common/core/overlaylayer.cpp | 101 ++++++++++++++++++++-- common/core/overlaylayer.h | 13 ++- common/display/displayqueue.cpp | 6 +- common/display/virtualdisplay.cpp | 2 +- common/display/virtualpanoramadisplay.cpp | 2 +- 5 files changed, 107 insertions(+), 17 deletions(-) diff --git a/common/core/overlaylayer.cpp b/common/core/overlaylayer.cpp index 87f6276d..d8fc10cb 100644 --- a/common/core/overlaylayer.cpp +++ b/common/core/overlaylayer.cpp @@ -184,18 +184,95 @@ void OverlayLayer::ValidateTransform(uint32_t transform, } } +void OverlayLayer::TransformDamage(HwcLayer* layer, uint32_t max_height, + uint32_t max_width) { + const HwcRect& surface_damage = layer->GetLayerDamage(); + if (surface_damage.empty()) { + surface_damage_ = surface_damage; + return; + } + HwcRect translated_damage = TranslateRect(surface_damage, 0, 0); +#ifdef RECT_DAMAGE_TRACING + IRECTDAMAGETRACE("Calculating Overlaylayer Damage for layer[%d]", z_order_); + IRECTDAMAGETRACE("max_width: %d, max_height:%d", max_width, max_height); + IRECTDAMAGETRACE("Original Surface_damage (LTWH): %d, %d, %d, %d", + surface_damage.left, surface_damage.top, + (surface_damage.right - surface_damage.left), + (surface_damage.bottom - surface_damage.top)); + IRECTDAMAGETRACE("translated_damage (LTWH): %d, %d, %d, %d", + translated_damage.left, translated_damage.top, + (translated_damage.right - translated_damage.left), + (translated_damage.bottom - translated_damage.top)); + IRECTDAMAGETRACE("source_crop_ (LTWH): %f, %f, %f, %f", source_crop_.left, + source_crop_.top, (source_crop_.right - source_crop_.left), + (source_crop_.bottom - source_crop_.top)); + IRECTDAMAGETRACE("display_frame_ (LTWH): %d, %d, %d, %d", display_frame_.left, + display_frame_.top, + (display_frame_.right - display_frame_.left), + (display_frame_.bottom - display_frame_.top)); +#endif + float ratio_w_h = max_width * 1.0 / max_height; + float ratio_h_w = max_height * 1.0 / max_width; + + int ox = 0, oy = 0; + + if (plane_transform_ == kTransform270) { + oy = max_height; + surface_damage_.left = translated_damage.top * ratio_w_h + 0.5; + surface_damage_.top = oy - translated_damage.right * ratio_h_w + 0.5; + surface_damage_.right = translated_damage.bottom * ratio_w_h + 0.5; + surface_damage_.bottom = oy - translated_damage.left * ratio_h_w + 0.5; + } else if (plane_transform_ == kTransform180) { + surface_damage_ = translated_damage; + } else if (plane_transform_ & hwcomposer::HWCTransform::kTransform90) { + if (plane_transform_ & kReflectX) { + surface_damage_.left = translated_damage.top * ratio_w_h + 0.5; + surface_damage_.top = translated_damage.left * ratio_h_w + 0.5; + surface_damage_.right = translated_damage.bottom * ratio_w_h + 0.5; + surface_damage_.bottom = translated_damage.right * ratio_h_w + 0.5; + } else if (plane_transform_ & kReflectY) { + ox = max_width; + oy = max_height; + surface_damage_.left = ox - (translated_damage.bottom * ratio_w_h + 0.5); + surface_damage_.top = oy - (translated_damage.right * ratio_h_w + 0.5); + surface_damage_.right = ox - (translated_damage.top * ratio_w_h + 0.5); + surface_damage_.bottom = oy - (translated_damage.left * ratio_h_w + 0.5); + } else { + ox = max_width; + surface_damage_.left = ox - translated_damage.bottom * ratio_w_h + 0.5; + surface_damage_.top = translated_damage.left * ratio_h_w + 0.5; + surface_damage_.right = ox - translated_damage.top * ratio_w_h + 0.5; + surface_damage_.bottom = translated_damage.right * ratio_h_w + 0.5; + } + } else if (plane_transform_ == 0) { + surface_damage_.left = translated_damage.left; + surface_damage_.top = translated_damage.top; + surface_damage_.right = translated_damage.right; + surface_damage_.bottom = translated_damage.bottom; + } +#ifdef RECT_DAMAGE_TRACING + IRECTDAMAGETRACE("Surface_damage (LTWH): %d, %d, %d, %d", + surface_damage_.left, surface_damage_.top, + (surface_damage_.right - surface_damage_.left), + (surface_damage_.bottom - surface_damage_.top)); +#endif +} + void OverlayLayer::InitializeState(HwcLayer* layer, ResourceManager* resource_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, - uint32_t max_height, uint32_t rotation, - bool handle_constraints) { + uint32_t max_height, uint32_t max_width, + uint32_t rotation, bool handle_constraints) { transform_ = layer->GetTransform(); if (rotation != kRotateNone) { ValidateTransform(layer->GetTransform(), rotation); } else { plane_transform_ = transform_; } +#ifdef RECT_DAMAGE_TRACING + IRECTDAMAGETRACE("validated plane_transform_: %d", plane_transform_); +#endif alpha_ = layer->GetAlpha(); layer_index_ = layer_index; @@ -205,9 +282,8 @@ void OverlayLayer::InitializeState(HwcLayer* layer, source_crop_ = layer->GetSourceCrop(); dataspace_ = layer->GetDataSpace(); blending_ = layer->GetBlending(); - surface_damage_ = layer->GetLayerDamage(); - solid_color_ = layer->GetSolidColor(); + TransformDamage(layer, max_height, max_width); if (previous_layer && layer->HasZorderChanged()) { if (previous_layer->actual_composition_ == kGpu) { @@ -257,6 +333,12 @@ void OverlayLayer::InitializeState(HwcLayer* layer, if (previous_layer) { ValidatePreviousFrameState(previous_layer, layer); } +#ifdef RECT_DAMAGE_TRACING + IRECTDAMAGETRACE("Surface_damage after init (LTWH): %d, %d, %d, %d", + surface_damage_.left, surface_damage_.top, + (surface_damage_.right - surface_damage_.left), + (surface_damage_.bottom - surface_damage_.top)); +#endif return; } @@ -376,22 +458,23 @@ void OverlayLayer::InitializeState(HwcLayer* layer, void OverlayLayer::InitializeFromHwcLayer( HwcLayer* layer, ResourceManager* resource_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, - uint32_t max_height, uint32_t rotation, bool handle_constraints) { + uint32_t max_height, uint32_t max_width, uint32_t rotation, + bool handle_constraints) { display_frame_width_ = layer->GetDisplayFrameWidth(); display_frame_height_ = layer->GetDisplayFrameHeight(); display_frame_ = layer->GetDisplayFrame(); InitializeState(layer, resource_manager, previous_layer, z_order, layer_index, - max_height, rotation, handle_constraints); + max_height, max_width, rotation, handle_constraints); } void OverlayLayer::InitializeFromScaledHwcLayer( HwcLayer* layer, ResourceManager* resource_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, - const HwcRect& display_frame, uint32_t max_height, uint32_t rotation, - bool handle_constraints) { + const HwcRect& display_frame, uint32_t max_height, uint32_t max_width, + uint32_t rotation, bool handle_constraints) { SetDisplayFrame(display_frame); InitializeState(layer, resource_manager, previous_layer, z_order, layer_index, - max_height, rotation, handle_constraints); + max_height, max_width, rotation, handle_constraints); } void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs, diff --git a/common/core/overlaylayer.h b/common/core/overlaylayer.h index 40b62580..b862c40e 100644 --- a/common/core/overlaylayer.h +++ b/common/core/overlaylayer.h @@ -49,15 +49,16 @@ struct OverlayLayer { void InitializeFromHwcLayer(HwcLayer* layer, ResourceManager* buffer_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, uint32_t max_height, - uint32_t rotation, bool handle_constraints); + uint32_t max_width, uint32_t rotation, + bool handle_constraints); void InitializeFromScaledHwcLayer(HwcLayer* layer, ResourceManager* buffer_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, const HwcRect& display_frame, - uint32_t max_height, uint32_t rotation, - bool handle_constraints); + uint32_t max_height, uint32_t max_width, + uint32_t rotation, bool handle_constraints); // Get z order of this layer. uint32_t GetZorder() const { return z_order_; @@ -277,10 +278,14 @@ struct OverlayLayer { void ValidateTransform(uint32_t transform, uint32_t display_transform); + void TransformDamage(HwcLayer* layer, uint32_t max_height, + uint32_t max_width); + void InitializeState(HwcLayer* layer, ResourceManager* buffer_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, uint32_t max_height, - uint32_t rotation, bool handle_constraints); + uint32_t max_width, uint32_t rotation, + bool handle_constraints); uint32_t transform_ = 0; uint32_t plane_transform_ = 0; diff --git a/common/display/displayqueue.cpp b/common/display/displayqueue.cpp index abf978d5..b44795c9 100644 --- a/common/display/displayqueue.cpp +++ b/common/display/displayqueue.cpp @@ -568,12 +568,14 @@ void DisplayQueue::InitializeOverlayLayers( overlay_layer->InitializeFromScaledHwcLayer( layer, resource_manager_.get(), previous_layer, z_order, layer_index, - display_frame, display_plane_manager_->GetHeight(), plane_transform_, + display_frame, display_plane_manager_->GetHeight(), + display_plane_manager_->GetWidth(), plane_transform_, handle_constraints); } else { overlay_layer->InitializeFromHwcLayer( layer, resource_manager_.get(), previous_layer, z_order, layer_index, - display_plane_manager_->GetHeight(), plane_transform_, + display_plane_manager_->GetHeight(), + display_plane_manager_->GetWidth(), plane_transform_, handle_constraints); } diff --git a/common/display/virtualdisplay.cpp b/common/display/virtualdisplay.cpp index be579520..fdd2d341 100644 --- a/common/display/virtualdisplay.cpp +++ b/common/display/virtualdisplay.cpp @@ -349,7 +349,7 @@ bool VirtualDisplay::Present(std::vector &source_layers, overlay_layer.InitializeFromHwcLayer( layer, resource_manager_.get(), previous_layer, z_order, layer_index, - height_, kIdentity, handle_constraints); + height_, width_, kIdentity, handle_constraints); index.emplace_back(z_order); layers_rects.emplace_back(layer->GetDisplayFrame()); z_order++; diff --git a/common/display/virtualpanoramadisplay.cpp b/common/display/virtualpanoramadisplay.cpp index 12d84c61..bfd78a5d 100644 --- a/common/display/virtualpanoramadisplay.cpp +++ b/common/display/virtualpanoramadisplay.cpp @@ -350,7 +350,7 @@ bool VirtualPanoramaDisplay::Present(std::vector &source_layers, overlay_layer.InitializeFromHwcLayer( layer, resource_manager_.get(), previous_layer, z_order, layer_index, - height_, kIdentity, handle_constraints); + height_, width_, kIdentity, handle_constraints); index.emplace_back(z_order); layers_rects.emplace_back(overlay_layer.GetDisplayFrame()); From b5a7f69b28383d010fb521cbed9e258c74b93bbd Mon Sep 17 00:00:00 2001 From: "Yang, Dong" Date: Tue, 14 May 2019 10:53:59 +0800 Subject: [PATCH 09/20] Init more program duing HWC initialization period More programs need to initialized, if the programe not created enough, then some will be create at compostion time, and will result in bad Janky Frame. Change-Id: I64470f616777646d6c1d27846c8e7be0f7eb4a75 Test: Compile pass on Android, no regressions on 1A. Tracked-On: https://jira.devtools.intel.com/browse/OAM-76069 Signed-off-by: Yang, Dong --- common/compositor/gl/glrenderer.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/common/compositor/gl/glrenderer.cpp b/common/compositor/gl/glrenderer.cpp index 160f256f..dd4c3f69 100644 --- a/common/compositor/gl/glrenderer.cpp +++ b/common/compositor/gl/glrenderer.cpp @@ -64,9 +64,11 @@ bool GLRenderer::Init() { glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); - std::unique_ptr program(new GLProgram()); - if (program->Init(1)) { - programs_.emplace_back(std::move(program)); + for (int i = 1; i < 5; i++) { + std::unique_ptr program(new GLProgram()); + if (program->Init(i)) { + programs_.emplace_back(std::move(program)); + } } glEnableVertexAttribArray(0); From eb96cabb70b50922c7a3d57d0dd8059f1feed222 Mon Sep 17 00:00:00 2001 From: Wan Shuang Date: Thu, 30 May 2019 13:13:38 +0800 Subject: [PATCH 10/20] Fixed the external display hang during video playback. Update validate_final_layers state to ensure HWC update plans' status properly and make the plane squashing behavior works as expected. Change-Id: I5f5aa496e57753da6b6e72f82900461ca672d367 Test: External display is not hang during video playback Tracked-On: None Signed-off-by: Wan Shuang --- common/display/displayplanemanager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/display/displayplanemanager.cpp b/common/display/displayplanemanager.cpp index e661ac95..d85944d3 100644 --- a/common/display/displayplanemanager.cpp +++ b/common/display/displayplanemanager.cpp @@ -241,7 +241,11 @@ bool DisplayPlaneManager::ValidateLayers( } else { // Plane separation is needed if (!layer->IsSolidColor() && !layer->IsVideoLayer()) { - // Current plane is not the video layer and not the solid + // validate_final_layers needs to be updated to ensure + // plane squashing works as expected. + if (!validate_final_layers) + validate_final_layers = !(last_plane.GetOffScreenTarget()); + // Current layer is not the video layer and not the solid // color layer as well. Initialize the DisplayPlaneState // object and link it with OverlayPlane object. ResetPlaneTarget(last_plane, commit_planes.back()); From bee374610533f2766de31870026a557bb0fc6357 Mon Sep 17 00:00:00 2001 From: "Fan, Yugang" Date: Thu, 30 May 2019 00:51:42 +0800 Subject: [PATCH 11/20] Limits some monitors' modes due to hardware limitation. Defines HWC_LIMITED_MONITOR_LIST for limited monitors' name, and only exposes the preferred mode for those monitors. Tests: Works well with limited monitors (e.g. "TD2230 Series") and other normal monitor, and can get display name from debug log. limited monitor only exposes preferred mode to uplevel. Tracked-On: OAM-78920 Signed-off-by: Yugang Fan Change-Id: Ic8bf86c4ea7fdc98de48fb54da669172425afe0b --- wsi/drm/drmdisplay.cpp | 63 ++++++++++++++++++++++++++++++++++- wsi/drm/drmdisplay.h | 4 +++ wsi/drm/drmdisplaymanager.cpp | 18 ++++++++-- wsi/physicaldisplay.h | 10 ++++++ 4 files changed, 92 insertions(+), 3 deletions(-) diff --git a/wsi/drm/drmdisplay.cpp b/wsi/drm/drmdisplay.cpp index 5c034242..c314392a 100644 --- a/wsi/drm/drmdisplay.cpp +++ b/wsi/drm/drmdisplay.cpp @@ -154,6 +154,66 @@ void DrmDisplay::DrmConnectorGetDCIP3Support( return; } +void DrmDisplay::GetEDIDDisplayData(const ScopedDrmObjectPropertyPtr &props) { + uint8_t *edid = NULL; + uint64_t edid_blob_id; + struct edid_display_data display_data[4]; + drmModePropertyBlobPtr blob; + + GetDrmObjectPropertyValue("EDID", props, &edid_blob_id); + blob = drmModeGetPropertyBlob(gpu_fd_, edid_blob_id); + if (!blob) { + return; + } + + edid = (uint8_t *)blob->data; + if (!edid) { + return; + } + std::memset(display_data, 0, sizeof(display_data)); + std::memcpy((void *)display_data, (void *)(edid + 54), + sizeof(edid_display_data) * 4); + + for (int i = 0; i < 4; i++) { + if (!(display_data[i].indicate == 0x0000 && + display_data[i].reserved1 == 0x00 && + display_data[i].reserved2 == 0x00)) + continue; + + if (display_data[i].tag_number == 0xfc) { + display_name_.clear(); + size_t display_desc_size = + sizeof(((struct edid_display_data *)0)->desc_data); + size_t display_desc_str_size = + strchrnul((char *)display_data[i].desc_data, '\n') - + (char *)display_data[i].desc_data; + size_t display_desc_copy_size = display_desc_str_size > display_desc_size + ? display_desc_size + : display_desc_str_size; + display_name_.assign((char *)display_data[i].desc_data, + display_desc_copy_size); + } + } + + ITRACE("Got EDID display name \"%s\"\n", display_name_.c_str()); +} + +/* +* Check limited monitors exposing some modes which not +* be supported by monitor hardware actually. Limited monitors +* be defined in HWC_LIMITED_MONITOR_LIST. +*/ +bool DrmDisplay::CheckLimitedMonitor() { + for (unsigned int i = 0; i < HWC_LIMITED_MONITOR_LIST.size(); ++i) { + if (display_name_.compare(HWC_LIMITED_MONITOR_LIST[i]) == 0) { + ITRACE("Got a limited monitor: %s\n", + HWC_LIMITED_MONITOR_LIST[i].c_str()); + return true; + } + } + return false; +} + bool DrmDisplay::ConnectDisplay(const drmModeModeInfo &mode_info, const drmModeConnector *connector, uint32_t config) { @@ -231,6 +291,8 @@ bool DrmDisplay::ConnectDisplay(const drmModeModeInfo &mode_info, ITRACE("DCIP3 support not available"); } + GetEDIDDisplayData(connector_props); + PhysicalDisplay::Connect(); SetHDCPState(desired_protection_support_, content_type_); @@ -636,7 +698,6 @@ void DrmDisplay::SetDrmModeInfo(const std::vector &mode_info) { #endif modes_.emplace_back(mode_info[i]); } - SPIN_UNLOCK(display_lock_); } diff --git a/wsi/drm/drmdisplay.h b/wsi/drm/drmdisplay.h index e96e0923..415135ff 100644 --- a/wsi/drm/drmdisplay.h +++ b/wsi/drm/drmdisplay.h @@ -133,6 +133,8 @@ class DrmDisplay : public PhysicalDisplay { first_commit_ = true; } + bool CheckLimitedMonitor(); + private: void ShutDownPipe(); void GetDrmObjectPropertyValue(const char *name, @@ -165,6 +167,7 @@ class DrmDisplay : public PhysicalDisplay { std::vector FindExtendedBlocksForTag(uint8_t *edid, uint8_t block_tag); void DrmConnectorGetDCIP3Support(const ScopedDrmObjectPropertyPtr &props); + void GetEDIDDisplayData(const ScopedDrmObjectPropertyPtr &props); void TraceFirstCommit(); @@ -195,6 +198,7 @@ class DrmDisplay : public PhysicalDisplay { uint32_t flags_ = DRM_MODE_ATOMIC_ALLOW_MODESET; bool planes_updated_ = false; bool first_commit_ = false; + std::string display_name_; HWCContentProtection current_protection_support_ = HWCContentProtection::kUnSupported; HWCContentProtection desired_protection_support_ = diff --git a/wsi/drm/drmdisplaymanager.cpp b/wsi/drm/drmdisplaymanager.cpp index b21bf00f..6fd8154f 100644 --- a/wsi/drm/drmdisplaymanager.cpp +++ b/wsi/drm/drmdisplaymanager.cpp @@ -285,7 +285,14 @@ bool DrmDisplayManager::UpdateDisplayState() { encoder->crtc_id, display->CrtcId(), display->GetDisplayPipe()); // Set the modes supported for each display - display->SetDrmModeInfo(mode); + if (display->CheckLimitedMonitor()) { + // only expose the preferred mode for limited monitor + std::vector limited_mode( + 1, connector->modes[preferred_mode]); + display->SetDrmModeInfo(limited_mode); + } else { + display->SetDrmModeInfo(mode); + } break; } } @@ -330,7 +337,14 @@ bool DrmDisplayManager::UpdateDisplayState() { IHOTPLUGEVENTTRACE("Connected with crtc: %d pipe:%d \n", display->CrtcId(), display->GetDisplayPipe()); // Set the modes supported for each display - display->SetDrmModeInfo(mode); + if (display->CheckLimitedMonitor()) { + // only expose the preferred mode for limited monitor + std::vector limited_mode( + 1, connector->modes[preferred_mode]); + display->SetDrmModeInfo(limited_mode); + } else { + display->SetDrmModeInfo(mode); + } break; } } diff --git a/wsi/physicaldisplay.h b/wsi/physicaldisplay.h index 471f13ca..4fd91f7e 100644 --- a/wsi/physicaldisplay.h +++ b/wsi/physicaldisplay.h @@ -306,5 +306,15 @@ class PhysicalDisplay : public NativeDisplay, public DisplayPlaneHandler { uint32_t config_ = DEFAULT_CONFIG_ID; }; +struct __attribute__((packed)) edid_display_data { + uint16_t indicate; + uint8_t reserved1; + uint8_t tag_number; + uint8_t reserved2; + uint8_t desc_data[13]; +}; + +const std::vector HWC_LIMITED_MONITOR_LIST{"TD2230 Series"}; + } // namespace hwcomposer #endif // WSI_PHYSICALDISPLAY_H_ From 2b06abd3ea993d9153dc23822ccef3b80f8a5566 Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Thu, 30 May 2019 16:46:46 +0800 Subject: [PATCH 12/20] Set the alpha of solid_color as 0xff by default For avoiding to impact the alpha of layer in case that solid_color is not set. Change-Id: I2030165839a9c7f371fed6f81279ac2d94db084e Tests: Work well on GP-P Tracked-On: None Signed-off-by: Shaofeng Tang --- public/hwclayer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/hwclayer.h b/public/hwclayer.h index f2dc0b3b..b8e4af30 100644 --- a/public/hwclayer.h +++ b/public/hwclayer.h @@ -348,7 +348,7 @@ struct HwcLayer { kVisible | kSurfaceDamageChanged | kVisibleRegionChanged | kZorderChanged; int layer_cache_ = kLayerAttributesChanged | kDisplayFrameRectChanged; bool is_cursor_layer_ = false; - uint32_t solid_color_ = 0; + uint32_t solid_color_ = 0xff; HWCLayerCompositionType composition_type_ = Composition_Device; }; From d79a302d40b68bdae989346e9877d58bb37d523a Mon Sep 17 00:00:00 2001 From: Wan Shuang Date: Tue, 4 Jun 2019 18:53:02 +0800 Subject: [PATCH 13/20] Revert 2 black stripe related patches Revert "Fixed the external display hang during video playback." Revert "Fixed the black stripe issue during video playback control bar popup" Change-Id: I2638468a04518ba9f45209eb5a8486a8de86b99d Tests: Video playback with 2 displays and check plane & layer binding. Tracked-On: None Signed-off-by: Wan Shuang --- common/display/displayplanemanager.cpp | 13 +------------ common/display/displayqueue.cpp | 5 ----- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/common/display/displayplanemanager.cpp b/common/display/displayplanemanager.cpp index d85944d3..2d678e10 100644 --- a/common/display/displayplanemanager.cpp +++ b/common/display/displayplanemanager.cpp @@ -238,19 +238,8 @@ bool DisplayPlaneManager::ValidateLayers( validate_final_layers = !(last_plane.GetOffScreenTarget()); ResetPlaneTarget(last_plane, commit_planes.back()); - } else { - // Plane separation is needed - if (!layer->IsSolidColor() && !layer->IsVideoLayer()) { - // validate_final_layers needs to be updated to ensure - // plane squashing works as expected. - if (!validate_final_layers) - validate_final_layers = !(last_plane.GetOffScreenTarget()); - // Current layer is not the video layer and not the solid - // color layer as well. Initialize the DisplayPlaneState - // object and link it with OverlayPlane object. - ResetPlaneTarget(last_plane, commit_planes.back()); - } } + break; } else { if (composition.empty()) { diff --git a/common/display/displayqueue.cpp b/common/display/displayqueue.cpp index b44795c9..9bcf475b 100644 --- a/common/display/displayqueue.cpp +++ b/common/display/displayqueue.cpp @@ -688,11 +688,6 @@ bool DisplayQueue::QueueUpdate(std::vector& source_layers, } } - if (previous_size != size) { - // Validate layers if visible layers changed from last frame. - validate_layers = true; - } - if (idle_frame) { if ((add_index != -1) || (remove_index != -1) || re_validate_commit) { idle_frame = false; From bee7ad16600544869da9a8ece41e4b2f15152313 Mon Sep 17 00:00:00 2001 From: "Yuanzhe, Liu" Date: Tue, 4 Jun 2019 17:43:16 +0800 Subject: [PATCH 14/20] Fix klocwork issues in GFX Domain Fix errors in gordon_peak 63 daily klocwork scanning. Test: Compile successful Tracked-On: No Sighed-off-by: Yuanzhe, Liu Change-Id: I8ad955264e1438cb592f99fc16d49fb8e3c61ff8 --- common/core/gpudevice.cpp | 2 ++ os/android/iahwc2.cpp | 1 + wsi/drm/drmdisplay.cpp | 16 ++++++++++++++- wsi/drm/drmdisplaymanager.cpp | 37 +++++++++++++++++++++++++++++++---- wsi/drm/drmplane.cpp | 1 + wsi/physicaldisplay.cpp | 2 +- 6 files changed, 53 insertions(+), 6 deletions(-) diff --git a/common/core/gpudevice.cpp b/common/core/gpudevice.cpp index 59c3d25e..0505b090 100644 --- a/common/core/gpudevice.cpp +++ b/common/core/gpudevice.cpp @@ -400,6 +400,8 @@ void GpuDevice::ParseLogicalDisplaySetting( logical_split_str.find_first_not_of("0123456789") != std::string::npos) return; uint32_t physical_index = atoi(physical_index_str.c_str()); + if (physical_index < 0) + return; uint32_t logical_split_num = atoi(logical_split_str.c_str()); if (logical_split_num <= 1) return; diff --git a/os/android/iahwc2.cpp b/os/android/iahwc2.cpp index 02fe3d22..2d82f8c4 100644 --- a/os/android/iahwc2.cpp +++ b/os/android/iahwc2.cpp @@ -1230,6 +1230,7 @@ int IAHWC2::HookDevOpen(const struct hw_module_t *module, const char *name, HWC2::Error err = ctx->Init(); if (err != HWC2::Error::None) { ALOGE("Failed to initialize IAHWC2 err=%d\n", err); + ctx.reset(); return -EINVAL; } diff --git a/wsi/drm/drmdisplay.cpp b/wsi/drm/drmdisplay.cpp index c314392a..07a986e3 100644 --- a/wsi/drm/drmdisplay.cpp +++ b/wsi/drm/drmdisplay.cpp @@ -134,6 +134,7 @@ void DrmDisplay::DrmConnectorGetDCIP3Support( edid = (uint8_t *)blob->data; if (!edid) { + drmModeFreePropertyBlob(blob); return; } @@ -736,8 +737,10 @@ void DrmDisplay::GetDrmObjectProperty(const char *name, ScopedDrmPropertyPtr property(drmModeGetProperty(gpu_fd_, props->props[i])); if (property && !strcmp(property->name, name)) { *id = property->prop_id; + property.reset(); break; } + property.reset(); } if (!(*id)) ETRACE("Could not find property %s", name); @@ -765,8 +768,10 @@ void DrmDisplay::GetDrmHDCPObjectProperty( } } } + property.reset(); break; } + property.reset(); } if (!(*id)) ETRACE("Could not find property %s", name); @@ -780,8 +785,10 @@ void DrmDisplay::GetDrmObjectPropertyValue( ScopedDrmPropertyPtr property(drmModeGetProperty(gpu_fd_, props->props[i])); if (property && !strcmp(property->name, name)) { *value = props->prop_values[i]; + property.reset(); break; } + property.reset(); } if (!(*value)) ETRACE("Could not find property value %s", name); @@ -1121,11 +1128,14 @@ bool DrmDisplay::PopulatePlanes( drmModeGetPlane(gpu_fd_, plane_resources->planes[i])); if (!drm_plane) { ETRACE("Failed to get plane "); + plane_resources.reset(); return false; } - if (!(pipe_bit & drm_plane->possible_crtcs)) + if (!(pipe_bit & drm_plane->possible_crtcs)) { + drm_plane.reset(); continue; + } uint32_t formats_size = drm_plane->count_formats; plane_ids.insert(drm_plane->plane_id); @@ -1148,10 +1158,13 @@ bool DrmDisplay::PopulatePlanes( overlay_planes.emplace_back(plane.release()); } } + + drm_plane.reset(); } if (overlay_planes.empty()) { ETRACE("Failed to get primary plane for display %d", crtc_id_); + plane_resources.reset(); return false; } @@ -1165,6 +1178,7 @@ bool DrmDisplay::PopulatePlanes( overlay_planes.emplace_back(cursor_plane.release()); } + plane_resources.reset(); return true; } diff --git a/wsi/drm/drmdisplaymanager.cpp b/wsi/drm/drmdisplaymanager.cpp index 6fd8154f..adef66ef 100644 --- a/wsi/drm/drmdisplaymanager.cpp +++ b/wsi/drm/drmdisplaymanager.cpp @@ -75,13 +75,21 @@ bool DrmDisplayManager::Initialize() { } ScopedDrmResourcesPtr res(drmModeGetResources(fd_)); - if (res && res->count_crtcs == 0) + if (!res) { + ETRACE("Failed to get resources"); + return false; + } + + if (res->count_crtcs == 0) { + res.reset(); return false; + } for (int32_t i = 0; i < res->count_crtcs; ++i) { ScopedDrmCrtcPtr c(drmModeGetCrtc(fd_, res->crtcs[i])); if (!c) { ETRACE("Failed to get crtc %d", res->crtcs[i]); + res.reset(); return false; } @@ -89,12 +97,15 @@ bool DrmDisplayManager::Initialize() { new DrmDisplay(fd_, i, c->crtc_id, this)); displays_.emplace_back(std::move(display)); + + c.reset(); } #ifndef DISABLE_HOTPLUG_NOTIFICATION hotplug_fd_ = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (hotplug_fd_ < 0) { ETRACE("Failed to create socket for hot plug monitor. %s", PRINTERROR()); + res.reset(); return true; } @@ -108,6 +119,7 @@ bool DrmDisplayManager::Initialize() { if (ret) { ETRACE("Failed to bind sockaddr_nl and hot plug monitor fd. %s", PRINTERROR()); + res.reset(); return true; } @@ -115,6 +127,7 @@ bool DrmDisplayManager::Initialize() { #endif IHOTPLUGEVENTTRACE("DisplayManager Initialization succeeded."); + res.reset(); return true; } @@ -233,9 +246,12 @@ bool DrmDisplayManager::UpdateDisplayState() { break; } // check if a monitor is connected. - if (connector->connection != DRM_MODE_CONNECTED) + if (connector->connection != DRM_MODE_CONNECTED) { + connector.reset(); continue; + } connected_display_count_++; + connector.reset(); } for (uint32_t i = 0; i < total_connectors; ++i) { @@ -246,15 +262,20 @@ bool DrmDisplayManager::UpdateDisplayState() { break; } // check if a monitor is connected. - if (connector->connection != DRM_MODE_CONNECTED) + if (connector->connection != DRM_MODE_CONNECTED) { + connector.reset(); continue; + } // Ensure we have atleast one valid mode. - if (connector->count_modes == 0) + if (connector->count_modes == 0) { + connector.reset(); continue; + } if (connector->encoder_id == 0) { no_encoder.emplace_back(i); + connector.reset(); continue; } @@ -297,6 +318,9 @@ bool DrmDisplayManager::UpdateDisplayState() { } } } + + encoder.reset(); + connector.reset(); } // Deal with connectors with encoder_id == 0. @@ -348,7 +372,11 @@ bool DrmDisplayManager::UpdateDisplayState() { break; } } + + encoder.reset(); } + + connector.reset(); } for (auto &display : displays_) { @@ -378,6 +406,7 @@ bool DrmDisplayManager::UpdateDisplayState() { if (device_.IsReservedDrmPlane()) RemoveUnreservedPlanes(); + res.reset(); return true; } diff --git a/wsi/drm/drmplane.cpp b/wsi/drm/drmplane.cpp index 389b1ac4..d7f563dc 100644 --- a/wsi/drm/drmplane.cpp +++ b/wsi/drm/drmplane.cpp @@ -216,6 +216,7 @@ bool DrmPlane::Initialize(uint32_t gpu_fd, const std::vector& formats, drmModeGetPropertyBlob(gpu_fd, in_formats_prop_value); if (blob == nullptr || blob->data == nullptr) { ETRACE("Unable to get property data\n"); + drmModeFreePropertyBlob(blob); return false; } diff --git a/wsi/physicaldisplay.cpp b/wsi/physicaldisplay.cpp index c051a245..7fad3e80 100644 --- a/wsi/physicaldisplay.cpp +++ b/wsi/physicaldisplay.cpp @@ -377,7 +377,7 @@ int PhysicalDisplay::RegisterVsyncCallback( void PhysicalDisplay::RegisterRefreshCallback( std::shared_ptr callback, uint32_t display_id) { - return display_queue_->RegisterRefreshCallback(callback, display_id); + display_queue_->RegisterRefreshCallback(callback, display_id); } void PhysicalDisplay::RegisterHotPlugCallback( From 27bf98d144dd520688e91b510ae772e80f23f9b0 Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Wed, 5 Jun 2019 21:46:28 +0800 Subject: [PATCH 15/20] Only enable RBC when single display is connected RBC will be disabled when 2 or more displays are connected Change-Id: I8944fb7070c99fad30732077f06b4c9e5e2bacd3 Tests: RBC only enabled with 1 connected display Tracked-On: https://github.com/intel/IA-Hardware-Composer/issues/585 Signed-off-by: Shaofeng Tang --- wsi/drm/drmdisplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsi/drm/drmdisplay.cpp b/wsi/drm/drmdisplay.cpp index 07a986e3..5ec27fd7 100644 --- a/wsi/drm/drmdisplay.cpp +++ b/wsi/drm/drmdisplay.cpp @@ -1147,7 +1147,7 @@ bool DrmDisplay::PopulatePlanes( bool use_modifier = true; #ifdef MODIFICATOR_WA - use_modifier = (manager_->GetConnectedPhysicalDisplayCount() < 3); + use_modifier = (manager_->GetConnectedPhysicalDisplayCount() < 2); if (i >= 2) use_modifier = false; #endif From 1c85787b01ded8412f14c735658ac59a44782a53 Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Mon, 3 Jun 2019 15:50:55 +0800 Subject: [PATCH 16/20] Avoid to re-validate Video Plane for Scaler Video Plane is now scaled by VPP, instead of Display Plane any more. No need to re-validate Video Plane for scaler. Change-Id: I870ab3d7ecf966180f83552e13d7f05885cb34e5 Tests: Work well on extend mode with rotate in Playing video Tracked-On: None Signed-off-by: Shaofeng Tang --- common/display/displayplanestate.cpp | 2 +- wsi/drm/drmdisplay.cpp | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/common/display/displayplanestate.cpp b/common/display/displayplanestate.cpp index 7265f91a..f4392b7e 100644 --- a/common/display/displayplanestate.cpp +++ b/common/display/displayplanestate.cpp @@ -612,7 +612,7 @@ void DisplayPlaneState::ValidateReValidation() { if (private_data_->source_layers_.size() == 1 && !(private_data_->type_ == DisplayPlanePrivateState::PlaneType::kVideo)) { re_validate_layer_ |= ReValidationType::kScanout; - } else { + } else if (!IsVideoPlane()) { bool use_scalar = CanUseDisplayUpScaling(); if (private_data_->use_plane_scalar_ != use_scalar) { re_validate_layer_ |= ReValidationType::kUpScalar; diff --git a/wsi/drm/drmdisplay.cpp b/wsi/drm/drmdisplay.cpp index 5ec27fd7..23c2b555 100644 --- a/wsi/drm/drmdisplay.cpp +++ b/wsi/drm/drmdisplay.cpp @@ -644,8 +644,14 @@ bool DrmDisplay::CommitFrame( comp_plane.GetRotationType(); if ((plane_transform != kIdentity) && (rotation_type == DisplayPlaneState::RotationType::kDisplayRotation)) { - HwcRect rotated_rect = - RotateScaleRect(display_rect, width_, height_, plane_transform); + HwcRect rotated_rect; + if (layer->IsVideoLayer()) { + rotated_rect = + RotateRect(display_rect, width_, height_, plane_transform); + } else { + rotated_rect = + RotateScaleRect(display_rect, width_, height_, plane_transform); + } layer->SetDisplayFrame(rotated_rect); } From 26e7341faf790413c03d9c37b6a8ad0464a8bd30 Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Tue, 4 Jun 2019 14:08:12 +0800 Subject: [PATCH 17/20] Fix surface-damage error in SF-rotate 180 When 'SetSurfaceDamage' is invoked without damage, surface_damage should not be rotated too. and For 180 case, the size should be rotated too for SF-rotation. Change-Id: I231a08de6fb5017bca60f8be02146fb2a0a06e33 Tests: Work well on extend mode with rotate_90, 180 and 270 Tracked-On: None Signed-off-by: Shaofeng Tang --- common/core/overlaylayer.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/common/core/overlaylayer.cpp b/common/core/overlaylayer.cpp index d8fc10cb..f4f70121 100644 --- a/common/core/overlaylayer.cpp +++ b/common/core/overlaylayer.cpp @@ -187,7 +187,7 @@ void OverlayLayer::ValidateTransform(uint32_t transform, void OverlayLayer::TransformDamage(HwcLayer* layer, uint32_t max_height, uint32_t max_width) { const HwcRect& surface_damage = layer->GetLayerDamage(); - if (surface_damage.empty()) { + if (surface_damage.empty() || !layer->HasSurfaceDamageRegionChanged()) { surface_damage_ = surface_damage; return; } @@ -223,7 +223,12 @@ void OverlayLayer::TransformDamage(HwcLayer* layer, uint32_t max_height, surface_damage_.right = translated_damage.bottom * ratio_w_h + 0.5; surface_damage_.bottom = oy - translated_damage.left * ratio_h_w + 0.5; } else if (plane_transform_ == kTransform180) { - surface_damage_ = translated_damage; + ox = max_width; + oy = max_height; + surface_damage_.left = ox - translated_damage.right; + surface_damage_.top = oy - translated_damage.bottom; + surface_damage_.right = ox - translated_damage.left; + surface_damage_.bottom = oy - translated_damage.top; } else if (plane_transform_ & hwcomposer::HWCTransform::kTransform90) { if (plane_transform_ & kReflectX) { surface_damage_.left = translated_damage.top * ratio_w_h + 0.5; From 646c006042eb8d44c36b9d7794271fdd39edd377 Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Wed, 5 Jun 2019 21:11:21 +0800 Subject: [PATCH 18/20] Add a property for merged HWC and SF rotation status In SF rotation, display_frame and surface are already rotated from SF. we need to split the rotation status for HWC and SF into transform_ and plane_transform_ for deciding if display_frame and surface need to be rotated. and add an property for merged rotation for rotate surface_damage. Change-Id: I0ce8522c2a9807d4194d0a8b8334b0f984def2b6 Tests: Work well in SF rotation on GP P and Q Tracked-On: None Signed-off-by: Shaofeng Tang --- common/core/overlaylayer.cpp | 26 ++++++++++++++------------ common/core/overlaylayer.h | 11 +++++++++-- wsi/drm/drmplane.cpp | 4 ++-- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/common/core/overlaylayer.cpp b/common/core/overlaylayer.cpp index f4f70121..d5061b97 100644 --- a/common/core/overlaylayer.cpp +++ b/common/core/overlaylayer.cpp @@ -138,8 +138,8 @@ void OverlayLayer::SetDisplayFrame(const HwcRect& display_frame) { } void OverlayLayer::SetTransform(uint32_t transform) { - plane_transform_ = transform; transform_ = transform; + merged_transform_ = transform; } void OverlayLayer::ValidateTransform(uint32_t transform, @@ -173,14 +173,14 @@ void OverlayLayer::ValidateTransform(uint32_t transform, // The elements {0, 1, 2, 3} form a circulant matrix under mod 4 arithmetic mtransform = (mtransform + mdisplay_transform) % 4; mtransform = inv_tmap[mtransform]; - plane_transform_ = mtransform; + merged_transform_ = mtransform; - if (plane_transform_ & kTransform90) { + if (merged_transform_ & kTransform90) { if (transform & kReflectX) - plane_transform_ |= kReflectX; + merged_transform_ |= kReflectX; if (transform & kReflectY) - plane_transform_ |= kReflectY; + merged_transform_ |= kReflectY; } } @@ -216,26 +216,26 @@ void OverlayLayer::TransformDamage(HwcLayer* layer, uint32_t max_height, int ox = 0, oy = 0; - if (plane_transform_ == kTransform270) { + if (merged_transform_ == kTransform270) { oy = max_height; surface_damage_.left = translated_damage.top * ratio_w_h + 0.5; surface_damage_.top = oy - translated_damage.right * ratio_h_w + 0.5; surface_damage_.right = translated_damage.bottom * ratio_w_h + 0.5; surface_damage_.bottom = oy - translated_damage.left * ratio_h_w + 0.5; - } else if (plane_transform_ == kTransform180) { + } else if (merged_transform_ == kTransform180) { ox = max_width; oy = max_height; surface_damage_.left = ox - translated_damage.right; surface_damage_.top = oy - translated_damage.bottom; surface_damage_.right = ox - translated_damage.left; surface_damage_.bottom = oy - translated_damage.top; - } else if (plane_transform_ & hwcomposer::HWCTransform::kTransform90) { - if (plane_transform_ & kReflectX) { + } else if (merged_transform_ & hwcomposer::HWCTransform::kTransform90) { + if (merged_transform_ & kReflectX) { surface_damage_.left = translated_damage.top * ratio_w_h + 0.5; surface_damage_.top = translated_damage.left * ratio_h_w + 0.5; surface_damage_.right = translated_damage.bottom * ratio_w_h + 0.5; surface_damage_.bottom = translated_damage.right * ratio_h_w + 0.5; - } else if (plane_transform_ & kReflectY) { + } else if (merged_transform_ & kReflectY) { ox = max_width; oy = max_height; surface_damage_.left = ox - (translated_damage.bottom * ratio_w_h + 0.5); @@ -249,7 +249,7 @@ void OverlayLayer::TransformDamage(HwcLayer* layer, uint32_t max_height, surface_damage_.right = ox - translated_damage.top * ratio_w_h + 0.5; surface_damage_.bottom = translated_damage.right * ratio_h_w + 0.5; } - } else if (plane_transform_ == 0) { + } else if (merged_transform_ == 0) { surface_damage_.left = translated_damage.left; surface_damage_.top = translated_damage.top; surface_damage_.right = translated_damage.right; @@ -270,10 +270,11 @@ void OverlayLayer::InitializeState(HwcLayer* layer, uint32_t max_height, uint32_t max_width, uint32_t rotation, bool handle_constraints) { transform_ = layer->GetTransform(); + plane_transform_ = rotation; if (rotation != kRotateNone) { ValidateTransform(layer->GetTransform(), rotation); } else { - plane_transform_ = transform_; + merged_transform_ = transform_; } #ifdef RECT_DAMAGE_TRACING IRECTDAMAGETRACE("validated plane_transform_: %d", plane_transform_); @@ -600,6 +601,7 @@ void OverlayLayer::CloneLayer(const OverlayLayer* layer, surface_damage_ = layer->GetSurfaceDamage(); transform_ = layer->transform_; plane_transform_ = layer->plane_transform_; + merged_transform_ = layer->merged_transform_; alpha_ = layer->alpha_; layer_index_ = z_order; z_order_ = z_order; diff --git a/common/core/overlaylayer.h b/common/core/overlaylayer.h index b862c40e..6847ea68 100644 --- a/common/core/overlaylayer.h +++ b/common/core/overlaylayer.h @@ -88,12 +88,18 @@ struct OverlayLayer { return transform_; } + // This represents hwc transform setting for this + // display on which this layer is being shown. + uint32_t GetPlaneTransform() const { + return plane_transform_; + } + // This represents any transform applied // to this layer(i.e. GetTransform()) + overall // rotation applied to the display on which this // layer is being shown. - uint32_t GetPlaneTransform() const { - return plane_transform_; + uint32_t GetMergedTransform() const { + return merged_transform_; } // Applies transform to this layer before scanout. @@ -289,6 +295,7 @@ struct OverlayLayer { uint32_t transform_ = 0; uint32_t plane_transform_ = 0; + uint32_t merged_transform_ = 0; uint32_t z_order_ = 0; uint32_t layer_index_ = 0; uint32_t source_crop_width_ = 0; diff --git a/wsi/drm/drmplane.cpp b/wsi/drm/drmplane.cpp index d7f563dc..9c49a085 100644 --- a/wsi/drm/drmplane.cpp +++ b/wsi/drm/drmplane.cpp @@ -342,7 +342,7 @@ bool DrmPlane::UpdateProperties(drmModeAtomicReqPtr property_set, if (rotation_prop_.id) { uint32_t rotation = 0; - uint32_t transform = layer->GetPlaneTransform(); + uint32_t transform = layer->GetMergedTransform(); if (transform & kTransform90) { rotation |= DRM_MODE_ROTATE_90; if (transform & kReflectX) @@ -456,7 +456,7 @@ bool DrmPlane::ValidateLayer(const OverlayLayer* layer) { } bool zero_rotation = false; - uint32_t transform = layer->GetPlaneTransform(); + uint32_t transform = layer->GetMergedTransform(); if (transform == kIdentity) { zero_rotation = true; } From 3ea5b3f3c8f91a26beeb55545bf7a3562fa1d745 Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Tue, 2 Apr 2019 15:22:26 +0800 Subject: [PATCH 19/20] An API for switching DRM master Add an API in binder for dropping and setting DRM master Test: Compile sucessful for Android. Change-Id: Iad5df43ad26e9d063aac339e79394b4f00e8431d Tracked-On: None Signed-off-by: Shaofeng Tang --- os/android/hwcservice.cpp | 4 ++++ os/android/hwcservice.h | 1 + os/android/iahwc2.cpp | 4 ++++ os/android/iahwc2.h | 2 ++ os/android/libhwcservice/hwcserviceapi.cpp | 9 +++++++++ os/android/libhwcservice/hwcserviceapi.h | 2 ++ os/android/libhwcservice/icontrols.cpp | 21 +++++++++++++++++++++ os/android/libhwcservice/icontrols.h | 2 ++ 8 files changed, 45 insertions(+) diff --git a/os/android/hwcservice.cpp b/os/android/hwcservice.cpp index b032fb56..f6116ac4 100644 --- a/os/android/hwcservice.cpp +++ b/os/android/hwcservice.cpp @@ -409,6 +409,10 @@ bool HwcService::Controls::EnableDRMCommit(bool enable, uint32_t display_id) { return mHwc.EnableDRMCommit(enable, display_id); } +bool HwcService::Controls::ResetDrmMaster(bool drop_master) { + return mHwc.ResetDrmMaster(drop_master); +} + status_t HwcService::Controls::VideoEnableEncryptedSession( uint32_t sessionID, uint32_t instanceID) { mHwc.SetPAVPSessionStatus(true, sessionID, instanceID); diff --git a/os/android/hwcservice.h b/os/android/hwcservice.h index 481b9a26..bb8ecaf3 100644 --- a/os/android/hwcservice.h +++ b/os/android/hwcservice.h @@ -108,6 +108,7 @@ class HwcService : public BnService { uint32_t SRMLength); uint32_t GetDisplayIDFromConnectorID(uint32_t connector_id); bool EnableDRMCommit(bool enable, uint32_t display_id); + bool ResetDrmMaster(bool drop_master); status_t VideoEnableEncryptedSession(uint32_t sessionID, uint32_t instanceID); status_t VideoDisableAllEncryptedSessions(uint32_t sessionID); diff --git a/os/android/iahwc2.cpp b/os/android/iahwc2.cpp index 2d82f8c4..8c0e0700 100644 --- a/os/android/iahwc2.cpp +++ b/os/android/iahwc2.cpp @@ -1309,6 +1309,10 @@ bool IAHWC2::EnableDRMCommit(bool enable, uint32_t display_id) { return device_.EnableDRMCommit(enable, display_id); } +bool IAHWC2::ResetDrmMaster(bool drop_master) { + return device_.ResetDrmMaster(drop_master); +} + void IAHWC2::SetHDCPSRMForDisplay(uint32_t connector, const int8_t *SRM, uint32_t SRMLength) { if (SRM == NULL) { diff --git a/os/android/iahwc2.h b/os/android/iahwc2.h index 1062860e..82cea0e1 100644 --- a/os/android/iahwc2.h +++ b/os/android/iahwc2.h @@ -74,6 +74,8 @@ class IAHWC2 : public hwc2_device_t { bool EnableDRMCommit(bool enable, uint32_t display_id); + bool ResetDrmMaster(bool drop_master); + public: class Hwc2Layer { public: diff --git a/os/android/libhwcservice/hwcserviceapi.cpp b/os/android/libhwcservice/hwcserviceapi.cpp index 45960424..7366abb0 100644 --- a/os/android/libhwcservice/hwcserviceapi.cpp +++ b/os/android/libhwcservice/hwcserviceapi.cpp @@ -315,6 +315,15 @@ status_t HwcService_EnableDRMCommit(HWCSHANDLE hwcs, uint32_t enable, return pContext->mControls->EnableDRMCommit(enable, display_id); } +status_t HwcService_ResetDrmMaster(HWCSHANDLE hwcs, uint32_t drop_master) { + HwcsContext* pContext = static_cast(hwcs); + if (!pContext) { + return android::BAD_VALUE; + } + + return pContext->mControls->ResetDrmMaster(drop_master); +} + status_t HwcService_Video_DisableHDCPSession_AllDisplays(HWCSHANDLE hwcs) { HwcsContext* pContext = static_cast(hwcs); if (!pContext) { diff --git a/os/android/libhwcservice/hwcserviceapi.h b/os/android/libhwcservice/hwcserviceapi.h index e0f6e2e9..68c5dd2f 100644 --- a/os/android/libhwcservice/hwcserviceapi.h +++ b/os/android/libhwcservice/hwcserviceapi.h @@ -224,6 +224,8 @@ uint32_t HwcService_GetDisplayIDFromConnectorID(HWCSHANDLE hwcs, status_t HwcService_EnableDRMCommit(HWCSHANDLE hwcs, uint32_t enable, uint32_t display_id); +status_t HwcService_ResetDrmMaster(HWCSHANDLE hwcs, uint32_t drop_master); + // The control enables a the protected video subsystem to control when to // replace any // encrypted content with a default bitmap (usually black). diff --git a/os/android/libhwcservice/icontrols.cpp b/os/android/libhwcservice/icontrols.cpp index 9a59aef1..ec1f93a4 100644 --- a/os/android/libhwcservice/icontrols.cpp +++ b/os/android/libhwcservice/icontrols.cpp @@ -58,6 +58,7 @@ class BpControls : public BpInterface { TRANSACT_VIDEO_SET_HDCP_SRM_FOR_DISPLAY, TRANSACT_GET_DISPLAYID_FROM_CONNECTORID, TRANSACT_ENABLE_DRM_COMMIT, + TRANSACT_RESET_DRM_MASTER, TRANSACT_VIDEO_ENABLE_ENCRYPTED_SESSION, TRANSACT_VIDEO_DISABLE_ENCRYPTED_SESSION, TRANSACT_VIDEO_DISABLE_ALL_ENCRYPTED_SESSIONS, @@ -458,6 +459,19 @@ class BpControls : public BpInterface { return (uint32_t)(reply.readInt32()); } + bool ResetDrmMaster(bool drop_master) override { + Parcel data; + Parcel reply; + data.writeInterfaceToken(IControls::getInterfaceDescriptor()); + data.writeInt32(drop_master); + + status_t ret = remote()->transact(TRANSACT_RESET_DRM_MASTER, data, &reply); + if (ret != NO_ERROR) { + ALOGW("%s() transact failed: %d", __FUNCTION__, ret); + } + return (uint32_t)(reply.readInt32()); + } + status_t VideoEnableEncryptedSession(uint32_t sessionID, uint32_t instanceID) override { Parcel data; @@ -801,6 +815,13 @@ status_t BnControls::onTransact(uint32_t code, const Parcel &data, reply->writeInt32(ret); return NO_ERROR; } + case BpControls::TRANSACT_RESET_DRM_MASTER: { + CHECK_INTERFACE(IControls, data, reply); + bool drop_master = data.readInt32(); + bool ret = this->ResetDrmMaster(drop_master); + reply->writeInt32(ret); + return NO_ERROR; + } case BpControls::TRANSACT_VIDEO_ENABLE_ENCRYPTED_SESSION: { CHECK_INTERFACE(IControls, data, reply); uint32_t sessionID = data.readInt32(); diff --git a/os/android/libhwcservice/icontrols.h b/os/android/libhwcservice/icontrols.h index c8c0c49f..db8f90c3 100644 --- a/os/android/libhwcservice/icontrols.h +++ b/os/android/libhwcservice/icontrols.h @@ -81,6 +81,8 @@ class IControls : public android::IInterface { virtual bool EnableDRMCommit(bool enable, uint32_t display_id) = 0; + virtual bool ResetDrmMaster(bool drop_master) = 0; + virtual status_t VideoEnableEncryptedSession(uint32_t sessionID, uint32_t instanceID) = 0; virtual status_t VideoDisableAllEncryptedSessions(uint32_t sessionID) = 0; From 95ec73b8710df14915d8bab798c7d9ee04c79c4e Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Wed, 12 Jun 2019 22:43:39 +0800 Subject: [PATCH 20/20] [WA]Force refresh layer content on extend display In "Presentation with Media Router" test case, the surface-damage for the changing layer on extend display is 0. For work around it HWC will mark "content is changed" for all layers on extend display Change-Id: I048b56e967a6f06ba73eff5ae77c95a55cbd028c Tests: Tested on Android Q Tracked-On: None Signed-off-by: Shaofeng Tang --- common/core/overlaylayer.cpp | 2 +- common/core/overlaylayer.h | 15 +++++++++++++-- common/display/displayqueue.cpp | 2 ++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/common/core/overlaylayer.cpp b/common/core/overlaylayer.cpp index d5061b97..0946b73d 100644 --- a/common/core/overlaylayer.cpp +++ b/common/core/overlaylayer.cpp @@ -571,7 +571,7 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs, if (!layer->HasVisibleRegionChanged() && !content_changed && surface_damage_.empty() && !layer->HasLayerContentChanged() && - !(state_ & kNeedsReValidation)) { + !(state_ & kNeedsReValidation) && !force_content_changed_) { state_ &= ~kLayerContentChanged; } } diff --git a/common/core/overlaylayer.h b/common/core/overlaylayer.h index 6847ea68..22d4930b 100644 --- a/common/core/overlaylayer.h +++ b/common/core/overlaylayer.h @@ -123,11 +123,17 @@ struct OverlayLayer { } const HwcRect& GetSurfaceDamage() const { - return surface_damage_; + if (force_content_changed_) + return display_frame_; + else + return surface_damage_; } HwcRect& GetSurfaceDamage() { - return surface_damage_; + if (force_content_changed_) + return display_frame_; + else + return surface_damage_; } uint32_t GetSourceCropWidth() const { @@ -252,6 +258,10 @@ struct OverlayLayer { void CloneLayer(const OverlayLayer* layer, const HwcRect& display_frame, ResourceManager* resource_manager, uint32_t z_order); + void SetForceContentChanged() { + force_content_changed_ = true; + } + void Dump(); private: @@ -306,6 +316,7 @@ struct OverlayLayer { uint32_t dataspace_ = 0; uint32_t solid_color_ = 0; + bool force_content_changed_ = false; HwcRect source_crop_; HwcRect display_frame_; diff --git a/common/display/displayqueue.cpp b/common/display/displayqueue.cpp index 9bcf475b..322763a4 100644 --- a/common/display/displayqueue.cpp +++ b/common/display/displayqueue.cpp @@ -545,6 +545,8 @@ void DisplayQueue::InitializeOverlayLayers( layers.emplace_back(); OverlayLayer* overlay_layer = &(layers.back()); + if (refrsh_display_id_ > 0) + overlay_layer->SetForceContentChanged(); OverlayLayer* previous_layer = NULL; if (previous_size > z_order) { previous_layer = &(in_flight_layers_.at(z_order));